PySide6表格列调整时断开/连接信号函数出现异常警告
我编写了如下函数,用于在PySide6中调整表格前两列尺寸,同时固定第三列(含下拉框)为90像素,确保窗口缩放时前两列保持比例适配表格可视区域:
def auto_n_manual_resize(self): self.header.setStretchLastSection(False) widget_width = self.wordsTable.contentsRect().width() column0 = self.header.sectionSize(0) column1 = self.header.sectionSize(1) scroll = self.wordsTable.verticalScrollBar().sizeHint().width() verHeadWidth = self.wordsTable.verticalHeader().sizeHint().width() available_width = ( widget_width - verHeadWidth - scroll - 90 ) # the 3rd col should be 90 pix wide denom = column0 + column1 or 1 if denom == 0: column0 = column1 = 1 denom = 2 col0_W_per = column0 / denom col1_W_per = column1 / denom newCol0Width = int(col0_W_per * available_width) newcol1Width = int(col1_W_per * available_width) self.header.sectionResized.disconnect(self.auto_n_manual_resize) self.wordsTable.setColumnWidth(0, newCol0Width) self.wordsTable.setColumnWidth(1, newcol1Width) self.wordsTable.setColumnWidth(2, 90) self.header.sectionResized.connect(self.auto_n_manual_resize) self.header.setMinimumSectionSize(60) self.header.setMaximumSectionSize((available_width)) self.header.setStretchLastSection(True)
该功能运行正常,但程序启动后会出现警告:
RuntimeWarning: Failed to disconnect (<bound method Table.auto_n_manual_resize of <widgets.Table(0x20d074122a0) at 0x0000020D07ADD280>>) from signal "sectionResized(int,int,int)".
此前未添加断开/连接信号的代码时,调整列宽会超出可视区域出现横向滚动条,窗口缩放时才会恢复;添加后功能正常但警告无法消除。
问题根源
程序启动后第一次调用auto_n_manual_resize时,sectionResized信号还未与auto_n_manual_resize函数建立连接,此时执行disconnect操作就会触发未连接的警告。
解决方法
方法1:检查连接状态后再断开
在执行断开操作前,先判断函数是否已连接到信号,避免无意义的断开操作:
# 替换原有的disconnect代码 if self.header.sectionResized.isConnected(self.auto_n_manual_resize): self.header.sectionResized.disconnect(self.auto_n_manual_resize)
方法2:临时阻塞信号(更推荐)
不需要手动断开重连,改用blockSignals临时阻塞表头的信号发射,避免setColumnWidth触发sectionResized信号导致递归调用:
# 替换原有的disconnect/connect代码块 self.header.blockSignals(True) self.wordsTable.setColumnWidth(0, newCol0Width) self.wordsTable.setColumnWidth(1, newcol1Width) self.wordsTable.setColumnWidth(2, 90) self.header.blockSignals(False)
额外优化建议
函数最后一行self.header.setStretchLastSection(True)会强制最后一列(第三列)自动拉伸填充剩余空间,这与你固定第三列90像素的需求冲突,建议删除该行,确保第三列宽度保持固定。
内容的提问来源于stack exchange,提问作者Tar-Eruntalion

