pyqt5教程(十一)多線程防阻塞

一、

當我們設計的界面在處理比較長時間的任務時,就會出現阻塞,出現程序未響應,導致程序停止的情況,例如這個百度圖片下載器
所以我們應把主線程與工作線程分離,以免主循環阻塞,造成程序停止響應

二、例子

from PyQt5.QtCore import *  
from PyQt5.QtGui import *  
from PyQt5.QtWidgets import *
import sys

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.t = 0

        window = QWidget()
        vbox = QVBoxLayout(window)
        #vbox = QVBoxLayout(window)

        lcdNumber = QLCDNumber()
        button = QPushButton("測試")
        vbox.addWidget(lcdNumber)
        vbox.addWidget(button)

        self.timer = QTimer()
        
        button.clicked.connect(self.work)
        self.timer.timeout.connect(self.setTime)

        self.setLayout(vbox)
        self.show()

    def setTime(self):
        self.t += 1
        self.lcdNumber.display(self.t)

    def work(self):
        self.timer.start(10000)
        for i in range(200000000):
            pass
        self.timer.stop()
        
        
if __name__ == "__main__":        
    app = QApplication(sys.argv)
    th = Example()
    sys.exit(app.exec_())

運行這個程序,當我們點擊測試,進行較長時間的任務時,程序就無法選中了,最終停止運行。

三、多線程

下面用多線寫法解決該問題

from PyQt5.QtCore import *  
from PyQt5.QtGui import *  
from PyQt5.QtWidgets import *
import sys

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.t = 0

        window = QWidget()
        vbox = QVBoxLayout(window)
        #vbox = QVBoxLayout(window)

        self.lcdNumber = QLCDNumber()
        button = QPushButton("測試")
        vbox.addWidget(self.lcdNumber)
        vbox.addWidget(button)

        self.timer = QTimer()
        
        button.clicked.connect(self.Work)
        self.timer.timeout.connect(self.CountTime)

        self.setLayout(vbox)
        self.show()

    def CountTime(self):
        self.t += 1
        self.lcdNumber.display(self.t)

    def Work(self):
        self.timer.start(1000)
        self.thread = RunThread()
        self.thread.start()
        self.thread.trigger.connect(self.TimeStop)

    def TimeStop(self):
        self.timer.stop()
        print("運行結束用時",self.lcdNumber.value())
        self.t = 0
        

class RunThread(QThread):
    # python3,pyqt5與之前的版本有些不一樣
    #  通過類成員對象定義信號對象
    # _signal = pyqtSignal(str)

    trigger = pyqtSignal()
 
    def __init__(self, parent=None):
        super(RunThread, self).__init__()

 
    def __del__(self):
        self.wait() 

    def run(self):
        # 處理你要做的業務邏輯,這里是通過一個回調來處理數據,這里的邏輯處理寫自己的方法
        # wechat.start_auto(self.callback)
        # self._signal.emit(msg);  可以在這里寫信號煥發
        for i in range(203300030):  
            pass  
        self.trigger.emit()
        # self._signal.emit(msg)

    def callback(self, msg):
        # 信號煥發,我是通過我封裝類的回調來發起的
        # self._signal.emit(msg)
        pass

        

if __name__ == "__main__":
    app = QApplication(sys.argv)
    th = Example()
    sys.exit(app.exec_())

從此以后,我們可以開始寫很多應用了

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 從哪說起呢? 單純講多線程編程真的不知道從哪下嘴。。 不如我直接引用一個最簡單的問題,以這個作為切入點好了 在ma...
    Mr_Baymax閱讀 2,831評論 1 17
  • Object C中創建線程的方法是什么?如果在主線程中執行代碼,方法是什么?如果想延時執行代碼、方法又是什么? 1...
    AlanGe閱讀 1,793評論 0 17
  • Java多線程學習 [-] 一擴展javalangThread類 二實現javalangRunnable接口 三T...
    影馳閱讀 2,987評論 1 18
  • 用markdown寫項目需求說明(對內開發版) 項目概述: 這是一個前端使用bootstrap, jQuery框架...
    小小奶狗閱讀 3,347評論 0 1
  • 親愛的大發家人們: 大家晚上好,每次學習活法后都有不同的感悟,每一小節的標題都是鼓舞人心的勵志語句,雖然...
    徐書成xsc閱讀 1,468評論 0 0