Почему таймер matplotlib ускоряется при нажатии кнопки PyQt?

1

У меня есть небольшой графический интерфейс, который я сделал с PyQt5, который в основном состоит из графика в реальном времени и двух кнопок для остановки и возобновления. Я хочу обновить сюжет каждые measure_interval 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_()
Теги:
matplotlib
pyqt5

1 ответ

1
Лучший ответ

Интервал таймера сбрасывается на 0 при нажатии кнопки запуска. Это связано с тем, что .start() принимает interval аргумента, который предназначен для установки интервала для таймера.

Однако при использовании функции start() непосредственно в качестве обратного вызова для clicked сигнала кнопки, на обратный вызов будет False некоторый статус False. Поэтому при нажатии кнопки вы вызываете start(False). Это то же самое, что и start(0) в python, и поэтому интервал устанавливается равным 0.

Чтобы этого избежать, вы можете использовать функцию лямбда и убедиться, что start() вызывается без аргумента, и в этом случае он будет помнить инициализированный интервал и использовать его.

button_start.clicked.connect(lambda : self._timer.start())
  • 0
    Хороший и простой обходной путь, спасибо. Я все еще пытаюсь выяснить, почему происходит сброс ... Дайте мне знать, если вы узнаете что-нибудь об этом!
  • 0
    Я нашел объяснение. Смотрите обновленный пост.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню