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

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标准的模态弹窗+关闭后回调的逻辑实现,稳定性更高:

  1. 打开articoli弹窗时用exec_()模态启动,弹窗关闭后父窗口代码会继续往下执行,直接触发重量列刷新即可,不需要全表重载,响应速度更快
  2. 把所有信号绑定、下拉框初始化的逻辑移到modificaviaggi的__init__方法里,仅执行1次,避免重复绑定
  3. 点击单元格时记录当前选中的行号、列号,补全下拉框选择方法需要的变量
  4. 返回按钮点击时先执行重量数据保存逻辑,再关闭弹窗
修正后的关键代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:54:31