You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5中QTableWidget无法多次刷新加载数据的问题排查

解决QTableWidget刷新后不显示新数据的问题

我帮你揪出问题根源了!核心问题在于你复用了同一个tab2实例,第二次筛选数据时,新创建的TableWidget并没有被添加到标签页的布局里,布局里还是之前那个被清空的旧表格控件,所以看不到新数据。

问题细节拆解

  • 第一次点击"Select Group"时,你给tab2添加了布局和tableWidget,一切正常显示。
  • 点击"Refresh"后,你清空了标签页切回分组选择页,但tab2里的旧布局和空表格并没有被清除。
  • 再次点击"Select Group"时,你创建了新的TableWidget并赋值给self.tab2.tableWidget,但这个新控件并没有被加入到tab2的布局中——布局里还是那个被你清空行的旧表格,自然看不到新数据。

修复方案

最简单的解决办法是每次筛选数据时都重新创建一个全新的tab2对象,而不是复用初始化时的那个,这样每次生成的标签页都是干净的,不会残留旧控件。

下面是修改后的完整代码,我标注了关键修改点:

import sys
from PyQt5 import QtWidgets, QtGui, QtCore
import pandas as pd

class TableWidget(QtWidgets.QTableWidget):
    def __init__(self, tab2_df, parent=None):
        super().__init__(parent)
        nRows = len(tab2_df.index)
        nColumns = len(tab2_df.columns)
        self.setRowCount(nRows)
        self.setColumnCount(nColumns)
        for i in range(self.rowCount()):
            for j in range(self.columnCount()):
                x = "{}".format(tab2_df.iloc[i, j])
                self.setItem(i, j, QtWidgets.QTableWidgetItem(x))
        print(tab2_df) # 验证新数据是否正确获取

class Window(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__()
        self.title = "Reporting Test"
        self.left = 400
        self.top = 50
        self.width = 1300
        self.height = 700
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.table_widget = MyTableWidget(self)
        self.setCentralWidget(self.table_widget)
        self.show()

class MyTableWidget(QtWidgets.QWidget):
    def __init__(self, parent):
        super().__init__(parent)
        self.layout = QtWidgets.QVBoxLayout(self)
        self.tabs = QtWidgets.QTabWidget()
        self.tab1 = QtWidgets.QWidget() # 分组选择标签页
        # 移除初始化时的tab2,改为每次筛选时创建
        # self.tab2 = QtWidgets.QWidget() 
        self.tabs.addTab(self.tab1,"Group Select")
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)

        # 示例DataFrame
        self.tab1.df = pd.DataFrame({'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]})
        self.tab1.group = self.tab1.df[["Name"]]
        self.tab1.groupList = self.tab1.group['Name'].tolist()
        self.tab1.listLabel = ["",] * len(self.tab1.groupList)
        self.tab1.grid = QtWidgets.QGridLayout()
        self.tab1.setLayout(self.tab1.grid)

        # 创建复选框
        for i, v in enumerate(self.tab1.groupList):
            self.tab1.groupList[i] = QtWidgets.QCheckBox(v)
            self.tab1.listLabel[i] = QtWidgets.QLabel()
            self.tab1.grid.addWidget(self.tab1.groupList[i], i, 0)

        self.tab1.button = QtWidgets.QPushButton("Select Group")
        self.tab1.button.clicked.connect(self.checkboxChanged)
        self.tab1.labelResult = QtWidgets.QLabel()
        self.tab1.grid.addWidget(self.tab1.button, len(self.tab1.groupList)+1, 0, 1,2)
        self.tab1.setLayout(self.tab1.grid)

    def checkboxChanged(self):
        self.tabs.clear()
        # 关键修改:每次筛选都创建新的tab2
        self.tab2 = QtWidgets.QWidget() 
        self.tabs.addTab(self.tab2,"Loaded Data")

        # 简化筛选逻辑(可选优化,比原逻辑更可靠)
        selected_names = [cb.text() for cb in self.tab1.groupList if cb.isChecked()]
        tab2_df = self.tab1.df[self.tab1.df["Name"].isin(selected_names)]

        # 创建新表格并添加到新tab2的布局
        self.tab2.tableWidget = TableWidget(tab2_df, self)
        self.tab2.tableWidget.setHorizontalHeaderLabels(("Name", "Age"))
        stylesheet3 = "::section{font: bold 18px}"
        self.tab2.tableWidget.horizontalHeader().setStyleSheet(stylesheet3)

        self.tab2.button = QtWidgets.QPushButton("Refresh", self.tab2)
        self.tab2.button.clicked.connect(self.refresh_button)
        self.tab2.layout = QtWidgets.QVBoxLayout()
        self.tab2.layout.addWidget(self.tab2.tableWidget)
        self.tab2.layout.addWidget(self.tab2.button)
        self.tab2.setLayout(self.tab2.layout)

    def refresh_button(self):
        self.tabs.clear()
        # 移除不必要的清空行操作,因为下次筛选会创建全新的表格
        # self.tab2.tableWidget.setRowCount(0)
        self.tabs.addTab(self.tab1,"Group Select")

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

额外优化说明

我还帮你简化了筛选逻辑:直接遍历复选框收集选中的名称,不用通过Label文本判断,这样代码更简洁也更可靠。

现在你每次点击"Select Group"都会生成一个全新的标签页,里面的表格也是最新的,刷新后再筛选就能正常显示数据了!

内容的提问来源于stack exchange,提问作者undeadsmarties

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 13:38:13