我想了解PySide的線程化基礎知識,所以放在一起下面的代碼。我想要做的是啓動一個線程,它將使用字符串列表更新QPlainTextEdit小部件,每個字符串之間有一個延遲。相反,就是我得到的是一個崩潰到桌面,我不明白爲什麼:PySide:線程化導致GUI崩潰
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部件與更新所有字符串同時,在這裏,因爲我想要的行爲是一個widget由每個字符串發出的線程進程更新 - 不完全後都已經發出:
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
我不知道PySide特別,但大多數的UI框架/工具包不是線程安全的,並要求用戶界面的任何更新到內發生主應用程序線程。 –
@MichaelAaronSafyan。在Qt中通過線程發送信號是安全的(它們默認排隊),所以這不是問題。 – ekhumoro