Would it be possible to have the actual instance passed in to the
callback function, instead of a brand new instance?  This would
make subclassing easier/nicer.  

The way it is now, you get this behavior:

class MyButton (GtkButton):
        ...
        def func (self):
                print "this is an instance of MyButton"

def clicked (button, data):
        # This doesn't work.  Since button is an instance of GtkButton,
        # not MyButton, an AttributeError is raised.
        button.func ()

mybutton = MyButton ()
mybutton.connect ("clicked", clicked, data=None)

Here is a little example (the commented stuff is the way I'd like
to do it).

from gtk import *

class BlinkingButton (GtkButton):
        def __init__ (self, label="", interval_milliseconds=300):
                GtkButton.__init__ (self)
                self.label_string = label
                self.label = GtkLabel (label)
                self.add (self.label)
                self.label.show ()
                timeout_add (interval_milliseconds, self.blink)
                self.state = "on"

        def blink (self):
                if self.state == "on":
                        self.label.set_text ("")
                        self.state = "off"
                else:
                        self.label.set_text (self.label_string)
                        self.state = "on"
                return TRUE

#def change_button_label (blinking_button, new_label_string):
#       print blinking_button
#       print blinking_button.label
#       blinking_button.label = new_label_string

def change_button_label (widget, blinking_button, new_label_string):
        print blinking_button
        print blinking_button.label
        blinking_button.label_string = new_label_string

win = GtkWindow ()
win.set_usize (200, 200)
win.connect ("destroy", mainquit)

button = BlinkingButton ("this is a blinking button")
#button.connect ("clicked", change_button_label, "blah blah")
button.connect ("clicked", change_button_label, button, "blah blah")
win.add (button)

win.show_all ()
mainloop ()


Will the change to extension classes allow this type of thing?
I took a look pygtk 0.7.0 and saw the the connect/marshal code
was the same as older versions of pygtk (don't know if it's going
to be changed).  

A way to add this is by adding the object instance to the data
tuple in _wrap_gtk_signal_connect ().  maybe something like this:

- if (!PyArg_ParseTuple(args, "O!sO|O!:gtk_signal_connect", &PyGtk_Type,
-                          &obj, &name, &func, &PyTuple_Type, &extra))
+ if (!PyArg_ParseTuple(args, "O!OsO|O!:gtk_signal_connect", &PyGtk_Type,
+                  &obj, &instance, &name, &func, &PyTuple_Type, &extra))
        return NULL;
    if (!PyCallable_Check(func)) {
-        PyErr_SetString(PyExc_TypeError, "third argument must be callable");
+        PyErr_SetString(PyExc_TypeError, "fourth argument must be callable");
        return NULL;
    }

    if (extra)
      Py_INCREF(extra);
    else
      extra = PyTuple_New(0);

    if (extra == NULL)
      return NULL;
-    data = Py_BuildValue("(ON)", func, extra);
+    data = Py_BuildValue("(OON)", func, instance, extra);


Then in PyGtk_CallbackMarshal ():

    if (PyTuple_Check(tuple)) {
-       func = PyTuple_GetItem(tuple, 0);
-       extra = PyTuple_GetItem(tuple, 1);
-       if (PyTuple_Size(tuple) > 2) {
-           obj = PyTuple_GetItem(tuple, 2);
+       func = PyTuple_GetItem(tuple, 0);
+       instance = PyTuple_GetItem(tuple, 1);
+       extra = PyTuple_GetItem(tuple, 2);
+       if (PyTuple_Size(tuple) > 3) {
+           obj = PyTuple_GetItem(tuple, 3);
            Py_INCREF(obj);
        }
    } else
        func = tuple;

then switch instance and obj in params, etc...


I didn't submit a patch because I wasn't sure about all the things that
needed to be changed.

Is something like this possible?



_______________________________________________
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk

Reply via email to