код pyqt блокируется, хотя и перемещен в другой QThread

Я попытался сделать свою программу PyQt4 более отзывчивой, переместив некоторый блокирующий код в отдельный QThread. Поскольку это не сработало, я создал этот минимальный пример в качестве демонстрации:

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 по-прежнему блокирует пользовательский интерфейс. Я обнаружил, что он работает так, как ожидалось, когда я создаю, подключаю и запускаю QTimer вне класса Sleeper, но я не понимаю, почему.


person jan    schedule 23.09.2014    source источник


Ответы (1)


connect вызывается, когда объект находился в потоке GUI, поэтому обработчик событий также будет выполняться в потоке 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 между потоками: почему это работать?

person Gábor Imre    schedule 23.09.2014