Design of Python-Gtk (long) 
Author Message
 Design of Python-Gtk (long)

As I have mentioned in my announcement for python-gtk, I would
like help designing the python module for Gtk.  I would
appreciate any and all input.  If you don't know what python-gtk
is, check out my announcement in this group or:

        http://www.*-*-*.com/ ~nascheme/python-gtk/

First, some background for people who are not familar with Gtk.
It is a new graphical toolkit for developing X11 applications.
It is implemented in C and uses an object oriented style.  It is
also designed to be quite flexible.

In developing python-gtk, I have taken an approach similar to
Tkinter.  First, there is a extension module, _gtk, implemented
in C.  It is basicly a one to one mapping of the Gtk API to
Python.  I have developed it using SWIG.  Second, there is a
native Python module, gtk, that implements an object oriented API
to Gtk.  This is part I would like help on.

First, I think gtk.py should completely hide _gtk.  This would
allow the extension module to be changed without affecting code
written for gtk.py.  Secondly, I think gtk.py should make good
use of Python features to make a nice OO API.  I don't want to
put down Tkinter too much, it is very useful, but I feel that the
Tkinter.py leaves a lot to be desired.  Perhaps much of the
trouble is due to Tk and Tcl.

As I said earlier, the Gtk API is OO, despite being implemented
in C.  This should make it much easier to implement a OO wrapper
in Python.  There is a type hierarchy and type cast macros are
extensively used.  Here is part of the hierarchy:

    GtkObject
    +-- GtkData
    |   \-- GtkAdjustment
    |
    \-- GtkWidget
        +-- GtkContainer
            +-- GtkBin
            |   +-- GtkAlignment
            |   +-- GtkFrame
            |   |   *-- GtkAspectFrame
            |   |
            |   +-- GtkItem
            |   |   +-- GtkListItem
            |   |   +-- GtkMenuItem
            |   |   |   +-- GtkCheckMenuItem
            |   |   |       *-- GtkRadioMenuItem
            |   |   |
            |   |   *-- GtkTreeItem
            |   |
            |   +-- GtkViewport
            |   \-- GtkWindow
            |       +-- GtkDialog
            |       \-- GtkFileSelection
            |
            +-- GtkButton
                +-- GtkOptionMenu
                \-- GtkToggleButton
                    \-- GtkCheckButton
                        \-- GtkRadioButton

All of the functions are consistantly named to show which types they
apply to.  For example:

        create a new window widget:
                GtkWidget *gtk_window_new()

        set the title:
                void gtk_window_set_title(GtkWindow *window, gchar *title)

        create a new button:
                GtkWidget *gtk_button_new()

Anything that is a child of GtkWindow can be cast to a GtkWindow
using a suitable macro.  Here is how I have currently implemented
the Window object:

=====================================================================
class Window(Bin):
     def __init__(self, type=WINDOW_TOPLEVEL, title=None,
                  wm_name=None, wm_class=None):
          if not hasattr(self, '_p'):
               self._p = _gtk.gtk_window_new(type)
               if title:
                    self.setTitle(title)
               if wm_name and wm_class:
                    self.setWMClass(wm_name, wm_class)
          self._window = _ptrcast(self._p, 'GtkWindow *')
          Bin.__init__(self)

     def setTitle(self, title):
          _gtk.gtk_window_set_title(self._window, title)

     def setWMClass(self, wm_name, wm_class):
          _gtk.gtk_window_set_wmclass(self._window, wm_name, wm_class)

     def setFocus(self, widget):
          _gtk.gtk_window_set_focus(self._window, widget._widget)
=====================================================================

self._p is a SWIG pointer to the C object.  All of the pointer
casts are done when the object is initialized.  Each class stores
a SWIG pointer of its type in self._<type>.  Also notice that
these pointers do not appear in the arguments of the __init__
functions.  I think this is an important fact.  One of the things
I didn't like about Tkinter was the special handling of __init__.
It makes subclassing widgets a pain in the ass and should not be
something the users should have to deal with.

Another important consideration is callbacks.  Gtk using a signal
mechanism similar to Qt.  Gtk implements callbacks as function
pointers and possibly pointers to data.  I have written a wrapper
function to take a pointer to a python function.  I don't believe
that the data pointer is necessary because Python can simulate
closures using default arguments.

Finally, I am still wondering how to handle memory management.
Right now, widgets have to be explicitly destroyed.  Should
reference counting be used and the widget be automaticly
destroyed when there are no more references to it?  This may make
it easier on the application programmer.  However, I am worried
about widgets getting destroyed when the programmer still wants
to have them around.  

One last thing.  Should I look into using Extension Classes?  I
really don't know too much about them.

        Neil



Sat, 22 Apr 2000 03:00:00 GMT  
 
 [ 1 post ] 

 Relevant Pages 

1. How to make a Python Long from a long long in an extension

2. Does python support long longs?

3. Now parsing gtk/gtk.h

4. Ruby-gtk, Gtk::Text question

5. GTK an GTK ada problemes

6. cl-gtk for gtk+-1.2

7. Stackless Python is DEAD! Long live Stackless Python

8. FYI: Re: Python, Glade, & GTK

9. Python GTK JPEG Images

10. gtk tutorial for python

11. Python and Gtk

12. problem with python/gtk

 

 
Powered by phpBB® Forum Software