2014-09-23 3 views
0

Я попытался сделать мою программу PyQt4 более отзывчивой, переместив некоторый код блокировки в отдельный QThread. Как это не сработало, я создал этот минимальный пример в качестве демонстрации:Код pyqt блокируется, хотя перемещается в другой 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_() 

Проблема с этим кодом является то, что сон-команда по-прежнему блокирует пользовательский интерфейс. Я обнаружил, что он работает так, как ожидалось, когда я создаю, подключаю и запускаю QTimer вне класса Sleeper, но я не понимаю, почему.

ответ

3

Вызывается connect, когда объект находится в потоке графического интерфейса, поэтому обработчик событий также будет выполнен в потоке графического интерфейса пользователя. Попробуйте сначала перенести в поток, а затем создайте соединение.

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?

+0

я все еще получаю закупорки в UI с помощью этого кода. – nvd