I'm encountering some strange behavior and hope someone on this list
can provide some insight.  We're using pygtk 0.6.8 with python 2.1,
and gtk-canvas 0.1.  We're using the gtk-canvas instead of
gnome-canvas so that our users don't have to install all of gnome.  A
disadvantage of that is that we have to create our own python wrappers
for the canvas functions.  Everything was fine until I tried to
extract mouse click coordinates.

Here's what happens.  There's a C++ class, OOFCanvas, that wraps the
gtk-canvas.  It has a set_callback() function which looks like this:

void OOFCanvas::set_callback(PyObject *callback) {
  pycallback = callback;  // pycallback is OOFCanvas instance data
  Py_XINCREF(callback);
  gtk_signal_connect(GTK_OBJECT(root),  // root is the gtk_canvas_root
                     "event",
                     GTK_SIGNAL_FUNC(OOFCanvas::mouse_event),
                     this);
}

set_callback() is SWIGged, and I know that its argument is being
handled correctly, since I can call the callback under other
circumstances.  (The SWIG typemap uses PyCallable_Check to verify that
the argument is sane.)

When the canvas gets an event, it calls the static function
OOFCanvas::mouse_event, which just calls a non-static function:

gint OOFCanvas::mouse_event(GtkCanvasItem *item, GdkEvent *event, gpointer data)
{
  OOFCanvas *oofcanvas = (OOFCanvas*)(data);
  oofcanvas->mouse_eventCB(item, event);
  return TRUE;
}

That non-static function invokes the Python callback:

void OOFCanvas::mouse_eventCB(GtkCanvasItem *item, GdkEvent *event) {
  PyObject *args = 0;
  switch(event->type) {
  case GDK_MOTION_NOTIFY:
     args = Py_BuildValue("(sdd)", "motion_notify",
                         event->motion.x, event->motion.y);
    break;
    // [ several other event types omitted ]
  }
  if(args) {
    PyObject *result = PyEval_CallObject(pycallback, args);  // dumps core!
    Py_XDECREF(args);
    Py_XDECREF(result);
  }
}

The call to PyEval_CallObject() dumps core.  I know that the argument
is being constructed correctly, since I can print it with
PyString_AsString(PyObject_Repr(args)).  I know that the callback is
set correctly, since I can examine it in the same way.  I can even
call the callback function successfully (but not usefully) if I call
it from set_callback().  It just doesn't work when I call it from
within a GtkCanvasItem signal callback!

Is there something special that I have to do to when calling Python
from C within a C gtk signal callback?  I can call the same Python
function successfully, with the same C++ code, as long as I don't call
it from within the signal handler.

Any advice would be much appreciated.

   -- Steve




-- 
/* EMail: [EMAIL PROTECTED] ------------------ Phone: (301) 975-5423 --
-- WWW:  http://math.nist.gov/~SLanger/ ------------ Fax:   (301) 990-4127 --
-- Mail: NIST; 100 Bureau Drive -- Stop 8910; Gaithersburg, MD  20899-8910 */
_______________________________________________
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to