添加新行后如何刷新QTableWidget的显示?
QTableWidget添加数据后界面不更新的解决方法
向QTableWidget添加新行后,数据已成功写入文件,但界面完全没变化。尝试调用显示函数更新无效,不确定是否需要重新将Widget添加到标签页布局,求解决。
构造函数代码
def __init__(self, parent=None): super(MainUI, self).__init__(parent) # “支出”标签 self.tabDepense = QWidget() # “预算”标签 self.tabBudgets = QWidget() # “收支平衡”标签 self.tabBilan = QWidget() self.data = Data() self.budgets = Budget() self.dicoBudgets = [] self.budgetsTab = QTableWidget() self.addTab(self.tabDepense, "Dépenses") self.addTab(self.tabBudgets, "Budgets") self.addTab(self.tabBilan, "Bilan") # 显示标签页 self.ongletDepense() self.ongletBudgets() self.bilanTab() # 窗口参数设置 self.setWindowTitle("Gestionnaire de dépense") self.setFixedSize(QSize(1350, 750))
预算标签页代码
def ongletBudgets(self): print("ONGLET **BUDGET**") # 创建不同布局 layout = QVBoxLayout() # 加载目录中的文件 choixMois = QComboBox() # 获取月份 # 不调用loadFile(),否则会产生重复数据 listMois = self.data.getMois() # 将月份添加到选择月份的ComboBox中 for i in range(len(listMois)): choixMois.addItem(listMois[i]) self.remplirDico() if(len(self.dicoBudgets) == 0): # 创建空表格 situationBudgetsTab = QTableWidget(len(self.dicoBudgets), 2, self) situationBudgetsTab.setHorizontalHeaderLabels(['Nom Budget', 'Situation Budget']) else: # 创建代表支出与预算对比情况的表格 situationBudgetsTab = QTableWidget(len(self.dicoBudgets), 2, self) # 设置列 situationBudgetsTab.setHorizontalHeaderLabels(['Nom Budget', 'Situation Budget']) # 将值填入表格 for j in range(situationBudgetsTab.rowCount()-1): nom = QTableWidgetItem(self.dicoBudgets[j][0]) # 将值填入当前位置 situationBudgetsTab.setItem(j, 0, nom) s = str(self.dicoBudgets[j][1]) # 查看当前已使用金额与预算上限的差距 situation = QTableWidgetItem("0" + "/" + s[:-1]) # 将值填入当前位置 situationBudgetsTab.setItem(j, 1, situation) j = situationBudgetsTab.rowCount()-1 # 手动添加最后一个元素(无换行符需要删除) nom = QTableWidgetItem(self.dicoBudgets[j][0]) situationBudgetsTab.setItem(j, 0, nom) situation = QTableWidgetItem("0" + "/" + str(self.dicoBudgets[j][1])) situationBudgetsTab.setItem(j, 1, situation) # 添加预算的表单 dateLabel = QLabel("Nom") lineEdit1 = QLineEdit() montantLabel = QLabel("MontantMax") lineEdit2 = QLineEdit() addButton = QPushButton("Ajouter", self) addButton.setCheckable(True) addButton.clicked.connect(lambda: self.majBudget(lineEdit1.text(), lineEdit2.text())) # 将Widget添加到主布局 layout.addWidget(choixMois) layout.addWidget(self.printBudgetsTab()) layout.addWidget(situationBudgetsTab) layout.addWidget(dateLabel) layout.addWidget(lineEdit1) layout.addWidget(montantLabel) layout.addWidget(lineEdit2) layout.addWidget(addButton) # 显示该布局 self.tabBudgets.setLayout(layout)
更新方法代码
def majBudget(self, nomBudget: QLineEdit, montantMax: QLineEdit): # 将预算添加到Budget.txt文件 self.budgets.addBudgetInFile(nomBudget, montantMax) self.clearDico() # 更新显示 self.printBudgetsTab()
表格显示方法代码
def printBudgetsTab(self): # 用文件中的值重新填充字典 self.remplirDico() # 如果字典为空,仅创建空表格 if(not self.dicoBudgets): # 创建空表格 budgetsTab = QTableWidget(len(self.dicoBudgets), 2, self) # 添加列 budgetsTab.setHorizontalHeaderLabels(['Nom Budget', 'Montant Budget']) # 否则将字典中的值填入表格 else: # 创建预算表格 budgetsTab = QTableWidget(len(self.dicoBudgets), 2, self) # 添加列 budgetsTab.setHorizontalHeaderLabels(['Nom Budget', 'Montant Budget']) # 将值填入预算表格 for i in range(len(self.dicoBudgets)): print(self.dicoBudgets) nom = QTableWidgetItem(self.dicoBudgets[i][0]) budgetsTab.setItem(i, 0, nom) s = str(self.dicoBudgets[i][1]) montantMax = QTableWidgetItem(s[:-1]) budgetsTab.setItem(i, 1, montantMax) i = budgetsTab.rowCount()-1 # 手动添加最后一个元素(无换行符需要删除) nom = QTableWidgetItem(self.dicoBudgets[i][0]) budgetsTab.setItem(i, 0, nom) montantMax = QTableWidgetItem(str(self.dicoBudgets[i][1])) budgetsTab.setItem(i, 1, montantMax) return budgetsTab
问题原因与修复方案
核心问题
每次调用printBudgetsTab()都会新建一个QTableWidget实例,但这个新实例并没有替换布局里原来的表格,只是返回后就没有后续处理,界面上显示的始终是第一次创建的旧表格,所以数据更新后界面毫无变化。另外初始化时定义的self.budgetsTab成员变量完全没用到,属于冗余定义。
修复步骤
- 复用已有的表格实例,不要每次新建。修改
printBudgetsTab为更新现有表格,而不是返回新表格。 - 调整布局添加的表格对象,直接使用
self.budgetsTab而不是调用printBudgetsTab()的返回值。 - 更新表格后触发界面刷新。
修改后的代码:
初始化时配置表格
在__init__里初始化self.budgetsTab的基础设置:
def __init__(self, parent=None): super(MainUI, self).__init__(parent) # ... 其他代码保持不变 ... self.budgetsTab = QTableWidget() self.budgetsTab.setColumnCount(2) self.budgetsTab.setHorizontalHeaderLabels(['Nom Budget', 'Montant Budget']) # ... 其他代码保持不变 ...
修改printBudgetsTab为更新现有表格
def printBudgetsTab(self): # 用文件中的值重新填充字典 self.remplirDico() # 清空现有表格内容 self.budgetsTab.setRowCount(0) # 填充新数据 for budget in self.dicoBudgets: row = self.budgetsTab.rowCount() self.budgetsTab.insertRow(row) # 处理预算名称 nom_item = QTableWidgetItem(budget[0]) self.budgetsTab.setItem(row, 0, nom_item) # 处理预算金额(统一处理换行符问题) montant_str = str(budget[1]).rstrip('\n') # 移除末尾换行符 montant_item = QTableWidgetItem(montant_str) self.budgetsTab.setItem(row, 1, montant_item) # 刷新表格显示 self.budgetsTab.viewport().update()
修改ongletBudgets中的布局添加代码
把layout.addWidget(self.printBudgetsTab())改成:
# 先更新表格内容 self.printBudgetsTab() # 添加已有的表格实例到布局 layout.addWidget(self.budgetsTab)
修改majBudget方法
def majBudget(self, nomBudget, montantMax): # 将预算添加到Budget.txt文件 self.budgets.addBudgetInFile(nomBudget, montantMax) self.clearDico() # 更新表格内容并刷新界面 self.printBudgetsTab()
额外优化
- 移除
printBudgetsTab中重复的表格创建逻辑,直接操作self.budgetsTab更高效。 - 用
rstrip('\n')统一处理金额字符串的换行符,避免手动处理最后一行的冗余代码。 - 调用
viewport().update()确保表格界面强制刷新。
内容的提问来源于stack exchange,提问作者goujon
相关产品推荐
相关产品推荐

