Урок №7. Создание меню и панели инструментов в Qt5

  Дмитрий Бушуев  | 

  |

  Обновл. 16 Сен 2021  | 

 38149

 ǀ   11 

На этом уроке мы поговорим о создании таких графических элементов приложения, как меню и панель инструментов. Большинство современных приложений имеют как меню, так и панель инструментов, которые содержат более-менее идентичный набор команд.

Меню является стандартной частью приложения с графическим интерфейсом и предоставляет пользователю возможность заняться «исследованием» приложения (изучать доступные команды), в то время как панели инструментов обеспечивают быстрый доступ к наиболее часто используемым командам.

Создание простого меню

Сейчас мы попробуем создать простое меню.

Заголовочный файл — simplemenu.h:

У нас есть строка меню с элементами и действиями, которые активируются по нажатию кнопки мыши (на соответствующий пункт). Чтобы работать с меню, нам сначала нужно выполнить наследование виджета QMainWindow.

Файл реализации — simplemenu.cpp:

Класс QAction представляет собой абстрактное действие пользовательского интерфейса, которое может быть вставлено в виджеты. В приложениях множество общих команд может быть вызвано через меню, панель инструментов и сочетания горячих клавиш. Поскольку пользователь ожидает, что каждая команда будет выполняться одним и тем же способом, независимо от используемого пользовательского интерфейса, то полезно представить каждую команду как действие. При этом каждый объект класса QMenu может иметь один или несколько объектов действия.

Основной файл программы — main.cpp:

Результат выполнения программы:


Иконки, горячие клавиши и разделители


Теперь давайте немного улучшим наше предыдущее приложение. Добавим в него иконки к пунктам меню, зададим сочетания горячих клавиш и установим разделитель.

Заголовочный файл — anothermenu.h:

В данном примере у нас есть одно меню с тремя действиями. При этом только действие Quit является рабочим. Мы также установим разделитель — горизонтальную линию, которая позволит нам группировать действия меню в некоторые логические группы, и сочетание клавиш CTRL+Q, которое будет завершать работу нашего приложения.

Файл реализации — anothermenu.cpp:

Основной файл программы — main.cpp:

Результат выполнения программы:


Меню с чекбоксом

Теперь попробуем создать пункт меню, который можно будет отметить галочкой.

Заголовочный файл — checkable.h:

Файл реализации — checkable.cpp:

Основной файл программы — main.cpp:

Результат выполнения программы:


Добавление панели инструментов


Класс QToolBar предоставляет программисту возможность использовать подвижную панель, содержащую набор элементов управления, которые обеспечивают быстрый доступ к действиям приложения.

Заголовочный файл — toolbar.h:

Чтобы создать панель инструментов, нужно выполнить наследование виджета QMainWindow.

Файл реализации — toolbar.cpp:

Основной файл программы — main.cpp:

Результат выполнения программы:


Каркас приложения

Сейчас мы попробуем создать заготовку, которая может стать основой для нашего будущего (уже более сложного) приложения. Пример основан на возможностях виджета QMainWindow.

Заголовочный файл — skeleton.h:

Создаем элементы меню, панель инструментов и панель состояния.

Файл реализации — skeleton.cpp:

Основной файл приложения — main.cpp:

Результат выполнения программы:


Заключение


На следующем уроке мы рассмотрим набор классов для управления макетом нашего приложения.

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (40 оценок, среднее: 4,78 из 5)
Загрузка...

