【问题标题】:How do you run Matplotlib in another thread on PyQt你如何在 PyQt 的另一个线程中运行 Matplotlib
【发布时间】:2013-01-24 00:49:18
【问题描述】:

我需要在我的 PyQt 应用程序中显示一些图表,所以我记下了这些代码。 这是可行的,但有时,绘制图表会花费大量时间,它会“冻结”主窗口。

我认为在另一个线程中执行应该可以解决它。但是我该怎么做呢? 或者,还有另一种“非阻塞”模式绘制图表的方法?

from PyQt4 import QtGui
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas   
from matplotlib.figure import Figure

class MplCanvas(FigureCanvas):

    def __init__(self):
        self.fig = Figure()
        self.axes = self.fig.add_subplot(111)

        # do something...
        FigureCanvas.__init__(self, self.fig)
        FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)
        # do something...

    def draw(self):
        # do something...

【问题讨论】:

  • 现在实现类似的东西。这是我的想法。您必须使用多个类,一个基于 PyQt 的 QDialog 或类似的 GUI 输出。另一个是基于 QThread 的工人阶级。一旦 QThread 完成绘图,它将使用 PyQt 信号引擎将图形和画布实例传递给 GUI 对象。我尝试将 QDialog 和 QThread 组合成一个类,但显然你做不到。 (我相信你可以做到,但使用 2 个单独的类更容易)

标签: python matplotlib pyqt4


【解决方案1】:

您应该在您的Qt 应用程序中使用QThreads(以使框架为您完成所有繁重的工作)

  1. 把你的耗时工作放在一个工人班上(派生自QObject

  2. 在你正在校准绘图的类中添加类似

    self.thread = QtCore.QThread(parent=self)
    
    self.worker = Worker(parent=None)
    self.worker.moveToThread(self.thread)
    self.thread.start()
    

并通过信号/插槽与您的工作人员进行通信。如果你直接调用它(如self.worker.do_slow_stuff()),它将在你调用它的线程上运行,这将阻塞主事件循环,使界面冻结。

一个很好的explanation 如何(和not to)使用QThread 进行线程处理(阅读两者......第一个现在描述了默认行为)

【讨论】:

  • 只是出于好奇而提出的问题。您是否曾经成功地让 QThread 应用程序在 Windows 上运行并长时间稳定而不会崩溃?我最终放弃并改变了我的整个程序模型以使用多处理,这让我发疯了。
【解决方案2】:

像这样的简单用途的 Python 线程基础非常简单。

你需要

import threading

然后,不只是调用 x.draw(),而是创建一个线程并按如下方式运行它:

draw_thread = threading.Thread(target=x.draw)
draw_thread.start()

这可能会让你至少完成 90% 的工作。您可以阅读文档来检测诸如仍在运行的线程、等待线程等内容。但从本质上讲,这并不难,如果 ti 只是简单的交互式图形,这可能就足够了。

但请注意,如果 draw() 引用全局变量,则可能会发生竞争条件,从而使您的程序不可靠。这是编写具有良好耦合、干净接口和不引用可变全局变量的代码的另一个优势(除非使用锁定来保护这些资源)。

【讨论】:

  • 你必须在 PyQt 中使用 QThreads。普通的旧线程无法正常工作
  • 啊,对我来说是个消息-感谢您的评论。 QThreadsthreading 线程配合得好吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-27
  • 2021-10-26
  • 2012-12-04
  • 1970-01-01
相关资源
最近更新 更多