需求
需要在tableWidget里的cellWidget(例如下图的QComboBox和QCheckBox)的操作做出响应,该响应将作用于其他cellWidget
在这之前,本想通过QTableWidget的信号来实现,但是测试了一通,cellWidget不能发送下列信号,无法实现上面的需求。
解决方案
- 在使用
setCellWIdget
添加匿名控件时,使用.connect()
把匿名控件对象连接到对应的槽函数; - 由于添加cellWidget时,控件是匿名对象,为了方便后续再次识别和操作,使用字典作为注册,把对象和行索引绑定;
- 在槽函数里使用
self.sender()
,获取发送此信号从而触发此槽函数的控件对象,再通过注册字典获取控件所在行,再由行数的注册字典获取该行上的其他控件对象进行操作。
代码示例
- 创建匿名控件注册字典
self.cellWidgetRegistry1: Typing.Dict[QComboBox, int] = dict()
self.cellWidgetRegistry2: Typing.Dict[int, QCheckBox] = dict()
- 添加cellWidget控件,并连接槽函数,并注册匿名控件对象
def update_tableWidget(self):
for row in range(12):
cbb = QComboBox() # 创建匿名控件对象
cbb.addItems(["1", "2", "3"])
self.tableWIdget.setCellWidget(row, 1, cbb) # 添加cellWidge
cbb.currentIndexChanged.connect(self.on_cbb_currentIndexChanged) # 匿名控件连接槽函数
self.cellWidgetRegistry1[cbb] = row # 注册到字典 绑定对象和行
ckb = QCheckBox()
self.tableWIdget.setCellWidget(row, 2, ckb) # 添加cellWidge
self.cellWidgetRegistry2[row] = ckb # 注册到字典 绑定行和对象
- 槽函数获取信号发送者
@QtCore.pyqtSlot(int)
def on_cbb_currentIndexChanged(self, idx):
cbb = self.sender() # 获取此信号的发送者(控件对象)
row = self.cellWidgetRegistry1.get(cbb, 0)
# 通过行号和另一个注册字典 反向查找该行的其他控件
cbb2 = self.cellWidgetRegistry2.get(row, QCheckBox)
...
参考
【1】 pyqt 信号槽 判断信号发出者(sender)
【2】QTableWidget中关于cellWidget的信号的处理方式
其他方案
可以尝试使用setItemDelegate
代理,