Get the index of a QTableWidget row knowing its elements

我的梦境 提交于 2019-12-24 14:28:37

问题


[I'm using PyQt4, but I think this Qt4 issue is not Python specific.]

I have a QTableWidget. In each row, the first column holds a button. When clicked, the row is removed.

To remove the row, I use removeRow(int row) method, which takes as argument the index of the row. When connecting the signal, I can't know the index of the row because it might change in the meantime (for instance if the first row is removed, all row indexes are changed).

The accepted answer here suggests to pass the callback an instance of a QTableWidgetItem in the line, then get the row number from this item at deletion time.

This would be nice, except none of the elements of the row is a QTableWidgetItem. The elements are the button itself and a few ComboBoxes.

I can't figure out a way around this.

Can I somehow fit one of my elements into a QTableWidgetItem? Should I add a QTableWidgetItem in some sort of hidden column?

Our current implementation uses indexAt(QtGui.qApp.focusWidget()) (see other answer to question mentioned above), which looks like a sorry workaround to me.

If I replace the button with a checkable QTableWidgetItem like this

rm_item = QtGui.QTableWidgetItem()
rm_item.setFlags(QtCore.Qt.ItemIsUserCheckable |
                 QtCore.Qt.ItemIsEnabled)

I have a QTableWidgetItem I can use to get back to the row index. But I don't know how to catch a "checked" or "clicked" event from it like I do with the button. All I found is the itemClicked signal of QTableWidget, but then I'd have to filter all the other widgets out.

There has to be something obvious I'm missing.

Edit

From what I read here, I could add both a QTableWidgetItem with setItem and a Button widget with setCellWidget to the same cell. This doesn't seem so natural to me, but apparently it works (can't test right now).

I guess I'll do that. Add the Button, plus a dummy QTableWidgetItem on the same cell to pass as a reference to the row.

Is this how it is meant to be?

Edit 2

Or maybe QTableWidget is not the proper Widget and I should be using a Layout, as suggested here.


回答1:


It seems that using a layout rather than a table is possibly the most "correct" answer, but that may come with it's own difficulties, as seen in my answer to this question:

  • How to delete widgets from gridLayout

If you want to continue using a table, a somewhat cleaner solution than adding dummy items would be to use a 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())



回答2:


If I understand your question correctly:

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())


来源:https://stackoverflow.com/questions/29633311/get-the-index-of-a-qtablewidget-row-knowing-its-elements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!