QtCore.QTimer.singleShot迭代调用函数时滞后

2024-09-22 11:23:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些pyqt图形用户界面,它通过函数定期更新 更新元素()

下面是我的代码是如何工作的。当用户单击按钮时,将调用buttonHandler。并且每隔10秒迭代调用一次updateDeleteMetry:

def buttonHandler(self):
    self.monitor=true
    self.updateTelemetry()

def updateTelemetry(self):
   try:
        #update values on gui
   finally:
       if self.monitor:
          QtCore.QTimer.singleShot(10000, self.updateTelemetry)

这种方法很有效,让我每10秒更新一次,但是,每10秒,整个gui冻结几秒钟,然后更新。我正在做的事情似乎被挡住了。我不知道是怎么回事。我以为单发qtimer会创建一个单独的线程?在

有没有更好的方法来做我正在做的事?在


Tags: 方法函数代码用户self元素defgui
1条回答
网友
1楼 · 发布于 2024-09-22 11:23:45

QTimer不创建单独的线程。QTimer只在给定的超时之后在主线程中发出一个信号。因此,一切(包括你的设备读取代码)仍然在主线程中运行。在

您应该将从设备读取的代码移动到QThread,并从QThread向主线程发出一个信号,您可以在主线程中更新GUI。GUI更新只能从主线程进行。唯一的信号发射是线程安全的!在

下面是一个QThread的粗略实现。在

class MyThread(QObject):
    send_data_to_gui = pyqtSignal(str)

    def __init__(self,*args,**kwargs):
        QObject.__init__(self,*args,**kwargs)

    @pyqtSlot()
    def run(self):
        while True: 
            # get data from device
            self.send_data_to_gui.emit(data_from_device)
            time.sleep(10) 

...

thread = QThread()
my_thread = MyThread()
my_thread.send_data_to_gui.connect(my_slot)
my_thread.moveToThread(thread)
thread.started.connect(my_thread.run)
thread.start()

注意,在当前形式中,QThread实际上有它自己的事件循环,所以您可以做各种复杂的事情(但是while True目前正在阻塞事件循环)。由于线程有一个独立的事件循环,您可以将while True替换为QTimer,配置为每10秒触发一次(不过,请确保QTimer实际上是在线程中创建的。MyThread.__init__仍然在主线程中运行,但是MyThread.run的内容将在新线程中执行)。您可能还想添加关闭线程的功能,或者添加其他我不知道的功能!在

如果您的实现有问题,请随时发布关于堆栈溢出的后续问题!在

相关问题 更多 >