Шаг 275.
Библиотека PyQt5.
Создание SDI- и MDI-приложений. Меню. Контекстное меню компонента

    На этом шаге мы рассмотрим создание контекстного меню.

    Чтобы создать для компонента контекстное меню, также можно воспользоваться соответствующими методами класса QWidget. Вот они:

    Необходимо также наследовать класс компонента и переопределить метод с названием contextMenuEvent(self, <event>). Этот метод будет автоматически вызываться при щелчке правой кнопкой мыши в области компонента. Внутри метода через параметр <event> доступен экземпляр класса QContextMenuEvent, который позволяет получить дополнительную информацию о событии. Класс QContextMenuEvent поддерживает следующие основные методы:

    Чтобы вывести собственно контекстное меню, внутри метода contextMenuEvent() следует вызвать метод exec() (или ехес_()) объекта меню и передать ему результат выполнения метода globalPos(). Пример:

def contextMenuEvent(self, event):
    self.context_menu.exec_(event.globalPos())

    В этом примере меню создано внутри конструктора класса и сохранено в атрибуте context_menu. Если контекстное меню постоянно обновляется, его можно создавать при каждом вызове внутри метода contextMenuEvent() непосредственно перед выводом.

    В заключение приведем небольшой пример, иллюстрирующий использование меню (основа для примера взята отсюда: https://dev-gang.ru/article/python-i-pyqt-sozdanie-menu-panelei-instrumentov-i-strok-sostojanija-l7ubf6mm7n/):

# -*- coding: utf-8 -*-
import sys
from PyQt5.QtCore import Qt
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QLabel, QAction, QMainWindow, QMenu


class Window(QMainWindow):

    def __init__(self, parent=None):
        """Initializer."""
        super().__init__(parent)
        self.setWindowTitle("Python PopupMenu")
        self.resize(400, 200)
        self.centralWidget = QLabel("Hello, World")
        self.centralWidget.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        self.setCentralWidget(self.centralWidget)

    def contextMenuEvent(self, event):
        # Creating a menu object with the central widget as parent
        menu = QMenu(self.centralWidget)
        # Populating the menu with actions
        exAction = QAction('Пункт 1', self)
        exAction.triggered.connect(self.popupMenu1)
        
        menu.addAction(exAction)
        menu.addAction('Пункт 2')
        menu.addAction('Пункт 3')
        menu.addAction('Пункт 4')
        menu.addAction('Пункт 5')
        menu.addAction('Пункт 6')
        # Launching the menu
        menu.exec(event.globalPos())

    def popupMenu1(self):
        QtWidgets.QMessageBox.information(None, "Сообщение", "Выбран пункт 1", 
            QtWidgets.QMessageBox.Close)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Window()
    win.show()
    sys.exit(app.exec_())
Архив с файлом можно взять здесь.

    Результат работы приложения показан на рисунках 1 и 2.


Рис.1. Результат работы приложения (контекстно-зависимое меню)


Рис.2. Результат работы приложения (реакция на выбор первого пункта)

    Немного прокомментируем приведенный пример.

    Метод __init__() содержит начальные настройки приложения и дополнительно компонент centralWidget(), представляющий собой виджет QLabel(), для которого будем создавать контекстно-зависимое меню.

    Метод contextMenuEvent() содержит создание пунктов меню, причем тольео первый пункт является активным. Для него создан объект exAction класса QAction(). В нем прописано название пункта меню и указана функция-обработчик, которая будет вызываться в ответ на выбор этого пункта.

    Метод popupMenu1() - это реакция на выбор первого пункта меню.

    На следующем шаге мы рассмотрим класс QAction.




Предыдущий шаг Содержание Следующий шаг