[PyQt] qthread and connections
Matt Smith
melkor at orangepalantir.org
Fri Jan 8 02:51:59 GMT 2010
If I have a QThread how do I connect signals to it so that it receives
signals and the slot is executed in a separate thread.
My understanding is that if I call a QThread.exec_() then I start that
thread's event loop. A signal that is connected to the thread should be
evaluated during that threads event loop and hence it should be
evaluated in the same thread the event loop was started.
Here is an example that creates three different buttons to show the
different ways to start a thread. I would expect buttonB
"ConnectedThread" to behave similar to buttonA, "DirectThread", but as
can be seen it behaves like buttonC, which uses no threads. I have
tried different connection styles but I still get the same results.
<pycode name="compare_threads.py">
#!/usr/bin/env python
from PyQt4 import QtCore,QtGui
import sys, time
class DisplayWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
widge = QtGui.QWidget()
layout = QtGui.QVBoxLayout()
self.ok = True
self.label = QtGui.QLabel("0")
button_layout = QtGui.QHBoxLayout()
buttonA = QtGui.QPushButton("Direct")
buttonB = QtGui.QPushButton("Connected")
buttonC = QtGui.QPushButton("No Thread")
buttonA.clicked.connect(self.startDirectThread)
self.proc = ConnectedThread()
self.proc.start()
buttonB.clicked.connect(self.proc.stopNWait,
type=QtCore.Qt.QueuedConnection)
buttonC.clicked.connect(self.sleepNoThread)
button_layout.addWidget(buttonA)
button_layout.addWidget(buttonB)
button_layout.addWidget(buttonC)
layout.addWidget(self.label)
layout.addLayout(button_layout)
widge.setLayout(layout)
self.setCentralWidget(widge)
@QtCore.pyqtSlot()
def startDirectThread(self):
if self.ok:
self.ok = False
self.x = DirectThread()
self.x.start()
self.x.finished.connect(self.xFinished)
@QtCore.pyqtSlot()
def sleepNoThread(self):
print QtCore.QThread.currentThreadId()
QtCore.QThread.sleep(1)
@QtCore.pyqtSlot()
def xFinished(self):
print QtCore.QThread.currentThreadId()
self.ok = True
class DirectThread(QtCore.QThread):
def __init__(self, parent=None):
QtCore.QThread.__init__(self,parent)
def run(self):
print QtCore.QThread.currentThreadId()
QtCore.QThread.sleep(1)
class ConnectedThread(QtCore.QThread):
def __init__(self, parent=None):
QtCore.QThread.__init__(self,parent)
def run(self):
print "Connected id: ",QtCore.QThread.currentThreadId()
self.exec_()
@QtCore.pyqtSlot()
def stopNWait(self):
print QtCore.QThread.currentThreadId()
QtCore.QThread.sleep(1)
if __name__=="__main__":
app = QtGui.QApplication(sys.argv)
wid = DisplayWindow()
wid.show()
sys.exit(app.exec_())
</pycode>
More information about the PyQt
mailing list