虽然pyqt代码移动到不同的QThread,但它仍然是阻塞的

时间:2014-09-23 12:37:05

标签: pyqt qthread qtimer

我试图通过将一些阻塞代码移动到单独的QThread来使我的PyQt4程序更具响应性。由于它不起作用,我创建了这个最小的例子作为演示:

import sys
import time
from PyQt4 import QtCore, QtGui


class Sleeper(QtCore.QObject):

    def __init__(self):
        super(Sleeper, self).__init__()
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.sleep)
        self.timer.start(1000)

    def sleep(self):
        time.sleep(1)


class MyGUI(QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(MyGUI, self).__init__(parent)
        self.button = QtGui.QPushButton("hello", self)
        self.sleeper = Sleeper()
        self.thread = QtCore.QThread()
        self.sleeper.moveToThread(self.thread)
        self.thread.start()


if __name__ == "__main__":
    qapp = QtGui.QApplication(sys.argv)
    my_gui = MyGUI()
    my_gui.show()
    qapp.exec_()

此代码的问题是sleep-command仍然阻止用户界面。当我在Sleeper类之外创建,连接和运行QTimer时,我发现它按预期工作,但我不明白为什么。

1 个答案:

答案 0 :(得分:4)

当对象在GUI线程中时调用connect,因此事件处理程序也将在GUI线程中执行。首先尝试移动到线程,然后创建连接。

class Sleeper(QtCore.QObject):

    def __init__(self):
        super(Sleeper, self).__init__()
        self.timer = QtCore.QTimer()

    def initialize(self): # Creating the connection and starting separately
        self.timer.timeout.connect(self.sleep)
        self.timer.start(1000)

    def sleep(self):
        time.sleep(1)

class MyGUI(QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(MyGUI, self).__init__(parent)
        self.button = QtGui.QPushButton("hello", self)
        self.sleeper = Sleeper()
        self.thread = QtCore.QThread()
        self.sleeper.moveToThread(self.thread) # Move to thread
        self.sleeper.initialize() # Create connection now
        self.thread.start()

另外,检查一下: Qt connection type between threads: why does this work?