我有一些计算繁重的任务,我想在不阻塞主事件循环的情况下,每5秒在一个循环中运行一次。为此,我打算使用一个QTimer
和一个单独的线程来运行它。我尝试了以下代码,但到目前为止还没有成功:
@pyqtSlot()
def heavy_task_function():
# Sleep for 10 seconds to simulate heavy computation
time.sleep(10)
print "First Timer Fired"
if __name__ == "__main__":
app = QCoreApplication.instance()
if app is None:
app = QApplication(sys.argv)
threaded_timer = ModbusComThread(heavy_task_function)
threaded_timer.start()
sys.exit(app.exec_())
其中:
class ModbusComThread(QThread):
def __init__(self, slot_function):
QThread.__init__(self)
self.slot_function = slot_function
self.send_data_timer = None
def run(self):
print "Timer started on different thread"
self.send_data_timer = QTimer(self)
self.send_data_timer.timeout.connect(self.slot_function)
self.send_data_timer.start(5000)
def stop(self):
self.send_data_timer.stop()
slot_function
从不由threaded_timer
中的QTimer
激发。我的线程体系结构正确吗?你知道吗
QTimer
需要一个正在运行的事件循环。默认情况下,QThread.run()
将为线程启动一个本地事件循环,但是如果您以您所做的方式完全重写它,则不会发生这种情况—因此计时器事件将永远不会被处理。你知道吗一般来说,当需要本地事件循环时,应该创建一个worker对象来执行所有处理,然后使用moveToThread将其放入一个单独的线程中。如果不是的话,完全可以重写
QThread.run()
。你知道吗下面的演示演示了如何做到这一点。请注意,在线程启动后创建计时器是非常重要的,否则它将在错误的线程中创建,并且它的计时器事件不会被线程的事件循环处理。工作线程和主线程之间的所有通信都是通过信号完成的,这一点也很重要,以确保线程安全。永远不要尝试在主线程之外直接执行GUI操作,因为Qt根本不支持这一点。为了演示的目的,主线程中的第二个计时器用于在固定的时间间隔后停止所有处理。如果有一个GUI,用户通过一个按钮进行干预也可以实现同样的效果。你知道吗
演示:
输出:
相关问题 更多 >
编程相关推荐