Visar inlägg med etikett PYGTK. Visa alla inlägg
Visar inlägg med etikett PYGTK. Visa alla inlägg

Interfaces uglier than C

I'm not to happy with what PyGTK does with my interfaces. In C, an implementation of GtkIImageTool looks like this. In Python, it looks like this:

import gobject import gtkimageview class MyTool(gobject.GObject, gtkimageview.IImageTool): def __init__(self): gobject.GObject.__init__(self) self.crosshair = gtk.gdk.Cursor(gtk.gdk.CROSSHAIR) self.cache = gtkimageview.PixbufDrawCache() def do_button_press(self, ev_button): pass def do_button_release(self, ev_button): pass def do_motion_notify(self, ev_motion): pass def do_pixbuf_changed(self, reset_fit, rect): print 'pixbuf changed' def do_paint_image(self, draw_opts, drawable): self.cache.draw(draw_opts, drawable) def do_cursor_at_point(self, x, y): return self.crosshair gobject.type_register(MyTool)

There are quite a few ugly warts here.

class MyTool(gobject.GObject, gtkimageview.IImageTool):

You have to subclass gobject.GObject, which I really would rather not. The whole point of writing programs in Python is to get rid of the stupid, annoying and complicated GObject system. Same for gtkimageview.IImageTool -- this is Python and you have duck-typing. You shouldn't need to subclass anything.

def do_cursor_at_point(self, x, y):

And why does PyGTK decide that all my interface methods should be prefixed with do_? I didn't tell it to do that. It is an extremely unpythonic convention.

gobject.type_register(MyTool)

Yet another GObject-ism. It would be plain simple to get rid of this step by making gobject.GObject a metaclass that registers the class when it is constructed. But no, PyGTK wants to remind you that you really are dealing with a C API and nothing more.

gobject.GObject.__init__(self)

As before, initialization like this shouldn't be needed for a plain Python class.

return self.crosshair

Don't try to return None, PyGTK:s code generator doesn't understand that an interface function can either return an object pointer or NULL.

But worst of all is probably that if you forget to do any of this, then IT WILL CRASH. Don't expect a nice exception, at best you'll get a cryptic GTK warning and a segfault with debug symbols.

PyGTK:s handling of GInterfaces is, as shown, currently very weak. But I expect it to be improved upon in the future. Meanwhile I'm thinking that PyGTK:s wrapping system with definition and override files isn't that good to begin with. It is fairly easy to whip something up fast, but when you want to make your binding pythonic, you run into problems.

I wonder if it wouldn't be possible to use ctypes to create more pythonic bindings with.

PyGTK on Windows

When installing PyGTK on Windows, don't forget that you must run a new cmd.exe for the changes to take effect. The PATH environment variable needs to be updated to include the path to the GTK+ libraries which by default are installed in c:/GTK/bin.

Quick guide to PyGTK on Windows

I found this to be non-trivial. Here are the steps you need to go through to get PyGTK to work in Windows:
  1. Download the Python 2.5 MSI installer. Direct link

    Install it to C:\Python25 and do not forget to add C:\Python25\bin to your PATH.

  2. Download the PyGTK EXE installer. Direct Link
  3. Download the GTK EXE installer. Direct link

    Install it in C:\GTK. It should automatically add C:\GTK\bin to your PATH. If it does not, do it manually.

  4. Download the PyCairo EXE installer. Direct link.

  5. Download the pygobject EXE installer. Direct link.
Maybe it is not that complicated. :)

Bloggarkiv