QTimer in worker thread blocking GUI
我正在尝试创建一个工作线程,其工作是监视定位平台的状态位。
为此,我将QTimer超时信号连接到查询平台的函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class expSignals(QtCore.QObject): pause=QtCore.pyqtSignal() class motorpositioner(QtCore.QObject): def __init__(self): QtCore.QThread.__init__(self) self.timer = QtCore.QTimer() self.timer.start(100) self.timer.timeout.connect(self.do_it) self.lock=QtCore.QMutex() self.running=True self.stat=0 def do_it(self): with QtCore.QMutexLocker(self.lock): #self.stat = self.motors.get_status() print(self.stat) time.sleep(5) @QtCore.pyqtSlot() def stop1(self): self.timer.stop() print('stop heard') |
GUI内容如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | class MyApp(QtWidgets.QMainWindow): def __init__(self): QtWidgets.QMainWindow.__init__(self) self.thread=QtCore.QThread(self) #worker self.mot=motorpositioner() # ============================================================================= # Putting buttons and GUI stuff in place # ============================================================================= self.button=QtWidgets.QPushButton('Derp',self) layout = QtWidgets.QHBoxLayout() layout.addWidget(self.button) self.setLayout(layout) self.setGeometry( 300, 300, 350, 300 ) # ============================================================================= # Connecting signals # ============================================================================= self.sig=expSignals() self.sig2=expSignals() self.button.clicked.connect(self.stop) self.sig.pause.connect(self.mot.stop1) self.sig2.pause.connect(self.thread.quit) self.mot.moveToThread(self.thread) self.thread.start() def stop(self): self.sig.pause.emit() def closeEvent(self,event): self.sig2.pause.emit() event.accept() |
无论如何,现在GUI都无法响应。但是,如果我注释掉
为什么使用QTimer时主线程被阻塞?
我不知道什么是
您的代码具有以下错误:
-
您正在线程启动之前启动计时器,因此该任务将在GUI线程上运行。
-
QTimer 不是motorpositioner 的子级,因此如果motorpositioner 移到新线程,则QTimer 不会。要让他移动,他必须是儿子,因此您必须将他作为父母交给自己。 -
我不知道这是否是一个真正的错误,但是您每100毫秒触发一次QTimer,但是任务需要5秒钟,尽管QMutex不会因为被阻止而出现问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | import sys from PyQt5 import QtCore, QtGui, QtWidgets import time class motorpositioner(QtCore.QObject): def __init__(self): QtCore.QThread.__init__(self) self.timer = QtCore.QTimer(self) self.lock = QtCore.QMutex() self.running = True self.stat = 0 def start_process(self): self.timer.timeout.connect(self.do_it) self.timer.start(100) def do_it(self): with QtCore.QMutexLocker(self.lock): #self.stat = self.motors.get_status() print(self.stat) time.sleep(5) @QtCore.pyqtSlot() def stop1(self): self.timer.stop() print('stop heard') class MyApp(QtWidgets.QMainWindow): def __init__(self): QtWidgets.QMainWindow.__init__(self) self.thread = QtCore.QThread(self) self.mot = motorpositioner() self.mot.moveToThread(self.thread) self.thread.started.connect(self.mot.start_process) self.thread.start() if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) ex = MyApp() ex.show() sys.exit(app.exec_()) |