Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you run Matplotlib in another thread on PyQt

I need to display some charts in my PyQt application, so I write down these code. It is works, but sometimes, draw a chart will spend a lot of time, it will "freeze" the main window.

I think do it in another thread should resolved it. But how can I do it? Or, there is another way to draw a chart in "non-block" mode?

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...
like image 386
比尔盖子 Avatar asked Sep 21 '25 09:09

比尔盖子


1 Answers

You should us QThreads in your Qt application (to make the frame work do all of the hard work for you)

  1. put your time consuming work in a worker class (that is derived from QObject)

  2. In you class that is caling the plotting add something like

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

and communicate with your worker via signals/slots. If you call it directly (as in self.worker.do_slow_stuff()), it will run on the thread you call it from, which will block the main event loop making the interface freeze.

A good explanation of how to (and not to) do threading with QThread (read both..the first one now describes the default behaviour)

like image 163
tacaswell Avatar answered Sep 22 '25 23:09

tacaswell