我有一个应用程序,其中一个线程正在执行一项冗长的任务。我使用一个发出信号的QPushButton来触发这个冗长的任务。但是,单击按钮会使GUI对进程的长度不响应,即使该进程位于另一个线程中。下面是一个复制此行为的小程序:
import sys
import time
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtCore import pyqtSignal, QThread, Qt
class WriteThread(QThread):
write_signal = pyqtSignal()
def __init__(self):
super().__init__()
self.write_signal.connect(self.worker, Qt.QueuedConnection)
def worker(self):
print("Before sleep")
time.sleep(2)
print("After sleep")
return True
class Example(QWidget):
def __init__(self):
super().__init__()
self.CustomEvent = None
self.write_thread = None
self.init_ui()
def init_ui(self):
self.write_thread = WriteThread()
redb = QPushButton('Red', self)
redb.move(10, 10)
blueb = QPushButton('Blue', self)
blueb.move(10, 50)
blueb.clicked.connect(self.print_method)
redb.clicked.connect(self.send_event)
self.write_thread.start()
self.setGeometry(300, 300, 300, 250)
self.setWindowTitle('Toggle button')
self.show()
def send_event(self):
print("\tSending signal")
self.write_thread.write_signal.emit()
print("\tFinished sending signal")
def print_method(self):
print("Not frozen")
def main():
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
time.sleep(2)
模拟冗长的过程。
我的问题是:为什么不同线程中的进程会冻结GUI
说明:
您必须了解,QThread不是一个Qt-thread,而是本机OS线程的处理程序,类似于threading.thread
正如the docs所指出的:
(强调矿山)
也就是说,只有run()方法在新线程上执行,因此“worker”在属于QThread的线程上执行,在本例中,QThread是主线程
解决方案:
如果希望执行“work”方法,则类对象必须位于辅助线程中,这样WriteThread就足够成为QObject(不需要是QThread),并将其移动到另一个线程:
相关问题 更多 >
编程相关推荐