PyQt5 QTableWidget右键单元格不会生成QMenu

4

我的程序有一个表格,希望可以右键单击表格中的单元格并生成适当的操作来操作该单元格(不同单元格有不同的操作)。我的测试代码只是创建了一个小部件,生成一个表格,并在视口上安装了一个事件过滤器来确定右键单击的单元格。

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QAction, QMenu, QTableWidget, QTableWidgetItem, QVBoxLayout
from PyQt5 import QtCore


class TestRightClickTableWidget(QWidget):

    def __init__(self):
        super().__init__()

        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(4)
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setItem(0, 0, QTableWidgetItem("Cell 1"))
        self.tableWidget.setItem(0, 1, QTableWidgetItem("Cell 2"))
        self.tableWidget.setItem(1, 0, QTableWidgetItem("Cell 3"))
        self.tableWidget.setItem(1, 1, QTableWidgetItem("Cell 4"))
        self.tableWidget.setItem(2, 0, QTableWidgetItem("Cell 5"))
        self.tableWidget.setItem(2, 1, QTableWidgetItem("Cell 6"))
        self.tableWidget.setItem(3, 0, QTableWidgetItem("Cell 7"))
        self.tableWidget.setItem(3, 1, QTableWidgetItem("Cell 8"))

        self.tableWidget.viewport().installEventFilter(self)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.tableWidget)
        self.setLayout(self.layout)

    def eventFilter(self, source, event):
        if(event.type() == QtCore.QEvent.MouseButtonPress and
           event.buttons() == QtCore.Qt.RightButton and
           source is self.tableWidget.viewport()):
            item = self.tableWidget.itemAt(event.pos())
            print('Global Pos:', event.globalPos())
            if item is not None:
                print('Table Item:', item.row(), item.column())
                menu = QMenu(self)
                menu.addAction(QAction('test'))
                menu.exec_(event.globalPos())
        return super(TestRightClickTableWidget, self).eventFilter(source, event)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = TestRightClickTableWidget()
    ex.show()
    sys.exit(app.exec_())

我需要找到正确的单元格以及在菜单上运行exec_的全局位置。但是菜单没有出现在屏幕上。我想知道这是Qt错误,其中菜单不会在表格中生成,还是我没有正确创建/执行菜单。感谢任何帮助。谢谢。

1个回答

7

试一试:

import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QAction, QMenu, QTableWidget, 
                             QMainWindow, QTableWidgetItem, QVBoxLayout, )
from PyQt5 import QtCore


class TestRightClickTableWidget(QWidget): #(QMainWindow):   # (QWidget): #

    def __init__(self):
        super().__init__()

        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(4)
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setItem(0, 0, QTableWidgetItem("Cell 1"))
        self.tableWidget.setItem(0, 1, QTableWidgetItem("Cell 2"))
        self.tableWidget.setItem(1, 0, QTableWidgetItem("Cell 3"))
        self.tableWidget.setItem(1, 1, QTableWidgetItem("Cell 4"))
        self.tableWidget.setItem(2, 0, QTableWidgetItem("Cell 5"))
        self.tableWidget.setItem(2, 1, QTableWidgetItem("Cell 6"))
        self.tableWidget.setItem(3, 0, QTableWidgetItem("Cell 7"))
        self.tableWidget.setItem(3, 1, QTableWidgetItem("Cell 8"))
        
        ### This property holds how the widget shows a context menu
        self.tableWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)     # +++
        ### This signal is emitted when the widget's contextMenuPolicy is Qt::CustomContextMenu, 
        ### and the user has requested a context menu on the widget. 
        self.tableWidget.customContextMenuRequested.connect(self.generateMenu) # +++

        self.tableWidget.viewport().installEventFilter(self)

        self.layout = QVBoxLayout() 
        self.layout.addWidget(self.tableWidget)
        self.setLayout(self.layout)

    def eventFilter(self, source, event):
        if(event.type() == QtCore.QEvent.MouseButtonPress and
           event.buttons() == QtCore.Qt.RightButton and
           source is self.tableWidget.viewport()):
            item = self.tableWidget.itemAt(event.pos())
            print('Global Pos:', event.globalPos())
            if item is not None:
                print('Table Item:', item.row(), item.column())
                self.menu = QMenu(self)
                self.menu.addAction(item.text())         #(QAction('test'))
                #menu.exec_(event.globalPos())
        return super(TestRightClickTableWidget, self).eventFilter(source, event)

    ### +++    
    def generateMenu(self, pos):
        print("pos======",pos)
        self.menu.exec_(self.tableWidget.mapToGlobal(pos))   # +++

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = TestRightClickTableWidget()
    ex.show()
    sys.exit(app.exec_())

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接