【问题标题】:QTimer and QThread odd behaviorQTimer 和 QThread 奇怪的行为
【发布时间】:2014-12-12 17:49:34
【问题描述】:
from PySide.QtGui import *
from PySide.QtCore import *
import sys
from time import sleep

class MyWorkerThread(QThread):
    def __init__(self, parent=None):
        super(MyWorkerThread, self).__init__(parent)

    def run(self):
        timer1 = QTimer()
        timer1.singleShot(1000, self.alarm_goes1)
        print "Timer 1 Start"
        timer1.start()

    def alarm_goes1(self):
        print "goes off 1"


class MainFrame(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.thread = MyWorkerThread(self)
        print "Thread Start"
        self.thread.start()

        timer2 = QTimer()
        timer2.singleShot(1000, self.alarm_goes2)
        print "Timer 2 Start"
        timer2.start()

    def alarm_goes2(self):
        print 'goes off 2'

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = MainFrame()
    main.show()
    sys.exit(app.exec_())

输出:

Thread Start
Timer 2 Start
Timer 1 Start
goes off 2

请解释为什么 alarm_goes1 不执行。我怎样才能做到呢?


编辑:

def run(self):
    timer1 = QTimer()
    timer1.singleShot(2000, self.alarm_goes1)
    print "Timer 1 Start"
    timer1.start()
    self.exec_()
    self._alive = True
    while self._alive:
        print 'this part will not execute'
        self.sleep(1)

使用self.exec_(),两个计时器都可以正常工作,但while 循环中的部分则不行。没有self.exec_(),只有一个定时器可以工作,但是while循环会工作。

我希望计时器和 while 循环一起工作。

我尝试在 while 循环中移动 self.exec_(),但它只会运行一次。

【问题讨论】:

    标签: python pyside qthread qtimer


    【解决方案1】:

    计时器发布QTimerEvent,但线程中没有运行事件循环来处理它。

    所以你需要做这样的事情:

        def run(self):
            timer1 = QTimer()
            timer1.singleShot(1000, self.alarm_goes1)
            print "Timer 1 Start"
            timer1.start()
            # start the clock
            clock = QTimer()
            clock.start(1000)
            clock.timeout.connect(self.tick)
            # start the thread's event loop
            self.exec_()
    
        def tick(self):
            print 'tick'
    

    将其添加到MainFrame 类可能是明智的:

        def closeEvent(self, event):
            # exit the thread's event loop
            self.thread.quit()
    

    【讨论】:

    • self.exec_() 之后的任何内容都不会运行。编辑了问题。
    • @f.rodrigues。像这样使用while 循环是行不通的:它只会阻塞GUI。您只需要一个简单的计时器来标记秒数(请参阅我更新的答案)。事实上,如果你想实现一个闹钟,你应该认真考虑摆脱线程,只用计时器来做所有事情
    • 该死的你是对的。我忘了计时器可以重复使用。
    猜你喜欢
    • 1970-01-01
    • 2019-02-01
    • 2021-01-08
    • 1970-01-01
    • 2012-06-03
    • 1970-01-01
    • 2012-05-16
    • 2014-07-10
    • 2013-10-15
    相关资源
    最近更新 更多