6. PyQt5 中的多線程的使用(上)


專欄地址 ʅ(‾◡◝)ʃ


這一節引入了多線程這個非常重要概念, 在我認為多線程的重要性是緊緊次於信號與槽函數的, 因為在平時經常使用

1. 為什么要用多線程

先看下面這一個示例代碼
6.1

from form import Ui_Form
from PyQt5.QtWidgets import *
import sys
import time

class MyWin(QWidget,Ui_Form):
    """docstring for Mywine"""
    def __init__(self):
        super(MyWin, self).__init__()
        self.setupUi(self)

    def test(self): # 這里test就是槽函數, 當點擊按鈕時執行 test 函數中的內容, 注意有一個參數為 self
        for i in range(10):
            self.pushButton.setText(str(i))
            time.sleep(1)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mywin = MyWin() # 實例化一個窗口小部件
    mywin.setWindowTitle('Hello world!') # 設置窗口標題
    mywin.show() #顯示窗口
    sys.exit(app.exec())

代碼很簡單, 就是點擊按鈕后, 將按鈕的內容設置為 0, 然后等待一秒后 再設置 為1, 如此循環, 一直設置到 9, 這個過程結束
但是在實際運行的過程中點擊按鈕后就沒有反應了, 一直等待 10 秒后直接將按鈕的內容設置為 9

這是因為圖形化界面必須等待代碼中的 test() 槽函數執行完畢后再更新圖形話界面的內容, 所以直到 test() 函數執行完畢后 按鈕的內容只會被設置為 9, 而沒有中間的設置過程

當然在實際的軟件開發的時候阻塞的時間可能會更長, 想象一下如果你制作一個下載器有一個進度條, 開始時進度還是0 ,過了很長時間突然件進度突然跑滿了, 會讓用戶有一種軟件卡住的錯覺, 這個時候我們就需要使用 PyQt5 的多線程了

2. 怎么使用多線程

python 編程基礎的人可能第一個想到的是 threading 這個庫
但這里不是用到 threading , 而是 PyQt5 中的多線程類
示例代碼:
6.2

from form import Ui_Form
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QThread, pyqtSignal
import sys
import time

class MyWin(QWidget,Ui_Form):
    """docstring for Mywine"""
    def __init__(self):
        super(MyWin, self).__init__()
        self.setupUi(self)
        self.mythread = MyThread() # 實例化自己建立的任務線程類
        self.mythread.signal.connect(self.callback) #設置任務線程發射信號觸發的函數

    def test(self): # 這里test就是槽函數, 當點擊按鈕時執行 test 函數中的內容, 注意有一個參數為 self
        self.mythread.start() # 啟動任務線程

    def callback(self,i): # 這里的 i 就是任務線程傳回的數據
        self.pushButton.setText(i)

class MyThread(QThread): # 建立一個任務線程類
    signal = pyqtSignal(str) #設置觸發信號傳遞的參數數據類型,這里是字符串
    def __init__(self):
        super(MyThread, self).__init__()

    def run(self): # 在啟動線程后任務從這個函數里面開始執行
        for i in range(10):
            self.signal.emit(str(i)) #任務線程發射信號用於與圖形化界面進行交互
            time.sleep(1)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mywin = MyWin() # 實例化一個窗口小部件
    mywin.setWindowTitle('Hello world!') # 設置窗口標題
    mywin.show() #顯示窗口
    sys.exit(app.exec())

可能看到這部分, 感覺很亂多出了很多代碼, 每行代碼的意義注釋我都已經進行了詳細的標注
這里簡單說一下建立任務線程的步驟:

  1. 導入需要的 的類 from PyQt5.QtCore import QThread, pyqtSignal 其實為了簡單你也可這樣寫 from PyQt5.QtCore import *
  2. 編寫任務線程的類 這里的任務線程類是 MyThread 並讓它繼承 QThread , 並設置觸發信號傳遞的數據類型, 編寫 run()函數, 設置觸發
  3. MyWin 類中的初始化函數中, 初始化一個任務線程, 設置任務線程觸發后接受的函數
  4. 在合適的位置啟動 任務線程, 比如這里我是在點擊按鈕后啟動的任務線程
  5. 編寫任務線程觸發的槽函數 callback()

其實剛學到這里的時候, 我也很懵, 但是很多都是固定的寫法, 只要注意上面的幾個關鍵的地方就可以了
啟動程序后, 按鈕的內容從 0 自增加到 9
這里要注意的是 傳遞信號必須事先定義好數據類型, 而傳遞過去的類型必須是已經定義好的數據類型
這里我只說了 任務線程 傳遞給圖形化界面數據(代碼中數據是 0, 1, 2, 3....9), 而沒有圖形界面傳遞給任務線程數據
下一節說明 圖形化界面如何傳遞給任務線程數據


免責聲明!

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



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