PyQt5:从 QTableView 索引小部件中的按钮菜单操作获取行号

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

基本上,我有一个 QTableView,每行的最后一列包含一个 QMenu,如果触发,则应删除该行。我尝试了下面的代码,但是如果我单击行号 > 1 中的菜单,返回的 rowNum 是 -1:

代码:

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)

我只需要知道 deleteRow 内部的发件人是哪个行号,然后我可以使用 model.removeRow() 删除它。

您的代码无法按预期工作的主要原因是您将菜单设置为操作的父项。菜单是一个弹出窗口 window,因此它的位置将在全局坐标中,而您需要相对于 table 的位置。实现此目的的一种简单方法是让按钮成为操作的父级。

您的代码的以下修订应该符合您的要求:

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