[PyQt] PyQt4 and threading

Ole Streicher ole-usenet-spam at gmx.net
Wed Oct 14 14:26:25 BST 2009


Hi,

I have a problem when I use multi threading with pyqt4: every of my
widgets has a worker thread that updates the content on changes. The
worker thread is build around Python threading (error handling removed
to shorten the code):

-------------------8<----------------------------
class AsyncThread(threading.Thread):
    def __init__(self, func):
        threading.Thread.__init__(self)
        self._cond = threading.Condition()
        self._func = func
        self.scheduled = False
        self.start()

    def run(self):
        while True:
            with self._cond:
                while not self.scheduled:
                    self._cond.wait()
                self.scheduled = False
            self._func()

    def __call__(self):
        with self._cond:
            self.scheduled = True
            self._cond.notify()
-------------------8<----------------------------

A call of the AsyncThread object will trigger a call of the enclosed
function func(). I use this to update a large QGraphicsView:

def update_map():
    # ...
    for item in scene.items: # 'items' contains some 1000s QGraphicsRectItems
        item.setBrush(QtGui.Brush(QtGui.QColor(...)))
    scene.update()

async_update_map = AsyncThread(update_map)

QtCore.connect(..., ..., async_update_map)

The "connect" connects, for example, cursor changes with the update.

The problem is now that I get random *crashes* with that code. This
ranges from a simple "segmentation fault" to hundreds of lines glibc
Backtraces like:

*** glibc detected *** python: realloc(): invalid pointer: 0x00007ffcfa2c5360 **
======= Backtrace: =========
/lib/libc.so.6[0x7ffcfb8a4cb8]
/lib/libc.so.6(realloc+0x2bc)[0x7ffcfb8a9f3c]
/usr/lib/libQtCore.so.4(_ZN9QListData7reallocEi+0x2b)[0x7ffcf9f0a46b]
...
/usr/lib/libQtGui.so.4(_ZN26QAbstractGraphicsShapeItem8setBrushERK6QBrush+0x35)[0x7ffcfaa70e15]
/usr/lib/python2.6/dist-packages/PyQt4/QtGui.so[0x7ffcfb2d4449]
python(PyEval_EvalFrameEx+0x4e23)[0x4a2b03]
...
python[0x4d3b3d]
/lib/libpthread.so.0[0x7ffcfc44a3ba]
/lib/libc.so.6(clone+0x6d)[0x7ffcfb912fcd]

Beside "invalid pointer", I also get "double free or corruption
(fasttop)" and similar errors.

My question is now whether this is a Bug of PyQt4 or if I use the
Threading incorrectly? Do I have to use Qt Threads instead? And how do I
do locking (the threading.Condition) in that case?

Regards

Ole



More information about the PyQt mailing list