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