Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading PySide:线程导致GUI崩溃_Multithreading_Python 3.x_Pyside - Fatal编程技术网

Multithreading PySide:线程导致GUI崩溃

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_

我正在尝试学习PySide线程的基础知识,因此将下面的代码放在一起。我试图做的是启动一个线程,该线程将使用字符串列表更新QPlainTextEdit小部件,每个字符串之间有一个延迟。相反,我得到的是桌面崩溃,我不明白为什么:

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中,跨线程发出信号是安全的(默认情况下,它们是排队的),所以这不是问题所在。非常感谢,这就成功了。我会记住这一点:垃圾收集。