We've had a lot of problems with our application (SciCraft[1]) hanging
at odd times after upgrading to PyQt 3.12 (package python2.3-qt3) in
debian. The problem seems to occur whenever we do a postEvent from
another thread while the event/gui-thread is handling a previous
event. Using PyQt 3.12 the application deadlocks when posting the
second event, while using version 3.11 gives none of these problems.
Attached is an example script showing the problem. The script runs
successfully (for me) using 3.11 and hangs on postEvent in 3.12. The
script uses a custom event with a data object with a slow __del__ to
make sure that the event handling is stalled long enough for the
second postEvent to occur.
Does anyone know a workaround, fix or even a kludge for this problem?
I'm running on Debian Unstable using the following package versions:
libqt3c102-mt 3.2.3-4
python2.3-qt3 3.12-1
python2.3-sip4-qt3 4.0-2
[1] - http://www.scicraft.org
--
Truls A. Tangstad - <[EMAIL PROTECTED] e r o c a m p.org>
import qt
import thread
import time
class Data:
def __del__(self):
print "Thread %s deleting data" % thread.get_ident()
time.sleep(1)
print "Thread %s deleted data" % thread.get_ident()
def trig():
"""Make sure that postEvent occurs while gui-thread is busy handling
another event.
1 - Start first posting thread
2 - First posting thread sends event
3 - First posting thread deletes its own reference to event, making
sure only eventqueue has a reference
3 - Start second posting thread
4 - Start single shot timer
5 - Finish this method so main thread can handle first posted event
6 - Main thread starts deleting the first posted event with its data, being
the last to hold a reference to it
responsibility of deleting it and starts the the destructor
7 - A new event is posted - causing a deadlock in PyQt 3.12
In PyQt 3.11, the following steps are also done:
8 - Destructor of first event finishes
9 - New event is handled and destructed in main thread
10 - Exit is triggered by single shot timer and application exits
"""
thread.start_new_thread(sendEvent, (0,))
thread.start_new_thread(sendEvent, (0.5,))
qt.QTimer.singleShot(3000, qt.qApp.exit)
time.sleep(0.2)
def sendEvent(sleeptime):
time.sleep(sleeptime)
someNumber = 1234
qEvent = qt.QCustomEvent(someNumber, Data())
print "Thread %s posting event" % thread.get_ident()
# will hang here if simultaneously in destructor of event's dataobject
qt.qApp.postEvent(qt.qApp, qEvent)
print "Thread %s posted event" % thread.get_ident()
del qEvent
qApp = qt.QApplication([])
qt.QTimer.singleShot(0, trig)
print "Thread %s is main thread" % thread.get_ident()
qApp.exec_loop()
print "No problems"