PyQt5在类外处理QTableView内嵌按钮点击事件坐标异常如何解决
问题解答
根因分析
你调用button.pos()获取到的是QPushButton相对于其直接父控件(也就是EditButtonsWidget容器)的坐标,而非相对于QTableWidget的坐标。而indexAt()方法要求传入的是相对于表格控件视口的坐标,因此你拿到的坐标始终在(0,0)附近,无法匹配到正确的单元格。
修复方案
这里提供两种常用的可行修复方式:
方案1:坐标映射适配
直接对按钮坐标做坐标系转换,适配indexAt的参数要求,该方案适合表格支持排序、动态增删行的场景,不会出现行号错位问题,修改handleButtonClicked方法即可:
def handleButtonClicked(self): button = self.sender() # 转换坐标:按钮局部坐标 -> 全局屏幕坐标 -> 表格视口局部坐标 btn_global_pos = button.mapToGlobal(QtCore.QPoint(0, 0)) pos_in_table = self.table.viewport().mapFromGlobal(btn_global_pos) index = self.table.indexAt(pos_in_table) if index.isValid(): print(index.row(), index.column())
方案2:绑定信号时直接传行号
在绑定点击事件时直接把当前行作为参数传入,逻辑更简单直观,适合表格行固定、无排序/动态增删的场景:
首先导入partial工具:
from functools import partial
修改循环内的信号绑定逻辑:
for index in range(4): # ... 原有生成单元格的逻辑不变 self.btn_sell = EditButtonsWidget() # 绑定信号时传入当前行号 self.btn_sell.editButton.clicked.connect(partial(self.handleButtonClicked, index)) self.table.setCellWidget(index,2,self.btn_sell)
修改槽函数接收行号参数:
def handleButtonClicked(self, row): # 直接使用row参数即可执行编辑、删除操作 print(row, 2)
内容的提问来源于stack exchange,提问作者DrankRockNein
相关产品推荐
相关产品推荐

