本文主要講解使用多線程模塊QThread解決PyQt界面程序唉執行耗時操作時,程序卡頓出現的無響應以及界面輸出無法實時顯示的問題。用戶使用工具過程中出現這些問題時會誤以為程序出錯,從而把程序關閉。這樣,導致工具的用戶使用體驗不好。下面我們通過模擬上述出現的問題并講述使用多線程QThread模塊解決此類問題的方法。
PyQt程序卡頓和無法實時顯示問題現象
使用PyQt界面程序,點擊運行按鈕后,程序在顯示框中每秒打印1個數字。程序代碼如下:
# -*- coding: utf-8 -*-import sysimport timefrom PyQt5.QtCore import QThread, pyqtSignalfrom PyQt5.QtWidgets import QApplication, QMainWindowfrom QThread_Example_UI import Ui_Formclass MyMainForm(QMainWindow, Ui_Form): def __init__(self, parent=None): super(MyMainForm, self).__init__(parent) self.setupUi(self) self.runButton.clicked.connect(self.display) def display(self): for i in range(20): time.sleep(1) self.listWidget.addItem(str(i))if __name__ == "__main__": app = QApplication(sys.argv) myWin = MyMainForm() myWin.show() sys.exit(app.exec_())
程序運行過程結果如下(點擊Run按鈕后界面出現 未響應 字樣 , 同時程序也沒有出現每隔1秒打印1個數字,實際結果是循環結束后20個數字一同展示):
問題分析
上述實現的GUI程序都是單線程運行,對于需要執行一個特別耗時的操作時就會出現該問題現象。要解決這種問題可以考慮使用多線程模塊QThread。
多線程模塊QThread基本原理
QThread是Qt的線程類中最核心的底層類。由于PyQt的的跨平臺特性,QThread要隱藏所有與平臺相關的代碼 要使用的QThread開始一個線程,可以創建它的一個子類,然后覆蓋其它QThread.run()函數。
class Thread(QThread): def __init__(self): super(Thread,self).__init__() def run(self): #
接下來創建一個新的線程
thread = Thread()thread.start()
可以看出,PyQt的線程使用非常簡單,建立一個自定義的類(如Thread),自我繼承自QThread ,并實現其run()方法即可。在使用線程時可以直接得到Thread實例,調用其start()函數即可啟動線程,線程啟動之后,會自動調用其實現的run()的函數,該方法就是線程的執行函數 。
業務的線程任務就寫在run()函數中,當run()退出之后線程就基本結束了,QThread有started和finished信號,可以為這兩個信號指定槽函數,在線程啟動和結束之時執行一段代碼進行資源的初始化和釋放操作,更靈活的使用方法是,在自定義的QThread實例中自定義信號,并將信號連接到指定的槽函數,當滿足一定的業務條件時發射此信號。
新聞熱點
疑難解答