PyQt中关闭子弹窗后重载QDialog内QTableWidget数据的方法
问题原因
你的代码有3个核心问题导致表格不刷新,附带2个会触发报错的隐藏bug:
- 逻辑时序错误:
reloading()方法仅在modificaviaggi窗口初始化时执行1次,articoli弹窗关闭时没有任何代码主动触发父窗口的表格刷新逻辑,仅修改类变量recall的值不会自动执行任何方法 - 语法错误:
reloading()方法内写的self.recall[0] == 2是比较运算(双等号),不是赋值运算,就算触发了也没法把状态改回初始值 - 冗余逻辑问题:你把信号绑定、下拉框创建的逻辑写在了
datitabella()和pressed()方法里,每次刷新表格、点击单元格都会重复绑定信号,运行时间长了会出现一次操作触发多次函数的问题 - 隐藏bug1:
customer_combo_selection()方法里使用了未定义的self.rrow、self.ccolumn变量,点击客户下拉框会直接抛出属性错误 - 隐藏bug2:
articoli弹窗的返回按钮点击后仅关闭窗口,没有调用insert()方法保存用户录入的重量数据,用户填的内容根本不会写入数据库
修复方案
不用靠类变量传状态做刷新,直接用Qt标准的模态弹窗+关闭后回调的逻辑实现,稳定性更高:
- 打开
articoli弹窗时用exec_()模态启动,弹窗关闭后父窗口代码会继续往下执行,直接触发重量列刷新即可,不需要全表重载,响应速度更快 - 把所有信号绑定、下拉框初始化的逻辑移到
modificaviaggi的__init__方法里,仅执行1次,避免重复绑定 - 点击单元格时记录当前选中的行号、列号,补全下拉框选择方法需要的变量
- 返回按钮点击时先执行重量数据保存逻辑,再关闭弹窗
修正后的关键代码
modificaviaggi类调整
class modificaviaggi(QtWidgets.QDialog): lastid = [0] def finestraarticoli(self): self.finestraarticoli = articoli() # 模态打开弹窗,阻塞直到用户关闭弹窗 self.finestraarticoli.exec_() # 弹窗关闭后直接刷新重量列,不需要全表重载 self.refresh_peso_colonna() def chiusura(self): self.accept() def __init__(self): super(modificaviaggi, self).__init__() uic.loadUi('modifica_reg.ui', self) bottonetorna = self.bottone_torna bottonetorna.clicked.connect(self.chiusura) # 所有信号绑定、控件初始化仅在窗口启动时执行1次 self.combo_customers = QComboBox() self.combo_customers.setEditable(True) delegate = MyDelegate(self) self.tabella_registrazioni.setItemDelegateForColumn(0, delegate) self.tabella_registrazioni.itemChanged.connect(self.changeIcon) self.tabella_registrazioni.clicked.connect(self.pressed) self.combo_customers.activated.connect(self.customer_combo_selection) # 首次加载全表数据 self.datitabella() def refresh_peso_colonna(self): """单独刷新重量列,比全表重载效率更高""" self.tabella_registrazioni.blockSignals(True) righe = self.tabella_registrazioni.rowCount() for i in range(righe): idrow = self.tabella_registrazioni.item(i, 0).text() # 用ISNULL处理无重量数据的情况,避免None转浮点报错 netweight = float(c.execute("SELECT ISNULL(SUM(Peso_netto),0) FROM Pesi WHERE ID_registrazione = ?", idrow).fetchone()[0]) grossweight = float(c.execute("SELECT ISNULL(SUM(Peso_lordo),0) FROM Pesi WHERE ID_registrazione = ?", idrow).fetchone()[0]) self.tabella_registrazioni.setItem(i, 8, QtWidgets.QTableWidgetItem(str(netweight))) self.tabella_registrazioni.setItem(i, 9, QtWidgets.QTableWidgetItem(str(grossweight))) self.tabella_registrazioni.blockSignals(False) def datitabella(self): tablerow = 0 conteggio = c.execute('SELECT COUNT(ID) FROM Viaggi').fetchone()[0] customers = [" "] self.tabella_registrazioni.blockSignals(True) self.customers_combo(customers) self.tabella_registrazioni.setRowCount(conteggio) for row in c.execute("SELECT * FROM Viaggi "): rigavalore = 0 for r in range(19): self.tabella_registrazioni.setItem(tablerow, rigavalore, QtWidgets.QTableWidgetItem(str(row[rigavalore]))) rigavalore+=1 tablerow+=1 # 加载完主表数据后填充重量列 self.refresh_peso_colonna() self.tabella_registrazioni.blockSignals(False) def customers_combo(self, customers): for cu in d.execute("SELECT ANDESCRI FROM VALL_CONTI WHERE ANTIPCON = 'C' "): customers.append(cu[0].strip()) def changeIcon(self, item): row = item.row() col = item.column() zero = self.tabella_registrazioni.item(row, 0).text() custcode = self.tabella_registrazioni.item(row, 3).text() custname = self.tabella_registrazioni.item(row, 4).text() c.execute('UPDATE Viaggi SET Codice_cliente = ?, Ragione_sociale = ? WHERE ID = ?', (custcode, custname, zero)) c.commit() def pressed(self, item): row = item.row() col = item.column() # 记录当前选中行列,给下拉框选择逻辑用 self.rrow = row self.ccolumn = col self.lastid[0] = self.tabella_registrazioni.item(row, 0).text() if col == 8 or col == 9: self.finestraarticoli() customers = [" "] self.customers_combo(customers) # 清空下拉框原有项再加新项,避免重复累积 self.combo_customers.clear() self.combo_customers.addItems(customers) textcell = self.tabella_registrazioni.item(row, col).text() self.combo_customers.setCurrentText(textcell) if col == 3: self.tabella_registrazioni.setCellWidget(row, 3, self.combo_customers) def customer_combo_selection(self): customer_name = self.combo_customers.currentText() self.tabella_registrazioni.setItem(self.rrow, self.ccolumn, QtWidgets.QTableWidgetItem(str(customer_name))) id = self.tabella_registrazioni.item(self.rrow, 0).text() c.execute("UPDATE Viaggi SET Ragione_Sociale=? WHERE ID = ?", (customer_name, id)) c.commit()
articoli类调整
class articoli(QtWidgets.QDialog): def changevariable(self): # 先保存录入的重量数据,再关闭弹窗 self.insert() self.accept() def __init__(self): super(articoli, self).__init__() uic.loadUi('Inserimento_articoli.ui', self) self.get_back_button.clicked.connect(self.changevariable) self.tabellapesi() # tabellapesi、insert方法保持原有逻辑即可,不需要修改recall类变量
内容的提问来源于stack exchange,提问作者IT-SRL
相关产品推荐
相关产品推荐

