Multithreading PySide:线程导致GUI崩溃
我正在尝试学习PySide线程的基础知识,因此将下面的代码放在一起。我试图做的是启动一个线程,该线程将使用字符串列表更新QPlainTextEdit小部件,每个字符串之间有一个延迟。相反,我得到的是桌面崩溃,我不明白为什么:Multithreading PySide:线程导致GUI崩溃,multithreading,python-3.x,pyside,Multithreading,Python 3.x,Pyside,我正在尝试学习PySide线程的基础知识,因此将下面的代码放在一起。我试图做的是启动一个线程,该线程将使用字符串列表更新QPlainTextEdit小部件,每个字符串之间有一个延迟。相反,我得到的是桌面崩溃,我不明白为什么: import sys import time from PySide import QtCore, QtGui class Worker(QtCore.QThread): to_log = QtCore.Signal(str) def __init_
import sys
import time
from PySide import QtCore, QtGui
class Worker(QtCore.QThread):
to_log = QtCore.Signal(str)
def __init__(self, txt, parent=None):
super(Worker, self).__init__(parent)
self.txt = txt
def run(self):
for i in self.txt:
self.to_log.emit(i)
time.sleep(1)
class TestThreadsApp(QtGui.QWidget):
def __init__(self):
super(TestThreadsApp, self).__init__()
self.initUI()
def initUI(self):
self.log = QtGui.QPlainTextEdit()
self.pb = QtGui.QPushButton('Go')
hbox = QtGui.QHBoxLayout()
hbox.addWidget(self.log)
hbox.addWidget(self.pb)
self.setLayout(hbox)
self.setGeometry(300, 300, 300, 150)
self.setWindowTitle('Test')
self.show()
self.pb.clicked.connect(self.get_worker)
def get_worker(self):
self.proceed = False
worker = Worker(['This is a test', 'to understand threading'])
worker.to_log.connect(self.to_log)
worker.start()
def to_log(self, txt):
self.log.appendPlainText(txt)
def main():
app = QtGui.QApplication(sys.argv)
ex = TestThreadsApp()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
如果我将get_worker()方法更新为以下内容,它将运行,但QPlainTextEdit小部件将同时使用所有字符串进行更新,其中我想要的行为是在每个字符串发出时由线程进程对小部件进行更新,而不是在两个字符串都发出后进行更新:
def get_worker(self):
self.proceed = False
worker = Worker(['This is a test', 'to understand threading'])
worker.to_log.connect(self.to_log)
worker.start()
while not worker.isFinished():
pass
您需要保留对线程的引用,否则它将在
get\u worker
返回时被垃圾收集
所以,你可以这样做:
def get_worker(self):
self.worker = Worker(['This is a test', 'to understand threading'])
self.worker.to_log.connect(self.to_log)
self.worker.start()
我不知道PySide的具体情况,但大多数UI框架/工具包都不是线程安全的,需要在主应用程序线程中对UI进行任何更新。@MichaelAaronSafyan。在Qt中,跨线程发出信号是安全的(默认情况下,它们是排队的),所以这不是问题所在。非常感谢,这就成功了。我会记住这一点:垃圾收集。