获取知道其元素的 QTableWidget 行的索引
Posted
技术标签:
【中文标题】获取知道其元素的 QTableWidget 行的索引【英文标题】:Get the index of a QTableWidget row knowing its elements 【发布时间】:2015-04-14 17:03:30 【问题描述】:[我使用的是 PyQt4,但我认为这个 Qt4 问题不是 Python 特有的。]
我有一个QTableWidget
。在每一行中,第一列包含一个按钮。单击时,该行将被删除。
要删除行,我使用removeRow(int row)
方法,该方法将行的索引作为参数。连接信号时,我不知道行的索引,因为它可能同时发生变化(例如,如果第一行被删除,所有行索引都会改变)。
The accepted answer here 建议在回调中传递一个 QTableWidgetItem 的实例,然后在删除时从该项目中获取行号。
这很好,除了该行的所有元素都不是QTableWidgetItem
。元素是按钮本身和一些 ComboBox。
我想不出办法。
我能否以某种方式将我的元素之一放入 QTableWidgetItem?我应该在某种隐藏列中添加 QTableWidgetItem 吗?
我们当前的实现使用indexAt(QtGui.qApp.focusWidget())
(请参阅上述问题的其他答案),这对我来说似乎是一个抱歉的解决方法。
如果我用这样的可检查 QTableWidgetItem 替换按钮
rm_item = QtGui.QTableWidgetItem()
rm_item.setFlags(QtCore.Qt.ItemIsUserCheckable |
QtCore.Qt.ItemIsEnabled)
我有一个 QTableWidgetItem 可以用来返回行索引。但是我不知道如何像使用按钮一样从中捕获“已检查”或“单击”事件。我发现的只是QTableWidget
的itemClicked
信号,但是我必须过滤掉所有其他小部件。
肯定有一些明显的我遗漏了。
编辑
根据我阅读的here,我可以将带有 setItem 的 QTableWidgetItem 和带有 setCellWidget 的 Button 小部件添加到同一个单元格。这对我来说似乎不太自然,但显然它有效(现在无法测试)。
我想我会这样做的。添加 Button,并在同一单元格上添加一个虚拟 QTableWidgetItem 作为对行的引用。
这就是它的本意吗?
编辑 2
或者QTableWidget
不是正确的小部件,我应该使用Layout
,正如here 建议的那样。
【问题讨论】:
这不是 python 答案,但我认为我的 C++ 答案 here 可能会有所帮助。 【参考方案1】:似乎使用布局而不是表格可能是最“正确”的答案,但这可能伴随着它自己的困难,正如我对这个问题的回答所示:
How to delete widgets from gridLayout如果您想继续使用表格,比添加虚拟项目更清洁的解决方案是使用persistent model index:
button = QtGui.QPushButton(text, self.table)
self.table.setCellWidget(row, column, button)
index = QtCore.QPersistentModelIndex(
self.table.model().index(row, column))
button.clicked.connect(
lambda *args, index=index: self.handleButton(index))
def handleButton(self, index):
print('button clicked:', index.row())
if index.isValid():
self.table.removeRow(index.row())
【讨论】:
再次感谢@ekhumoro。工作一种享受。我刚用button.clicked.connect(lambda: self.handleButton(index))
【参考方案2】:
如果我正确理解您的问题:
def set_button(self, row, col):
# create a push button
btn = QtGui.QPushButton('Remove row')
# connect to action
btn.clicked.connect(self.remove_row)
# set in cell
self.setCellWidget(row, col, btn)
def remove_row(self):
# find what is clicked
clicked = QtGui.qApp.focusWidget()
# position
idx = self.indexAt(clicked.pos())
# remove this row
self.removeRow(idx.row())
【讨论】:
这是我们已经做的,但我觉得在这里使用光标位置很奇怪。当连接信号时,我们知道行元素,所以故意丢失这些信息然后再寻找光标位置有点扭曲。此外,如果从键盘单击按钮,该方法将失败(参见accepted answer here)。 对不起,我误读了这个问题。 AFAIK 你是对的:table.itemclicked
你必须检查复选框的状态。我暂时没有找到其他方法。注意:键盘与按钮的交互对我来说工作正常。
我想如果您从键盘单击并且鼠标指针位于另一行,indexAt(QtGui.qApp.focusWidget())
将返回另一行的索引。无论如何,请参阅我对问题所做的编辑。我认为我有一个可以接受的解决方法(在同一个单元格中同时使用 QTableWidgetItem 和 setCellItem),答案是我不应该首先使用 QTableWidget,而是使用 QLayout。以上是关于获取知道其元素的 QTableWidget 行的索引的主要内容,如果未能解决你的问题,请参考以下文章