连接到PyQt信号时,同步PyQt QGLWidget和QWidget(与FigureCanvas)

时间:2014-12-22 11:27:42

标签: python matplotlib pyqt qthread synchronize

我正在使用PyQt来创建GUI。我有一个解算器线程来计算要显示的数据:

SolveODE 类(在新主题中):

class RepaintGLSignal(QtCore.QObject):
    signal_repaintGL = QtCore.pyqtSignal()

class SolveODE(QObject):
    def __init__(self, MBD_system=[], running=False, stopped=False, finished=False, parent=None):
        super(SolveODE, self).__init__(parent)
        self.repaintGL_signal = RepaintGLSignal()

    def solve_ODE__(self, t_0, t_n, q0, TOL, Hmax, Hmin):
        while running == TRUE:
            #    calculate-integrate here
            ...
            #    update opengl widget every (N-th) step
            self.repaintGL_signal.signal_repaintGL.emit()

模拟由 SimulationControlWidget 类控制,它有一个信号连接到更新OpenGL小部件:

class SimulationControlWidget(QWidget):
    def __init__(self, MBD_system_=[], parent=None, flags=0):
        super(SimulationControlWidget, self).__init__(parent)

        self.OpenGLWidget = OpenGLWidget()
        self.graphWidget = GraphWidget()

        #    create solver thread
        self.solver = SolveODE()
        self._solver_thread = QThread()
        self._solver_thread.start()
        self.solver.moveToThread(self._solver_thread)

        #    signal from thread SolveODE is connected to OpenGLWidget to repaint - update OpenGL widget
        self.solver.solveODE.repaintGL_signal.signal_repaintGL.connect(self.OpenGLWidget.repaintGL)
        self.solver.solveODE.repaintGL_signal.signal_repaintGL.connect(self.graphWidget.plot_graph)

在新窗口中,我使用matplotlib添加了一个带有 GraphWidget 类的图表:

import numpy as np
from PyQt4 import QtCore, QtGui
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

class GraphWidget(QtGui.QWidget):
    def __init__(self, parent=None, flags=0):
        super(GraphWidget, self).__init__(parent)

        self.setWindowTitle('Graph of motion')
        self.fig = Figure((8.0, 4.0), dpi=100)
        self.canvas = FigureCanvas(self.fig)
        self.axes = self.fig.add_subplot(111)
        self.layout = QtGui.QVBoxLayout(self)
        self.layout.addWidget(self.canvas)
        self.canvas.draw()

    @QtCore.pyqtSlot()
    def plot_graph(self):
        x = np.random.rand(10, 1)    #at the moment I just plot some random data, just to check if it is working correctly
        y = np.random.rand(10, 1)
        self.axes.plot(x, y, 'ro')
        self.canvas.draw()
        print "graph updated"

发出并连接信号self.repaintGL_signal以触发两个不同的动作(更新OpenGL widgwet和重绘matplotlib画布)。问题是当我按下开始按钮开始模拟时,OpenGL小部件正在顺利更新,但图表会延迟。为了清楚地表示我的问题,我在重绘图表后添加了print行,我得到以下输出:

Simulation is started
t = 0
graph updated
t = 1
graph updated
...
Simulation is finished
graph updated
graph updated
graph updated
graph updated
graph updated
graph updated

但输出应该是这样的

Simulation is started
t = 0
graph updated
t = 1
graph updated
t = 2
graph updated
t = 3
graph updated
t = 4
graph updated
...
Simulation is finished

我想问你如何解决这个问题?可以找到整个代码here

0 个答案:

没有答案