M
M
MechanicZelenyy2020-05-22 12:09:41
Python
MechanicZelenyy, 2020-05-22 12:09:41

How to call context menu in PyQt5?

I want to call the context menu for the TreeView element. I wrote the following test code:

import sys

from PyQt5 import QtCore
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5.QtWidgets import QTreeView, QMenu, QAction, QApplication


class TreeView(QTreeView):
    def __init__(self):
        super().__init__()
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.menu = self.create_menu()
        self.customContextMenuRequested.connect(self.open_menu)

    def create_menu(self) -> QMenu:
        menu = QMenu() # Передавать self пробовал, не помогает.
        menu.addAction(QAction("Action 1"))
        menu.addAction(QAction("Action 2"))
        return menu

    def open_menu(self, position) -> QMenu:
        print(position)
        print("Open menu")
        action = self.menu.exec(self.viewport().mapToGlobal(position))
        print(action)
        # Так тоже пробовал
        # self.menu.popup(self.viewport().mapToGlobal(position))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    model = QStandardItemModel()
    for i in range(2):
        item = QStandardItem("Item {}".format(i))
        for j in range(2):
            item.appendRow(QStandardItem("Sub item {}".format(j)))
        model.appendRow(item)
    window = TreeView()
    window.setModel(model)
    window.show()
    sys.exit(app.exec_())


When you right-click on an element in the tree, something like this is displayed in the console:
PyQt5.QtCore.QPoint(62, 23)
Open menu

but the menu itself is not displayed. Moreover, if you click the left button, the menu will close and return None to the action variable. What is missing to display the menu?
OS: Linux green-deb 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64 GNU/Linux
Python: 3.7.6
PyQt: 5.9.2

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
MechanicZelenyy, 2020-05-22
@MechanicZelenyy

If you look in the documentation of the addAction method, then the possible method signatures are indicated there:

def addAction(self, *__args): # real signature unknown; restored from __doc__ with multiple overloads
        """
        addAction(self, QAction)
        addAction(self, str) -> QAction
        addAction(self, QIcon, str) -> QAction
        addAction(self, str, PYQT_SLOT, shortcut: Union[QKeySequence, QKeySequence.StandardKey, str, int] = 0) -> QAction
        addAction(self, QIcon, str, PYQT_SLOT, shortcut: Union[QKeySequence, QKeySequence.StandardKey, str, int] = 0) -> QAction
        """
        return QAction

If you do menu.addAction("Action"), then everything will work.
At the same time, when I created a menu bar for the program, the method similar to my code worked (perhaps there are other settings for the QMenu instance).
UPD: I found an error, the problem was in creating QAction instances, when creating, you need to pass a value for parent

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question