close

今天練習如何在pyqt5開啟兩個執行緒,

兩個執行緒各自繪製矩形在同一個畫布,

因此必須考慮如何"等待",當另一個執行緒占用該畫布時

此外,第一個thread執行時間較第二個執行緒多

 

首先,新增RectThread.py

 

from PyQt5.QtCore import QThread
from PyQt5.QtGui import QPainter
from PyQt5.QtCore import QThread, QRect

創建一個繼承QThread的RectThread自訂義

創建階段__init__

class RectThread(QThread):
    def __init__(self, label, pixmap, y, locker, color, sleep_time):
        super().__init__()
        # 顯示在label元件
        self.label = label
        # 畫布
        self.pixmap = pixmap
        # 繪製矩形高度位置
        self.y = y
        # 利用locker占用資源,強迫另一個thread等待
        self.locker = locker
        # 繪製矩形顏色
        self.color = color
        # 目前執行緒休眠時間
        self.sleep_time = sleep_time

並覆寫run()

# overloading run method
    def run(self):
        # 跑一個for-loop          
        for i in range(10, 300, 1):
            # 目前thread佔用painter,避免另一個thread同時使用painter(意味著另一個thread必須等待)
            self.locker.lock()
            # 創建畫筆,QPainter傳入畫布
            painter = QPainter(self.pixmap)
            # 繪製填滿矩形,每次向右移動i
            painter.fillRect(QRect(i, self.y, 20, 20), self.color)
            # painter.drawEllipse(i, self.y, 20, 20)
            self.label.setPixmap(self.pixmap)
            painter.end()
                     
            # 避免GUI資源耗盡(讓目前painter有時間釋放)
            self.msleep(1)
           
            # 釋放目前painter給另一個thread
            self.locker.unlock()  

            # 目前thread暫停一會(讓另一個thread也可以分時使用相同painter)
            self.msleep(self.sleep_time)

以上為RectThread.py

新增main.py

import sys
import typing
from PyQt5.QtWidgets import QApplication, QLabel
from PyQt5.QtCore import QMutex
from PyQt5.QtGui import QPixmap, QColor
from RectThread import RectThread


if __name__ == "__main__":
    app = QApplication(sys.argv)

    # 兩個threads共用locker,讓資源可以共享,
    # 但同一時間只有一個thread可以使用( locker.lock() ),
    # 另一個thread必須等待直到對方不在使用中( locker.unlock() )
    locker = QMutex()

    # 顯示在QLabel上
    label = QLabel()
    label.resize(350, 200)

    # 指定畫布大小並塗白色
    pixmap = QPixmap(350, 200)
    pixmap.fill(QColor("white"))
   
    # 繪製矩形高度
    draw_pos_y = 50
    # 執行緒休眠時間
    sleep_time = 4
    # 第一個執行緒
    thread1 = RectThread(label, pixmap, draw_pos_y, locker,  QColor("blue"), sleep_time)
       
    draw_pos_y = 100
    sleep_time = 9
    # 第二個執行緒
    thread2 = RectThread(label, pixmap, draw_pos_y, locker,  QColor("red"), sleep_time)
   
    label.setWindowTitle("pthread example")
    label.show()

    # 啟動兩組執行緒
    thread1.start()
    thread2.start()
   
    sys.exit(app.exec_())

 

arrow
arrow
    全站熱搜

    me1237guy 發表在 痞客邦 留言(0) 人氣()