Комментариев: 11

  1. dn:

    Поясните за последний пример, вроде TextEdit ничем не инициализируется но на скрине написано «Quit Application»

  2. Rock:

    можно рассказать о двух строчках из чек бокса

    зачем в коде statusBar(); по документации он возвращает пустую строку состояния главного окна но как она помогает в текущем коде не ясно

    и в конекте всегда писали 3 аргументом qApp а тут this с чем связанно то что в данном примере мы передаем QMainWindow

    заранее спасибо

    1. Фото аватара Дмитрий Бушуев:

      По первому вопросу:
      Попробуйте закомментировать в конструкторе вызов statusBar(). Вы увидите, что теперь на старте у приложения не будет строки состояния.
      (Для наглядности вместо statusBar() можете использовать statusBar()->showMessage("Status Bar"); )

      По второму вопросу:
      Если по простому, то соединение сигнала со слотом происходит следующим образом: connect(отправитель, сигнал_отправителя, получатель, слот_получателя). Все четыре параметра представлены в виде адресов на соответствующие объекты.
      Далее, мы, находясь внутри объекта-получателя класса Checkable, пытаемся связать его слот-метод Checkable::toggleStatusbar() с внешним сигналом. А как сослаться на объект, находясь внутри него? Правильно, через указатель this.

      Почему в других примерах вместо this использовали qApp? Потому что в этом случае получателем сигнала (приводящего к закрытию окна) было само приложение (объект класса QApplication), а не наш объект класса Checkable . И мы должны каким-то образом передать указатель на приложение. Для этого в Qt есть встроенная переменная под названием… qApp. Как-то так 🙂

      1. Rock:

        Обратил внимание что в "плюс минус" приложении из прошлого поста тоже указатель this в коннекте и там тоже собственный слот сигнал.
        Резюмируя — если слот самописный то указатель this и адрес метода слота внутри нашего класса четвертым параметром, а если слот уже есть в программе то обращаться нужно к qApp? Если все верно то спасибо разобрался.

        Единственное что смущает это макрос slots после спецификатора,
        он функциональный или лишь для удобства чтения? Удаление его (в моем случае) не повредило сигналам и слотам.

        1. Фото аватара Дмитрий Бушуев:

          >>Резюмируя — если слот самописный то указатель this и адрес метода слота внутри нашего класса четвертым параметром, а если слот уже есть в программе то обращаться нужно к qApp? Если все верно…

          Нет.
          В качестве примера, посмотрите на объявление класса Checkable:

          Как нетрудно заметить, происходит открытое наследование от класса QMainWindow. А в данном классе есть уже готовые слоты, которые перейдут и в наш класс Checkable, а именно:
          Public Slots

          https://doc.qt.io/qt-5/qmainwindow.html#public-slots

          Мы не будем сейчас разбирать, для чего нужны вышеприведенные слоты. Важен сам факт того, что они есть. Допустим, мы захотели связать сигнал не с самописным слотом Checkable::toggleStatusbar(), а с унаследованным от QMainWindow слотом setAnimated(). Для этого напишем:

          Обратите внимание, что слот setAnimated() — не самописный, но в то же время мы используем указатель this. Подумайте — почему так?

          А чтобы легче думалось, советую перечитать моё предыдущее сообщение, а также этот урок:
          Урок №121. Скрытый указатель *this
          https://ravesli.com/urok-121-skrytyj-ukazatel-this/

  3. Владимир:

    Вот смотрю на примеры, в частности на последний, и у меня возникает недоумение…
    Вот создаются в конструкторе окна объекты QToolbar и QMenu(точнее указатели на них), но при создании, им не передается это окно как владелец/родитель(this)(явной привязки этих объектов к главному окну нет), им вообще никакой владелец не передается при создании. Как после сборки, они оказываются частью главного окна?

    1. Фото аватара Дмитрий Бушуев:

      >>Вот создаются в конструкторе окна объекты QToolbar и QMenu […]. Как после сборки, они оказываются частью главного окна?

      Насчет QMenu офф. документация по Qt говорит следующее:

      "QMenuBar *QMainWindow::menuBar() const

      If you want all windows in a Mac application to share one menu bar, don't use this function to create it, because (—->)the menu bar created here will have this QMainWindow as its parent(<—-). Instead, you must create a menu bar that does not have a parent, which you can then share among all the Mac windows. Create a parent-less menu bar this way:

      QMenuBar *menuBar = new QMenuBar(nullptr);"

      Т.е., для меню, созданного через вызов функции menuBar(), родитель назначается автоматически.

  4. Михаил Харитонов:

    Для понимания, при создании QAction амперсанд "&" указывает на букву для быстрого вызова этого пункта меню. Т.е. если мы сделает вот так QAction("F&ile") — тогда быстрая буква будет на "i", если вот так QAction("&File") — тогда быстрая буква будет на "f". Может быть я невнимательно читал и не нашел тут упоминания об этом, и полей в нете искать причину этого амперсанда)

  5. KaligayevX3:

    Извините, когда пробовал у себя anothermenu картинки около пунктов меню не появлялись, хотя код точная — копия вашего, версия — qt 5.13.0, помогите, пожалуйста

    1. Chiz:

      У меня было так же, я просто указал прямой путь к другим иконкам, подумал может он не видит эти иконки. Как только указал всё заработало, вот пример:

    2. Фото аватара Дмитрий Бушуев:

      Как уже верно заметили выше. попробуйте прописать прямой путь к каждой иконке 🙂

Добавить комментарий для KaligayevX3 Отменить ответ

Ваш E-mail не будет опубликован. Обязательные поля помечены *