Pyqt子界面刷新问题

类中设置了两个方法,用于绘图和更新数据,第一次按下按钮触发Draw函数时使用正常,但是关闭窗口后再次点击按钮,弹出的窗口不再更新,需要通过缩放窗口才可以正常显示调整后的界面,update()、repaint()、showNormal()、adjustSize()等方法均无效(不排除使用方法错误),第二次调用时是直接使用之前创建的窗口,但是在关闭时删除画布和布局后并不能重新生成画布和布局,问题出现在用字典存放的重复利用的窗口与新的布局画布的位置,线程更新正常。

class Ui_MainWindow(object):
    def __init__(self):
        self.plots = {}
        self.timers = {}# 多个线程
        self.widgets = {}
        for name in ['B1', 'B2', 'B3', 'B4', 'B5', 'B6']:
            self.widgets[name] = QWidget()
            self.widgets[name].setWindowTitle(name)


    def Draw(self, name, index, ylabel):
        if name in self.plots:
            fig, ax = self.plots[name]
        else:
            fig, ax = matplotlib.pyplot.subplots()
            self.plots[name] = (fig, ax)

        canvas = FigureCanvasQTAgg(fig)
        layout = QVBoxLayout(self.widgets[name])
        layout.addWidget(canvas)
        self.widgets[name].show()


                def CloseEvent(event, layout, canvas):
            try:
                print("Widget is closed")
                self.timers[name] = False  # 将对应的标志位设置为False,关闭线程
                timer.timeout.disconnect(update)  # 断开与主时间对象的连接
                self.widgets[name].close()
            except Exception as e:
                print(str(e))

        self.widgets[name].closeEvent = lambda event: CloseEvent(event, layout, canvas)

        self.timers[name] = True  # 将对应的标志位设置为True

        def update():#根据name运行updata启动数据更新线程
            if self.timers[name]:
                self.UpdatePlot(ax, name, index, ylabel)

        timer.timeout.connect(update)#通过主线程连接update进而选择线程


    def UpdatePlot(self, ax, name, index, ylabel):
        print(name + "updata")
        global table#存放数据的表格
        if not table:
            return
        data = [row[index] for row in table]
        t = [row[0] for row in table]
        time = []
        for item in t:
            hours, minutes, seconds = item.split(":")
            second = int(hours) * 3600 + int(minutes) * 60 + int(seconds)
            time.append(second)

        ax.clear()  # 清除当前图像
        ax.plot(time, data)
        ax.set_xlabel('time/s')
        ax.set_ylabel(ylabel)
        ax.set_title(name)
        fig = self.plots[name][0]
        fig.canvas.draw()

你的问题可能出现在关闭窗口并不真正销毁窗口对象,而是隐藏了它。因此,当你再次打开窗口时,你正在重新打开隐藏的旧窗口,而非新建一个窗口。在这个旧窗口中,你的图像和布局可能不再有效或正确。

在关闭窗口时,尝试完全删除和销毁旧的布局和画布,然后在打开窗口时,每次都创建新的布局和画布。尝试更新你的Draw函数,让它每次都创建新的图像和布局,像这样:

def Draw(self, name, index, ylabel):
    fig, ax = matplotlib.pyplot.subplots()
    self.plots[name] = (fig, ax)
    canvas = FigureCanvasQTAgg(fig)
    
    # 每次都创建新的布局
    layout = QVBoxLayout(self.widgets[name])
    self.widgets[name].setLayout(layout)

    # 在添加新的画布前,清除布局中的所有元素
    while layout.count():
        child = layout.takeAt(0)
        if child.widget():
            child.widget().deleteLater()

    layout.addWidget(canvas)
    self.widgets[name].show()

同时,请注意,当你使用self.widgets[name].setLayout(layout)设置新布局时,Qt会自动删除并销毁旧布局。因此,确保你已保存所有需要保存的数据,因为在设置新布局后,旧布局和它包含的所有小部件都将被删除。