关闭window后方法仍然是运行

Method is still running after closing window

我无法理解 window 对象的工作原理。我通过 matplotlib 在二级 window 上有一个实时绘图。该图每秒更新一次新的计算值。 我期望的是每当我关闭第二个 window 时停止 运行 并在我重新打开它时重新启动的方法。我可以在关闭第二个 window 时重置数组值,但如前所述,这种计算值的方法仍然是 运行.

这是我的代码(最初使用传感器,我修改它以生成随机数):

from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout
import sys
import random
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure


# The main window 
class Window(QWidget):
    def __init__(self):
        super().__init__()
 
        self.setGeometry(200,200, 400,300)
        self.setWindowTitle('Test')
        self.demo = None
        
        self.create_buttons()
        
    def create_buttons(self):
        btn1 = QPushButton('Open window', self)
        btn1.setGeometry(100,100, 100,100)
        btn1.clicked.connect(self.open_w)
        
    def open_w(self):
        if self.demo is None:
            self.demo = AppDemo()
        self.demo.show()
        
# Second window, where I plot the data
class AppDemo(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(650, 500)
        self.plotwidget = QWidget(self)
        self.chart = Matplotlibwidget()
        self.chart.plot_widget(self.plotwidget, self.chart)
        
    def closeEvent(self, event):
        event.accept()
        func.start_lists()
        print('Window closed')
        
# My widget for my graph        
class Matplotlibwidget(FigureCanvas):
    def __init__(self, parent=None):
        fig = Figure()
        self.axes = fig.add_subplot(111)
        
        FigureCanvas.__init__(self, fig)
        self.setParent(parent)
        FigureCanvas.updateGeometry(self)      
    
    def plot_widget(self, canvasWidget, graph):
        self.layoutvertical = QVBoxLayout(canvasWidget)
        self.layoutvertical.addWidget(graph)        
        timer = QtCore.QTimer(self)
        timer.timeout.connect(self.plotting)
        timer.start(1000)
              
    def plotting(self):
        self.y = func.calculate()
        func.appends(self.y)
        self.axes.cla()
        self.axes.plot(func.x, func.y)
        self.draw()

# This is a generic class I use to calculate the data, originally this is a class for my sensor
class FuncTime ():
    def __init__(self):
        self.start_lists()
         
    def start_lists(self):
        self.x, self.y = [0], [1]
        
    def calculate(self):
        return self.y[-1] + self.y[-1] * random.uniform(-0.1, 0.1)
        
    def appends(self, y):
        print(self.x[-1], ', ', self.y[-1])
        self.x.append(self.x[-1] + 1)
        self.y.append(y)

  
app = QApplication(sys.argv)
func = FuncTime()
window = Window()
window.show()
sys.exit(app.exec_())

window关闭并不意味着定时器停止,您必须使用QTimer的停止方法来实现它。

from functools import cached_property
import random
import sys

from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure


class Window(QWidget):
    def __init__(self):
        super().__init__()

        self.setGeometry(200, 200, 400, 300)
        self.setWindowTitle("Test")
        self.create_buttons()

    @cached_property
    def demo(self):
        return AppDemo()

    def create_buttons(self):
        btn1 = QPushButton("Open window", self)
        btn1.setGeometry(100, 100, 100, 100)
        btn1.clicked.connect(self.open_w)

    def open_w(self):
        self.demo.chart.start()
        self.demo.show()


class AppDemo(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(650, 500)

        self.chart = Matplotlibwidget()

        lay = QVBoxLayout(self)
        lay.addWidget(self.chart)

    def closeEvent(self, event):
        super().closeEvent(event)
        self.chart.stop()


class Matplotlibwidget(FigureCanvas):
    def __init__(self, parent=None):
        fig = Figure()
        self.axes = fig.add_subplot(111)
        FigureCanvas.__init__(self, fig)
        self.setParent(parent)
        self.updateGeometry()

    @cached_property
    def timer(self):
        return QTimer(interval=1000, timeout=self.handle_timeout)

    @cached_property
    def func_time(self):
        return FuncTime()

    def start(self):
        self.timer.start()

    def stop(self):
        self.timer.stop()
        self.func_time.reset()

    def handle_timeout(self):
        self.plotting()

    def plotting(self):
        self.y = self.func_time.calculate()
        self.func_time.appends(self.y)
        self.axes.cla()
        self.axes.plot(self.func_time.x, self.func_time.y)
        self.draw()


class FuncTime:
    def __init__(self):
        self.reset()

    def reset(self):
        self.x, self.y = [0], [1]

    def calculate(self):
        return self.y[-1] + self.y[-1] * random.uniform(-0.1, 0.1)

    def appends(self, y):
        print(self.x[-1], ", ", self.y[-1])
        self.x.append(self.x[-1] + 1)
        self.y.append(y)


app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())