PyQt5: Get row number from button-menu action in QTableView index-widget

405 Views Asked by At

Basically, I have a QTableView and the last column of each row contains a QMenu where if triggered, the row should be deleted. I tried the code below, but if I click on the menu that is in a row number > 1, the returned rowNum is -1:

Code:

def addrowIntable(self, a, b):
    Column1 = QStandardItem("%s" % (a))
    Column2 = QStandardItem("%s" % (b))

    actionBTN = QPushButton("")
    actionMenu = QMenu()

    self.RemList = QtWidgets.QAction("Remove row", actionMenu)
    actionMenu.addAction(self.RemList)

    actionMenu.raise_()
    actionBTN.setMenu(actionMenu)
    self.rulesWhitelistWidgetModel.appendRow([Column1, Column2])
    self.rulesWhiteListFileTBL.setIndexWidget(
        self.rulesWhitelistWidgetModel.index(self.rulesWhitelistWidgetModel.rowCount() - 1,
                                             self.rulesWhiteListFileTBL.model().columnCount() - 1), actionBTN)
    self.RemList.triggered.connect(lambda: self.deleteRow("Hello"))

def deleteRow(self, str):
    rowNum = self.rulesWhiteListFileTBL.rowAt(self.rulesWhiteListFileTBL.viewport().mapFromGlobal(self.sender().parent().pos()).y())
    print(self.rulesWhiteListFileTBL.indexAt(self.sender().parent().pos()).row())
    print(rowNum)

I just need to know which row number was the sender from inside deleteRow where I could then use model.removeRow() to delete it.

1

There are 1 best solutions below

0
ekhumoro On BEST ANSWER

The main reason why your code doesn't work as expected is because you set the menu as the parent of the action. A menu is a popup window, so its position will be in global coordinates, whereas you want the position relative to the table. A simple way to achieve this is to make the button the parent of the action instead.

The following revision of your code should do what you want:

def addrowIntable(self, a, b):
    Column1 = QStandardItem("%s" % (a))
    Column2 = QStandardItem("%s" % (b))
    actionBTN = QPushButton()
    actionMenu = QMenu()
    actionRem = QtWidgets.QAction("Remove row", actionBTN)
    actionMenu.addAction(actionRem)
    actionBTN.setMenu(actionMenu)
    self.rulesWhitelistWidgetModel.appendRow([Column1, Column2])
    self.rulesWhiteListFileTBL.setIndexWidget(Column2.index(), actionBTN)
    actionRem.triggered.connect(lambda: self.deleteRow("Hello"))

def deleteRow(self, str):
    pos = self.sender().parent().pos()
    index = self.rulesWhiteListFileTBL.indexAt(pos)
    self.rulesWhitelistWidgetModel.removeRow(index.row())