默认情况下,QThread
具有事件循环,可以处理信号和插槽。在当前的实现中,很遗憾,您已通过重写删除了此行为QThread.run
。如果还原它,则可以得到所需的行为。
因此,如果您不能覆盖QThread.run()
,如何在Qt中进行线程处理?线程的另一种方法是将代码放在的子类中,QObject
然后将该对象移至标准QThread
实例。然后,您可以将信号和插槽连接在主线程和线程之间,QThread
以双向通信。这将使您能够实现所需的行为。
在下面的示例中,我启动了一个工作线程,该工作线程将打印到终端,等待2秒钟,再次打印,然后等待用户输入。单击该按钮时,工作线程中的第二个单独的函数运行,并以与第一次相同的模式打印到终端。请注意我使用moveToThread()
和连接信号的顺序)。
码:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import time
class MyWorker(QObject):
wait_for_input = pyqtSignal()
done = pyqtSignal()
@pyqtSlot()
def firstWork(self):
print 'doing first work'
time.sleep(2)
print 'first work done'
self.wait_for_input.emit()
@pyqtSlot()
def secondWork(self):
print 'doing second work'
time.sleep(2)
print 'second work done'
self.done.emit()
class Window(QWidget):
def __init__(self, parent = None):
super(Window, self).__init__()
self.initUi()
self.setupThread()
def initUi(self):
layout = QV@R_209_2419@Layout()
self.button = QPushButton('User input')
self.button.setEnabled(False)
layout.addWidget(self.button)
self.setLayout(layout)
self.show()
@pyqtSlot()
def enableButton(self):
self.button.setEnabled(True)
@pyqtSlot()
def done(self):
self.button.setEnabled(False)
def setupThread(self):
self.thread = QThread()
self.worker = MyWorker()
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.firstWork)
self.button.clicked.connect(self.worker.secondWork)
self.worker.wait_for_input.connect(self.enableButton)
self.worker.done.connect(self.done)
# Start thread
self.thread.start()
if __name__ == "__main__":
app = QApplication([])
w = Window()
app.exec_()