Задать вопрос
@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
  • Вопрос задан
  • 1245 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 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
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы
Greenway Global Новосибирск
от 150 000 ₽
SPA2099 Москва
До 100 000 ₽
HR Prime Москва
от 300 000 до 3 800 000 ₽