Exaile still uses PyGTK, which in turn depends on Python 2 and GTK+ 2. Why haven’t we upgraded?
- Python 3: Not even sure PyGI supports it yet. Either way, needs PyGI.
- GTK+ 3: Needs PyGI.
- PyGI (a.k.a. new PyGObject): We’ve been trying. It segfaults randomly. And debugging segfaults from a Python program is… hard.
Update (2015-11): It’s happening; we’re slowly porting Exaile to PyGI. It will be using GTK+ 3 and GStreamer 1, but will still be on Python 2.
These are actually development versions of PyGObject and PyGTK as downloaded on 2010-10-27, not any specific release versions. Credits to John Stowers, who maintains PyGTK’s Windows port.
Update (2011-01-08): pygtk.org now provides official packages for PyGTK 2.22. I’ve removed all download links to my own builds.
PyGTK uses NumPy in one function and this is not documented in the Win32 README. There is some automated check to disable NumPy support if it’s not available, but it fails on my machine because I have NumPy’s binaries installed; PyGTK’s setup.py assumes I also have the include files, which I don’t.
No big deal;
pkg-config and space characters
pkg-config only gained support for space characters five months ago, and that’s still in their development version. (Insert expletives here.)
I don’t think I’ve used
C:\PROGRA~1-style paths in years. Thanks for the nostalgia, pkg-config.
If you have a GtkFontButton, finding out whether the chosen font is monospaced is quite a complicated process. Here is a complete walk-through.
(By the way, I will be using PyGTK’s Pango documentation because the C version is a mess.)
FontButton.get_font_name returns the font family (a.k.a. “font name”), style, and size; for example, “Liberation Serif Italic 14”. The first thing we need to do is pick just the family name. We do this by going through a PangoFontDescription.
desc_str = font_button.get_font_name() # Liberation Serif Italic 14
desc = pango.FontDescription(desc_str)
family_name = desc.get_family() # Liberation Serif
Next, check whether the font family describes a monospaced font. Here is where it gets dodgy. We need an arbitrary PangoContext, which can be obtained from a GtkWidget using
Widget.get_pango_context. We then list all available font families and find the one with the appropriate name. Call
FontFamily.is_monospace to finish the job.
(By the way, this is also a good place to show off Python’s for-else construct.)
context = widget.get_pango_context() # widget can be any GtkWidget.
for family in context.list_families():
if family.get_name() == family_name:
else: # Should not happen.
family.is_monospace() # False -- Liberation Serif is proportional.
Playing with Unicode in Python 2 is not fun, and combining this with third-party libraries brings even more headaches. This post explains how Unicode in PyGTK is handled.
Note: This information is only valid for Python 2.x. It will likely change when PyGTK releases support for Python 3.
Calling GTK+ functions: PyGTK accepts
unicode objects as input.
str objects are assumed to be in UTF-8. If you pass a non-UTF-8
str to a GTK+ function, it will work until you try to show it, where you’ll get a “PangoWarning: Invalid UTF-8 string passed to pango_layout_set_text()”.
Handling GTK+ return values: PyGTK functions always return strings as
str objects. In most (all?) cases, the strings are encoded in UTF-8. Ideally, Python programs should use
unicode strings internally, so it’s wise to convert the output of PyGTK function calls to
label1.set_text("Some UTF-8 string")
label1.set_text(u"Some Unicode string")
x = label1.get_text() # x is an str object containing UTF-8 string.
y = unicode(x, 'utf-8') # y is the unicode version of x.
y = x.decode('utf-8') # Same as above.