diff options
author | James Henstridge <james@daa.com.au> | 2001-05-06 16:51:48 +0000 |
---|---|---|
committer | James Henstridge <jamesh@src.gnome.org> | 2001-05-06 16:51:48 +0000 |
commit | 4a9a14997dc9d70e8e77a1c37ec3e06a109af300 (patch) | |
tree | 728a24234a2ebe7e081755b5e83f14e4aa0dd6f3 | |
parent | 2fa1a292a8c3056183f7e0ac77ce46551c58b853 (diff) | |
download | pygobject-4a9a14997dc9d70e8e77a1c37ec3e06a109af300.tar.gz pygobject-4a9a14997dc9d70e8e77a1c37ec3e06a109af300.tar.xz pygobject-4a9a14997dc9d70e8e77a1c37ec3e06a109af300.zip |
2001-05-06 James Henstridge <james@daa.com.au>
2001-05-07 James Henstridge <james@daa.com.au>
* examples/gobject/signal.py:
2001-05-06 James Henstridge <james@daa.com.au>
* gobjectmodule.c (pygobject__init__): make the __init__ function
choose what GType to pass to g_object_new based on the __gtype__
attribute.
(pygobject_methods): make __gobject_init__ an alias for
GObject.__init__.
(pyg_type_register): new function for registering new GTypes.
(pyg_type_register): register the type as "module+class" rather
than "module.class", as the second form is considered bad (would
like to use the second form though.
* configure.in: require 1.3.5 versions of glib and gtk+.
-rw-r--r-- | examples/signal.py | 8 | ||||
-rw-r--r-- | gobject/gobjectmodule.c | 106 |
2 files changed, 109 insertions, 5 deletions
diff --git a/examples/signal.py b/examples/signal.py index b98bca7..c52f0ad 100644 --- a/examples/signal.py +++ b/examples/signal.py @@ -1,10 +1,12 @@ -import ltihooks, ExtensionClass import gobject class C(gobject.GObject): + def __init__(self): + self.__gobject_init__() # default constructor using our new GType def do_my_signal(self, arg): print "C: class closure for `my_signal' called with argument", arg +gobject.type_register(C) gobject.signal_new("my_signal", C, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_INT, )) @@ -13,6 +15,8 @@ class D(C): print "D: class closure for `my_signal' called. Chaining up to C" C.do_my_signal(self, arg) +gobject.type_register(D) + def my_signal_handler(object, arg, *extra): print "handler for `my_signal' called with argument", arg, \ "and extra args", extra @@ -20,8 +24,6 @@ def my_signal_handler(object, arg, *extra): inst = C() inst2 = D() -print "instance id 0x%x" % id(inst) - inst.connect("my_signal", my_signal_handler, 1, 2, 3) inst.emit("my_signal", 42) inst2.emit("my_signal", 42) diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c index 660db72..daaab4b 100644 --- a/gobject/gobjectmodule.c +++ b/gobject/gobjectmodule.c @@ -922,10 +922,28 @@ pygobject__class_init__(PyObject *something, PyObject *args) static PyObject * pygobject__init__(PyGObject *self, PyObject *args) { - GType object_type = G_TYPE_OBJECT; + PyObject *gtype; + GType object_type; - if (!PyArg_ParseTuple(args, "|i:GObject.__init__", &object_type)) + if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type)) return NULL; + + gtype = PyObject_GetAttrString((PyObject *)self, "__gtype__"); + if (!gtype) { + PyErr_Clear(); + PyErr_SetString(PyExc_TypeError, + "required __gtype__ attribute missing"); + return NULL; + } + object_type = (GType) PyInt_AsLong(gtype); + if (PyErr_Occurred()) { + PyErr_Clear(); + Py_DECREF(gtype); + PyErr_SetString(PyExc_TypeError, + "__gtype__ attribute not an integer"); + return NULL; + } + Py_DECREF(gtype); self->obj = g_object_new(object_type, NULL); if (!self->obj) { PyErr_SetString(PyExc_RuntimeError, "could not create object"); @@ -1338,6 +1356,7 @@ pygobject_stop_emission(PyGObject *self, PyObject *args) static PyMethodDef pygobject_methods[] = { { "__class_init__", (PyCFunction)pygobject__class_init__, METH_VARARGS|METH_CLASS_METHOD }, { "__init__", (PyCFunction)pygobject__init__, METH_VARARGS }, + { "__gobject_init__", (PyCFunction)pygobject__init__, METH_VARARGS }, { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS }, { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS }, { "freeze_notify", (PyCFunction)pygobject_freeze_notify, METH_VARARGS }, @@ -1491,6 +1510,88 @@ pyg_type_interfaces (PyObject *self, PyObject *args) return NULL; } +static PyObject * +pyg_type_register(PyObject *self, PyObject *args) +{ + PyObject *class, *gtype, *module; + GType parent_type, instance_type; + gchar *type_name = NULL; + GTypeQuery query; + GTypeInfo type_info = { + 0, /* class_size */ + + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + + (GClassInitFunc) NULL, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + + 0, /* instance_size */ + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL + }; + + if (!PyArg_ParseTuple(args, "O:gobject.type_register", &class)) + return NULL; + if (!ExtensionClassSubclass_Check(class, &PyGObject_Type)) { + PyErr_SetString(PyExc_TypeError,"argument must be a GObject subclass"); + return NULL; + } + + /* find the GType of the parent */ + gtype = PyObject_GetAttrString(class, "__gtype__"); + if (!gtype) { + PyErr_Clear(); + PyErr_SetString(PyExc_TypeError, + "required __gtype__ attribute missing"); + return NULL; + } + parent_type = (GType) PyInt_AsLong(gtype); + if (PyErr_Occurred()) { + PyErr_Clear(); + Py_DECREF(gtype); + PyErr_SetString(PyExc_TypeError, + "__gtype__ attribute not an integer"); + return NULL; + } + Py_DECREF(gtype); + + /* make name for new widget */ + module = PyObject_GetAttrString(class, "__module__"); + if (module && PyString_Check(module)) { + type_name = g_strconcat(PyString_AsString(module), "+", + ((PyExtensionClass *)class)->tp_name, NULL); + } else { + if (module) + Py_DECREF(module); + else + PyErr_Clear(); + type_name = g_strdup(((PyExtensionClass *)class)->tp_name); + } + + /* fill in missing values of GTypeInfo struct */ + g_type_query(parent_type, &query); + type_info.class_size = query.class_size; + type_info.instance_size = query.instance_size; + + /* create new typecode */ + instance_type = g_type_register_static(parent_type, type_name, + &type_info, 0); + g_free(type_name); + if (instance_type == 0) { + PyErr_SetString(PyExc_RuntimeError, "could not create new GType"); + return NULL; + } + + /* set new value of __gtype__ on class */ + gtype = PyInt_FromLong(instance_type); + PyObject_SetAttrString(class, "__gtype__", gtype); + Py_DECREF(gtype); + + Py_INCREF(Py_None); + return Py_None; +} static PyObject * pyg_signal_new(PyObject *self, PyObject *args) @@ -1578,6 +1679,7 @@ static PyMethodDef pygobject_functions[] = { { "type_is_a", pyg_type_is_a, METH_VARARGS }, { "type_children", pyg_type_children, METH_VARARGS }, { "type_interfaces", pyg_type_interfaces, METH_VARARGS }, + { "type_register", pyg_type_register, METH_VARARGS }, { "signal_new", pyg_signal_new, METH_VARARGS }, { NULL, NULL, 0 } }; |