Эта глава постепенно раскрывает что меню — это не набор пунктов, а сценарий взаимодействия. Здесь вы обнаружите, как профессиональные приложения добиваются ощущения «родного» интерфейса, не нарушая платформенные правила. Вы узнаете секреты, которые позволяют сократить путь пользователя к действию и одновременно упростить поддержку кода.
Будут разобраны несколько типов меню, показаны практические приемы работы с QMenu и QMenuBar, а также логика использования мнемоник и «горячих» клавиш. На реальных примерах демонстрируется, как грамотная структура меню снижает когнитивную нагрузку и повышает ощущение профессионального качества интерфейса.
Пропуск этой главы — риск остаться на уровне «работает, но неудобно». А такие детали пользователи замечают быстрее всего.
В этой главе вы найдёте готовые к использованию примеры кода.
Самопроверка по главе
В чём принципиальная разница между «горячими» клавишами и мнемониками (клавишами быстрого вызова)?Ответ
Правильный ответ: Горячие клавиши — это глобальные комбинации (например, Ctrl+S), работающие в любом месте приложения, а мнемоники — контекстные комбинации Alt+буква, требующие предварительного открытия нужного меню.
Почему команды меню верхнего уровня не следует использовать для непосредственного выполнения действий?Ответ
Правильный ответ: Команды верхнего уровня предназначены исключительно для отображения выпадающих меню; использование их для других целей нарушает привычные паттерны интерфейса и озадачивает пользователей.
Что произойдёт с символом & перед буквой в названии команды меню на платформе macOS?Ответ
Правильный ответ: Символ & будет просто удалён из текста, так как macOS не поддерживает мнемоники по дизайну платформы; подчёркивания в пунктах меню не отображаются, а навигация по Alt+буква не работает.
Какую роль играет класс QAction в системе меню Qt?Ответ
Правильный ответ: QAction представляет отдельную команду (действие) в меню, инкапсулируя её свойства (текст, иконку, горячие клавиши, состояние) и может быть переиспользован в разных местах интерфейса (меню, панели инструментов).
Зачем рекомендуется ограничивать степень вложенности подменю максимум двумя уровнями?Ответ
Правильный ответ: Глубокая вложенность усложняет навигацию и делает меню менее понятным для пользователей; два уровня — оптимальный баланс между организацией команд и удобством использования.
Почему в Windows 10 и 11 подчёркивания мнемоник не отображаются по умолчанию, даже при нажатии Alt?Ответ
Правильный ответ: Microsoft эволюционировала визуальный дизайн интерфейса для большей чистоты, при этом функциональность мнемоник Alt+буква полностью сохранена независимо от визуального отображения.
Какой метод нужно вызвать, чтобы показать контекстное меню в правильной позиции при нажатии правой кнопки мыши?Ответ
Правильный ответ: Нужно вызвать menu->exec(event->globalPos()) в методе contextMenuEvent(), передав глобальные координаты указателя мыши из объекта события.
Как сделать команду меню недоступной (отображаемой серым цветом)?Ответ
Правильный ответ: Через указатель на QAction вызвать метод setEnabled(false), что визуально отобразит команду серым цветом и заблокирует её выполнение.
Зачем добавлять троеточие в конец названия команды меню?Ответ
Правильный ответ: Троеточие сигнализирует пользователю, что выбор команды откроет диалоговое окно для дополнительных действий; это не применяется к простым окнам сообщений.
Что вернёт метод addAction() после добавления команды в меню?Ответ
Правильный ответ: Метод возвращает указатель на объект QAction, через который можно настраивать свойства команды (флажок, иконку, доступность, горячие клавиши).
Чем принципиально отличается контекстное меню от всплывающего меню в Qt?Ответ
Правильный ответ: Контекстное меню использует тот же класс QMenu, но не присоединяется к QMenuBar, а показывается через exec() при обработке события правого клика мыши.
Какой сигнал отправляет меню при выборе пользователем любой команды, и что он передаёт?Ответ
Правильный ответ: Меню отправляет сигнал triggered(QAction*), передающий указатель на объект действия выбранной команды, что позволяет идентифицировать команду в одном слоте.
Почему Qt автоматически адаптирует отображение мнемоник к конкретной операционной системе?Ответ
Правильный ответ: Разные ОС имеют различные соглашения по отображению клавиш доступа; автоматическая адаптация обеспечивает нативный вид приложения и соответствие ожиданиям пользователей каждой платформы.
Практические задания
Простой уровень
Меню выбора стиля текста
Создайте приложение с текстовым полем (QTextEdit) и меню “Стиль” с командами для изменения форматирования текста: Жирный, Курсив, Подчёркнутый. Каждая команда должна иметь флажок, отражающий текущее состояние. Добавьте горячие клавиши: Ctrl+B, Ctrl+I, Ctrl+U соответственно. Включите разделитель и команду “Сбросить форматирование” в конце.
Подсказки: Используйте QMenuBar и QMenu. Для флажков вызовите setCheckable(true) у объектов QAction. Методы QTextEdit: setFontWeight(), setFontItalic(), setFontUnderline(). Для сброса создайте новый QTextCharFormat и примените его через setCurrentCharFormat().
Средний уровень
Редактор с контекстным меню и цветовыми схемами
Разработайте текстовый редактор с меню верхнего уровня “Файл” (Создать, Открыть, Сохранить, Выход) и контекстным меню для смены цветовой схемы. При правом клике на текстовом поле должно появляться меню с подменю “Тема”, содержащим варианты: Светлая, Тёмная, Синяя. Выбор темы должен менять цвета фона и текста. Добавьте мнемоники для всех команд и стандартные горячие клавиши для команд файлового меню.
Подсказки: Переопределите contextMenuEvent(). Создайте подменю через addMenu(). Используйте QPalette для смены цветов или setStyleSheet(). Сигнал triggered() передаёт QAction*, из которого можно получить text() для определения выбранной темы. Не забудьте добавить троеточие к командам “Открыть…” и “Сохранить…”.
Сложный уровень
Динамическое меню недавних файлов
Создайте приложение для просмотра изображений с полноценным меню. Реализуйте динамическое подменю “Недавние файлы” в меню “Файл”, которое хранит последние 5 открытых файлов. При выборе файла из списка он должен открываться. Список должен обновляться при каждом открытии нового файла (последний — сверху). Если файл уже есть в списке, переместите его наверх. Добавьте команду “Очистить список” в конец подменю. Команды недавних файлов должны быть недоступны, если файл был удалён с диска. Сохраняйте список между запусками приложения.
Подсказки: Используйте QSettings для сохранения списка файлов (QStringList). Создайте слот для обновления подменю, вызываемый при каждом открытии файла. Проверяйте существование файлов через QFile::exists(). Для динамического меню используйте clear() и заново добавляйте действия. Свяжите каждое действие с одним слотом, передающим путь к файлу через QAction::setData() и sender(). QFileDialog для выбора файлов, QLabel с QPixmap для отображения изображений.
💬 Присоединяйтесь к обсуждению!
Разобрались с созданием меню в Qt? Есть вопросы о различиях между горячими клавишами и мнемониками?
Возможно, у вас появились идеи по организации сложных меню или вы столкнулись с особенностями поведения контекстных меню на разных платформах?
Поделитесь своим опытом, задайте вопросы или помогите другим читателям освоить тонкости работы с QMenu и QMenuBar!