在PyQt5中显示QMenu的问题

时间:2019-06-12 14:16:37

标签: python python-3.x pyqt pyqt5

当我在QTableWidget上单击鼠标右键时,我试图显示QMenu。问题在于,只要出现菜单,它就会显示为一个点。在下面,您可以找到一个最小的可复制示例。

import sys

from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import (QApplication, QAction, QMenu, QTableWidget,
                             QAbstractItemView)


class PhotoSetTable(QTableWidget):
    _menu = None

    def __init__(self, parent=None):
        super().__init__(parent)

        self.setRowCount(0)
        self.setColumnCount(2)
        self.setHorizontalHeaderLabels(["Name", "Count"])
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self._menu = self._generate_menu()
        row_position = self.rowCount()
        self.insertRow(row_position)
        name_item = QtWidgets.QTableWidgetItem("asd")
        name_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        count_item = QtWidgets.QTableWidgetItem("0")
        count_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        self.setItem(row_position, 0, name_item)
        self.setItem(row_position, 1, count_item)


        #self._refresh()

    @staticmethod
    def _generate_menu():
        menu = QMenu()
        menu.addAction(QAction("Quit"))
        menu.addSeparator()
        menu.addAction(QAction("WUUU"))
        menu.addSeparator()

        return menu

    def mousePressEvent(self, e):
        super().mousePressEvent(e)
        if e.buttons() == QtCore.Qt.RightButton:
            item = self.itemAt(e.pos())

            if item is not None:
                self._menu.exec(e.globalPos())


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

是什么原因导致这种行为?

2 个答案:

答案 0 :(得分:2)

问题在于将QAction添加到生成的上下文菜单中。相反,请尝试添加菜单项,其中以菜单项名称作为字符串作为第一个参数,然后将其作为第二个参数调用。

@staticmethod
def _generate_menu():
    menu = QMenu()
    menu.addAction("Quit", lambda: print('quitting'))
    menu.addSeparator()
    menu.addAction("WUUU", method_name)
    menu.addSeparator()

    return menu

答案 1 :(得分:0)

之所以只看到一个“点”,是因为您实际上是在创建一个没有父级的QAction,因此实际上看到的是一个空菜单。
QMenu.addAction(QAction*)不会将QAction的所有权转让给菜单(如here所述,它的行为为QWidget.addAction,因为QMenu是QWidget的后代),这意味着一旦{{1} }方法返回时,这些操作将“转移”到Python的垃圾收集器(又名已删除)。

如果出于任何原因,您确实需要创建“独立” QAction,请为其添加父项(或使它们成为某个持久对象的属性,甚至可以通过添加到另一个持久对象(例如列表或元组)) ,或仅使用MalloyDelacroix指出的_generate_menu()
顺便说一句,如果您仅将菜单设置为父菜单,就足够了:

menu.addAction(str)

也就是说,至少根据您的示例,确实不需要为此使用静态方法。