多執行緒環境下 PyQtGraph 繪畫解決方案

华科云商小雪發表於2024-03-05

在我們多執行緒編譯並且使用PyQtGraph進行繪圖時,我們需要確保所有的圖形操作都在主執行緒中執行,主要是因為PyQtGraph是在主執行緒中建立的,並且不是執行緒安全的。下面我們將深入探討在多執行緒環境下使用PyQtGraph繪圖並做詳細記錄。

1、問題背景

在使用 PyQtGraph 繪圖時,如果在主執行緒之外進行繪圖操作,可能會出現繪圖不生效或程式崩潰的問題。這是因為 PyQtGraph 的繪圖操作需要在主執行緒中進行,否則可能會導致繪圖操作與 GUI 介面更新操作衝突。

2、解決方案

為了解決這個問題,可以採用以下解決方案:

  1. 將繪圖操作封裝成一個函式,並將其放入一個佇列中;

  1. 建立多個工作執行緒,並讓每個工作執行緒從佇列中獲取繪圖任務,然後在主執行緒中執行繪圖操作;

  1. 透過訊號和槽機制將工作執行緒和主執行緒連線起來,以便工作執行緒在完成繪圖任務後通知主執行緒更新 GUI 介面。

以下是一個示例程式碼,演示瞭如何使用上述解決方案來在多執行緒環境下進行 PyQtGraph 繪圖:


from 
PyQt5 
import 
QtCore, 
QtWidgets

import pyqtgraph as pg
import threading
import Queue

# 建立一個繪圖物件
app = QtWidgets. QApplication([])
win = pg. GraphicsWindow( title = "Basic plotting examples")
plot = win. addPlot( title = "Simple plot", labels ={ 'left': 'Y Axis', 'bottom': 'X Axis'})
curve = plot. plot( curve = np. random. normal( size = 100))

# 定義繪圖函式
def draw( data):
curve. setData( data)

# 將繪圖函式封裝成一個類
class DrawingThread( threading. Thread):
def __init__( self, queue):
super( DrawingThread, self). __init__()
self. queue = queue

def run( self):
while True:
# 從佇列中獲取繪圖任務
data = self. queue. get()

# 在主執行緒中執行繪圖操作
QtCore. QMetaObject. invokeMethod( curve, "setData", QtCore. Qt. QueuedConnection,
QtCore. Q_ARG( object, data))

# 通知主執行緒更新 GUI 介面
QtCore. QMetaObject. invokeMethod( app, "processEvents", QtCore. Qt. QueuedConnection)

# 標記任務完成
self. queue. task_done()

# 建立一個佇列來儲存繪圖任務
queue = Queue. Queue()

# 建立多個工作執行緒
num_worker_threads = 3
for i in range( num_worker_threads):
thread = DrawingThread( queue)
thread. daemon = True
thread. start()

# 將繪圖任務放入佇列中
for i in range( 100):
queue. put( np. random. normal( size = 100))

# 啟動應用程式
app. exec_()

在這個示例中,我們建立了一個繪圖物件 curve ,並將其新增到 PyQtGraph 的繪圖視窗中。然後,我們定義了一個繪圖函式 draw() ,這個函式將資料 data 繪製到 curve 上。

接下來,我們將繪圖函式封裝成一個類 DrawingThread 。這個類繼承自 threading.Thread ,並重寫了 run() 方法。在 run() 方法中,我們從佇列中獲取繪圖任務,然後在主執行緒中執行繪圖操作。

最後,我們建立了一個佇列 queue 來儲存繪圖任務,並建立了多個工作執行緒來從佇列中獲取繪圖任務並執行繪圖操作。

在主執行緒中,我們透過訊號和槽機制將工作執行緒和主執行緒連線起來,以便工作執行緒在完成繪圖任務後通知主執行緒更新 GUI 介面。

透過這種方式,我們可以在多執行緒環境下進行 PyQtGraph 繪圖,並且不會出現繪圖不生效或程式崩潰的問題。

最重要的需要注意的是,雖然資料生成過程是在工作執行緒中進行的,但資料傳輸和繪圖更新操作都是在主執行緒中執行的,以確保PyQtGraph的執行緒安全性。如果有更多問題可以留言探討。


來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70034537/viewspace-3008079/,如需轉載,請註明出處,否則將追究法律責任。

相關文章