Some notes on porting from PyGTK to PyGObject
These are some notes I wrote as porting my on-again off-again hobby project Basketball GM from PyGTK to PyGObject. I did this because PyGTK is dead and stuck on GTK+ 2, and PyGObject is the future and already on GTK+ 3 through the use of GObject introspection. So, others going through the same transition might (or might not) find this useful. You can see the code I'm referring to on the pygobject branch on GitHub.
However, there were tons of bugs with the functionality and a ton of error messages. Here is a probably incomplete list of things I did to fix those problems:
Gtk.main_iterationno longer takes any arguments. Removing them seems to fix the error with no consequences. I probably didn't need to be messing with the arguments there to begin with.
I had to manually set the "Show text" parameter of my
Gtk.ProgressBarto "Yes" in Glade to get text to display on top of my
Gtk.ProgressBar. I guess the default setting changed?
gtk.Tooltipswas previously deprecated (which I did not know..), but now it's totally gone and replaced by
Gtk.Tooltip. If I had been using the
gtk.TooltipAPI to begin with, as I should have been, this wouldn't have been an issue
gtk.ComboBox.get_active_textis gone, so I worked around that by using
Gtk.ComboBox.get_active_iter, which seems more convoluted, but whatever.
If you tell a
Gtk.ListStoreit's getting an
int, it only wants an
int. It won't take a
floatand do the best it can like it used to. This is good because it helped me find an obvious typo in my SQL schema. But it's bad because because SQLite's
TOTALfunction will return a
FLOATeven if you call it on an
INTEGERcolumn. This is especially annoying as I have some convenience functions to handle the boilerplate for
TreeViews which relied on the old behavior from PyGTK. So I ended up manually comparing the column type of my
GObject.TYPE_INTso I could manually make the input an
Gtk.TreeViewColumn.set_cell_data_functo truncate floats to one decimal place in
TreeViews. The second parameter (the data function) now requires a mandatory fifth parameter which I don't think I have any use for.
I had to switch to a different way of checking if a window is open. I'm not sure why, to be honest.
It seems you can no longer do
del liststore[i]to delete a row from a
Gtk.ListStore. You need to do something much less Pythonic, like
To temporarily raise a window that is minimized or in the background, this solution from the old PyGTK FAQ doesn't work anymore. Instead, the better solution (as I learned on Stack Overflow) is to just call
Gtk.Window.present(). This same method would have worked in PyGTK, but I wasn't aware of it.
TreePathobjects no longer support indexing. So, if you want to access the numerical values in a
TreePath, you have to call the
get_indicesmethod on it.
I encountered a very strange bug related to connecting to the
responsesignal from a
Gtk.Dialogin Glade, and I wasn't able to figure out the root cause, so I worked around it by manually connecting to that signal.
I ran into another issue that might be a bug in PyGObject, which I worked around by making my UI uglier and clunkier.
I'm not totally done. I'm still having some performance issues with updating large
Gtk.TreeViews, and I need to do some more testing to find any remaining bugs. But for the most part... things work. And porting wasn't that difficult or time consuming.
So in conclusion, the new bindings for GTK+ 3 are less Pythonic than PyGTK was, they're more glitchy, and there's less documentation. But they work well enough for most purposes. That's not really a useful conclusion, as I'm just repeating conventional wisdom, which turned out to be correct in this case.
Is porting worth the effort? In 2012, it would probably have been more efficient to put this time towards porting my software to a web app. But I'm just doing this for fun.