You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QThread结合pyqtgraph无性能提升问题咨询

Hey there! Let's figure out why your threaded pyqtgraph setup isn't giving you the CPU performance boost you're hoping for, and walk through fixes that should help.

Common Issues & Solutions for Your Threaded PyQtGraph Window

1. You're probably updating the GUI directly from the child thread

PyQt/PySide enforces a strict rule: all GUI operations must happen in the main thread. If your threaded code is calling pyqtgraph plotting methods (like plot() or clear()) directly from the worker thread, you're not just breaking Qt's thread safety rules—you're adding unnecessary cross-thread synchronization overhead that can keep CPU usage high (or even make it worse).

Fix it with signals & slots:

Move only your data-fetching logic to the child thread, then use Qt signals to send the data to the main thread for plotting. Here's a simplified example:

from PyQt5.QtCore import QThread, QObject, pyqtSignal
import psutil

class DataWorker(QObject):
    # Signal to send fetched data back to main thread
    new_data = pyqtSignal(float)
    _is_running = True

    def run(self):
        while self._is_running:
            # Only do the data fetch work here (no GUI calls!)
            cpu_val = psutil.cpu_percent(interval=0.1)
            self.new_data.emit(cpu_val)
            # Use Qt's thread sleep instead of time.sleep to respect event loops
            QThread.msleep(100)

    def stop(self):
        self._is_running = False

# In your main window class
class MultiPlotWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # Initialize your pyqtgraph widgets here
        self.cpu_plot = self.setup_pyqtgraph_plot()

        # Set up the worker thread
        self.worker = DataWorker()
        self.thread = QThread()
        self.worker.moveToThread(self.thread)

        # Connect signals: data from worker triggers GUI update
        self.worker.new_data.connect(self.update_cpu_plot)
        self.thread.started.connect(self.worker.run)

        # Start the thread
        self.thread.start()

    def update_cpu_plot(self, cpu_value):
        # This runs in the main thread - safe to update pyqtgraph here
        # Use setData() instead of re-plotting for better performance
        self.cpu_plot.setData([cpu_value], clear=True)

    def closeEvent(self, event):
        # Clean up the thread properly on window close
        self.worker.stop()
        self.thread.quit()
        self.thread.wait()
        event.accept()

2. Your data-fetching task is too fast to benefit from threading

Threads shine when you have long-running tasks (like heavy computations, slow IO, or waiting for external data). If your current data-fetching logic only takes a few milliseconds to complete, moving it to a thread won't reduce CPU usage—because the bottleneck wasn't blocking the main thread in the first place.

Verify this:

Add timing to your non-threaded timer callback to see how long data fetching takes:

import time

def timer_callback(self):
    start_time = time.time()
    # Your existing data fetch code
    data = self.get_data()
    print(f"Data fetch took: {(time.time() - start_time)*1000:.2f}ms")
    self.update_plots(data)

If the time is under ~10ms, threading won't help here—you'll need to optimize the GUI rendering instead.

3. You're using QThread incorrectly

Some tutorials teach subclassing QThread and overriding run(), but this can lead to mistakes if you don't manage the thread's event loop properly. Using time.sleep() instead of Qt's thread-safe sleep methods can also cause unnecessary CPU wakeups.

Best practices for QThread:

  • Always move a QObject worker to a QThread (like the example above) instead of subclassing QThread directly.
  • Use QThread.msleep()/usleep() instead of time.sleep() to let the thread respect Qt's event system.
  • Always clean up threads (call quit() + wait()) when closing the window to avoid zombie threads.

4. The CPU overhead is coming from pyqtgraph rendering

If you have multiple plots updating frequently, the CPU usage might be from GUI rendering (which happens in the main thread, so threads can't help here). Try these optimizations:

  • Reduce the refresh rate (if 0.1s is too frequent, try 0.2s).
  • Use PlotDataItem.setData() instead of calling plot() every time—this reuses existing plot items instead of creating new ones.
  • Disable unnecessary plot features (like auto-scaling if you don't need it, or hide grid lines temporarily).

内容的提问来源于stack exchange,提问作者Misael Alarcon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:16:55