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

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

Войти через центр авторизации
Похожие вопросы