为啥按下 PyQt 按钮时 matplotlib 的计时器会加快?

Posted

技术标签:

【中文标题】为啥按下 PyQt 按钮时 matplotlib 的计时器会加快?【英文标题】:Why does matplotlib's timer speed up when PyQt button is pressed?为什么按下 PyQt 按钮时 matplotlib 的计时器会加快? 【发布时间】:2018-07-30 13:41:39 【问题描述】:

我有一个使用 PyQt5 制作的小型 GUI,它基本上由一个实时绘图和两个用于停止和恢复的按钮组成。我想每measure_interval 毫秒更新一次绘图。在我的脚本中,我将其设置为 1000(1 秒)。程序开始正常工作,但是当我按下“停止”按钮然后用“开始”恢复时,即使它的时间间隔没有改变,计时器似乎也在加速。事实上,每当我按下“开始”按钮时,绘图速度都会加快(即使之前没有停止它)。所以我相信错误就在那里,即使我无法发现它。这是我的代码:

import numpy as np
from matplotlib.backends.qt_compat import QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.figure import Figure

class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        global measure_interval
        super(ApplicationWindow, self).__init__()
        self._main = QtWidgets.QWidget()
        self.setCentralWidget(self._main)
        # Canvas
        dynamic_canvas = FigureCanvas(Figure(figsize=(10, 10)))
        self._dynamic_ax = dynamic_canvas.figure.subplots()
        self._timer = dynamic_canvas.new_timer(measure_interval, [(self._update_window, (), )])
        self._timer.start()
        # Buttons
        button_stop = QtWidgets.QPushButton('Stop', self)
        button_stop.clicked.connect(self._timer.stop)
        button_start = QtWidgets.QPushButton('Start', self)
        button_start.clicked.connect(self._timer.start)
        # Layout
        layout = QtWidgets.QVBoxLayout(self._main)
        layout.addWidget(dynamic_canvas)
        layout.addWidget(button_stop)
        layout.addWidget(button_start)

    def _update_window(self):
        global x, y, win_size, count_iter
        # Update variables
        x.append(x[count_iter] + 0.01)
        y.append(np.random.random())
        idx_inf = max([count_iter-win_size, 0])
        count_iter += 1
        # Plot
        self._dynamic_ax.clear()
        self._dynamic_ax.plot(x[idx_inf:count_iter], y[idx_inf:count_iter],'-o', color='b')
        self._dynamic_ax.figure.canvas.draw()
#%%
if __name__ == "__main__":
    measure_interval = 1000 # milisegs
    win_size = 100 # maximum window size (samples)
    y = [np.random.random()]
    x = [0]
    count_iter = 0
    qapp = QtWidgets.QApplication([])
    app = ApplicationWindow()
    app.show()
    qapp.exec_()

【问题讨论】:

【参考方案1】:

按下开始按钮时,计时器间隔重置为0。 这是因为.start() 函数接受了一个参数interval 来设置定时器的时间间隔。

但是,当直接使用start() 作为按钮的clicked 信号的回调时,一些状态False 将提供给回调。所以基本上当你按下按钮时,你调用start(False)。这与 python 中的start(0) 相同,因此间隔设置为0

为避免这种情况,您可以使用 lambda 函数并确保在没有参数的情况下调用 start(),在这种情况下,它会记住最初设置的间隔并使用它。

button_start.clicked.connect(lambda : self._timer.start())

【讨论】:

不错的简单解决方法,谢谢。我仍在尝试找出重置发生的原因...如果您发现任何相关信息,请告诉我! 不错的收获。谢谢!

以上是关于为啥按下 PyQt 按钮时 matplotlib 的计时器会加快?的主要内容,如果未能解决你的问题,请参考以下文章

无法在 pyqt5 中嵌入的 matplotlib 上绘制线条

按下按钮时获取 PyQt4 以打开另一个 Qt 窗口

pyqt 中的多个嵌入式 matplotlib 画布在鼠标悬停时改变大小

当我在 PyQt5 窗口中嵌入 Matplotlib 图形时,为啥有两个重复的轴标签?

python 在pyqt中matplotlib图形之间的变化

matplotlib 绘图问题