PYQT中使用線程解決界面卡頓問題


  PYQT作為界面程序包,為Pythoner快速構建界面,提供了便利性。特別是結合Pycharm擴展工具(QTdesigner)能夠通過“拖拖拽拽”的方式構建簡單界面。通過UIC將UI文件快速轉化為PY文件,節省了時間。

  PYQT的項目實踐,必須參照MVC模式,才能形成多人工作合力,關於MVC的實踐,會另起它文進行總結歸納,本文重點總結歸納PYQT項目中,因耗時操作產生界面卡頓現象時,如何通過分線程的方式,解決主界面線程等待造成界面卡頓的問題。

  一、問題的出現

  設計了一個界面,去局域網共享文件夾中查看是否存在文件,若存在,則在textBrowser中顯示文件數量,每隔幾秒鍾執行一次,同時將信息Append到textBrowser中。

  使用os.listdir(target_path)打開共享文件夾時,由於網絡故障,待反饋耗時大,由於Ui_MainWindow中的方法都在主線程中進行,造成界面的卡頓。

  二、解決思路

  將耗時操作分離至新線程,主界面保留資源用於交互。查詢網絡上現有的解決思路,大致如下:利用PYQT中的QThread類,新起一個線程,用來處理共享文件夾查閱的操作,待該線程處理完成后,主線程接收子線程處理結果,append到textBrowser中。

  三、難點

  利用信號與槽的機制,將主、子線程建立關聯關系。

  四、如何實現

  1、實例化Ui_MainWindow類的MyThread對象,用於填裝子線程處理任務。

  self.my_thread = MyThread()

  2、將事件信號與槽函數建立聯系,通過count函數啟用線程。

  self.StopButton.clicked.connect(self.CountFilesNum)

  3、Count函數:

  self.textBrowser_2.append("開始檢測……")
  self.my_thread.is_on = True
  self.my_thread.start()#啟動線程

  4、設計MyThread類,繼承Qthread類

  my_signal = pyqtSignal(str)  #

  tipwords = ''
  def __init__(self):
      super(MyThread, self).__init__()
      self.tipwords = ''
      self.is_on = True

  定義一個信號(my_signal)用於向槽函數傳遞字符型變量(字符會輸出到textBrowser中),調用父類的INIT方法,完成初始化設置。

  5、定義線程中的主邏輯函數:

  all_content = os.listdir(target_path)

  ……

  self.my_signal.emit(str(self.tipwords))  

  函數執行完,釋放信號。線程中的信號關聯到append函數

  self.my_thread.my_signal.connect(self.appendTextBrowser)  

  實現了線程中數據返回主線程的目的。

  五、總結

  除了button中的信號與槽機制外,主、子線程也是通過信號與槽機制完成的關聯,可見,信號與槽機制,確實是PYQT的核心。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM