@MechanicZelenyy

Как вызвать контекстное меню в PyQt5?

Хочу вызвать контекстное меню для элемента TreeView. Набросал такой тестовый код:
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_())


При клике правой кнопкой по элементу дерева в консоль выводится что-то типа:
PyQt5.QtCore.QPoint(62, 23)
Open menu

но само меню не отображается. Причем если щелкнуть левой кнопкой то меню закроется и в переменную action вернет None. Чего не хватает для отображения меню?
ОС: 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
  • Вопрос задан
  • 111 просмотров
Решения вопроса 1
@MechanicZelenyy Автор вопроса
Если посмотреть в документацию метода addAction, то тамуказаны возможные сигнатры метода:
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


Если сделать menu.addAction("Action"), то все работать будет.

При этом когда я создавал для программы menu bar, то способ аналогичны моему коду работал (возможно там другие настройки у экземпляра QMenu).

UPD: Нашел ошибку, проблема была в создании экземпляров QAction, при создании нужно передать значение для parent
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
OnederX Москва
от 100 000 до 120 000 ₽
от 80 000 до 120 000 ₽
SwapZilla.co Москва
от 200 000 ₽
13 авг. 2020, в 12:26
12000 руб./за проект
13 авг. 2020, в 11:59
20000 руб./за проект
13 авг. 2020, в 11:57
15000 руб./за проект