PyQt5學習筆記14----初識pyqt多執行緒操作
阿新 • • 發佈:2019-01-11
首先來看一個例子:
# coding=utf-8 __author__ = 'a359680405' from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * global sec sec=0 def setTime(): global sec sec+=1 lcdNumber.display(sec) #LED顯示數字+1 def work(): timer.start(1000) #計時器每秒計數 for i in range(2000000000): pass timer.stop() app=QApplication([]) top=QWidget() layout=QVBoxLayout(top) #垂直佈局類QVBoxLayout; lcdNumber=QLCDNumber() #加個顯示屏 layout.addWidget(lcdNumber) button=QPushButton("測試") layout.addWidget(button) timer=QTimer() timer.timeout.connect(setTime) #每次計時結束,觸發setTime button.clicked.connect(work) top.show() app.exec()
有經驗的開發者立即指出,這裡需要使用執行緒。這是因為 Qt 中所有介面都是在 UI 執行緒中(也被稱為主執行緒,就是執行了QApplication::exec()的執行緒),在這個執行緒中執行耗時的操作(比如那個迴圈),就會阻塞 UI 執行緒,從而讓介面停止響應。介面停止響應,使用者體驗自然不好,不過更嚴重的是,有些視窗管理程式會檢測到你的程式已經失去響應,可能會建議使用者強制停止程式,這樣一來你的程式可能就此終止,任務再也無法完成。所以,為了避免這一問題,我們要使用 QThread 開啟一個新的執行緒:
# coding=utf-8 __author__ = 'a359680405' from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * global sec sec=0 class WorkThread(QThread): trigger = pyqtSignal() def __int__(self): super(WorkThread,self).__init__() def run(self): for i in range(203300030): pass self.trigger.emit() #迴圈完畢後發出訊號 def countTime(): global sec sec+=1 lcdNumber.display(sec) #LED顯示數字+1 def work(): timer.start(1000) #計時器每秒計數 workThread.start() #計時開始 workThread.trigger.connect(timeStop) #當獲得迴圈完畢的訊號時,停止計數 def timeStop(): timer.stop() print("執行結束用時",lcdNumber.value()) global sec sec=0 app=QApplication([]) top=QWidget() layout=QVBoxLayout(top) #垂直佈局類QVBoxLayout; lcdNumber=QLCDNumber() #加個顯示屏 layout.addWidget(lcdNumber) button=QPushButton("測試") layout.addWidget(button) timer=QTimer() workThread=WorkThread() button.clicked.connect(work) timer.timeout.connect(countTime) #每次計時結束,觸發setTime top.show() app.exec()
我增加了一個WorkerThread類。WorkerThread繼承自QThread類,重寫了其run()函式。可以認為,run()函式就是新的執行緒需要執行的程式碼。在這裡就是要執行這個迴圈,然後發出計算完成的訊號。而在按鈕點選的槽函式中,使用work()中的workThread.start()函式啟動一個執行緒(注意,這裡不是run()函式)。再次執行程式,你會發現現在介面已經不會被阻塞了。