[PyQt] An issue with calling back into the Python interpreter from C from inside of PyQt...

Randall Frank rjfrank at ensight.com
Mon Jul 25 23:07:09 BST 2011

   This one has been a little perplexing, so I thought
I'd run it past folks here to see if they had any suggestions.
It is a little complex, but let me try to describe the setup.
I have an embedded Python interpreter with PyQt installed
in it.  My application itself is Qt/C++, but some portions
of the GUI are written in Python/PyQt.  In general, this
works really well.  My app also has a module that allows
Python code to make calls into it.  Here is my problem.
I have PyQt class that looks like:

from PyQt4 import QtGui, QtCore

class CeiStyleListWidget(QtGui.QListWidget):
    def __init__(self,parent):
        self._ext = None

    def setExtension(self,ext):
        self._ext = ext

    def startDrag(self, actions):
        mime = self._ext.dragBuildMIME("currentitem")
        drag = QtGui.QDrag(self)

    def doDrag(self,execute):
        print "Hello!"
        return True

'ext' is a module that calls back into my C code
that creates a somewhat specialized QMimeData
instance (it puts in some extra formats).  Now,
on the drag operation, I have a QWidget subclass
that allows drops (EnsCvfWidget).  I get to my
dropEvent method:

void EnsCvfWidget::dropEvent ( QDropEvent * event )

just fine and can crack open the QMimeData object
and see that it came from CeiStyleListWidget.
Now, to complete the action, I call back out to
the Python doDrag() method on the CeiStyleListWidget
instance using: PyObject_Call() from my C++ code in
the dropEvent method.  This crashes the Python
interpreter in a bad way (note: if I make the call
to doDrag from C++ directly, the call works fine).
It looks like some sort of Python interpreter
re-entrancy issue.   When I add a call to check
the thread state:

PyThreadState *tstate = PyThreadState_GET();

My PyObject_Call() only works if tstate does not
return NULL.  In the drag/drop callback stack, it
always seems to be NULL.

First, should this work?  Can I call drag.exec_()
from Python and then in the dropEvent method (on an
Qt object written in C++) be able to call a method
on the Python object using PyObject_Call()?  If not,
can I do so with some other method? 

I know the question is a little dense, but if I can
clarify any of it for you, please let me know.

Thanks in advance for considering my problem!

rjf                       Quando omni flunkus moritati
Randall Frank     rjfrank at ensight.com     919-363-0883
Computational Engineering International www.ceintl.com
2166 North Salem St,  Suite 101,  Apex,  NC 27523-6456

More information about the PyQt mailing list