工作线程阻塞GUI中的QTimer

时间:2018-07-12 12:50:29

标签: python pyqt pyqt5 qthread qtimer

我正在尝试创建一个工作线程,其工作是监视定位平台的状态位。

为此,我将QTimer超时信号连接到查询平台的函数。

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内容如下:

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都无法响应。但是,如果我注释掉self.timer.timeout.connect(self.do_it)并将do_it放入while(True)循环中,则不会阻止GUI。

为什么使用QTimer时主线程被阻塞?

1 个答案:

答案 0 :(得分:1)

我不知道expSignals()是什么,我认为这无关紧要,按钮也没有。

您的代码具有以下错误:

  • 您正在线程启动之前启动计时器,因此该任务将在GUI线程上运行。

  • QTimer不是motorpositioner的子级,因此如果motorpositioner移至新线程QTimer不会。要让他搬家,他必须是儿子,所以您必须将他作为父母交给自己。

  • 我不知道这是否是一个真正的错误,但是您每100毫秒触发一次QTimer,但是任务需要5秒钟,尽管QMutex不会因为被阻止而出现问题。


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_())
相关问题