=> Главная База Знаний Qt Создание меню и панелей инструментов


Создание меню и панелей инструментов

Создание меню и панелей инструментов

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

Рис. 3.3. Меню приложения Электронная таблица.

Использование понятия «действия» упрощает программирование меню и панелей инструментов при помощи средств разработки Qt. Элемент action (действие) можно добавлять к любому количеству меню и панелей инструментов. Создание в Qt меню и панелей инструментов разбивается на следующие этапы:

• создание и настройка действий;

• создание меню и добавление к ним действий;

• создание панелей инструментов и добавление к ним действий.

В приложении Электронная таблица действия создаются в createActions():

01 void MainWindow::createActions()

02 {

03 newAction = new QAction(tr("&New"), this);

04 newAction->setIcon(QIcon(":/images/new.png"));

05 newAction->setShortcut(tr("Ctrl+N"));

06 newAction->setStatusTip(tr("Create a new spreadsheet file"));

07 connect(newAction, SIGNAL(triggered()),

08 this, SLOT(newFile()));

Действие New (создать) имеет клавишу быстрого выбора пункта меню (New)[5], родительское окно (главное окно), пиктограмму (new.png), клавишу быстрого вызова команды (Ctrl+N) и сообщение в строке состояния. Мы подсоединяем к сигналу этого действия triggered() закрытый слот главного окна newFile(); этот слот мы реализуем в следующем разделе. Это соединение гарантирует, что при выборе пользователем пункта меню File | New (файл | создать), при нажатии им кнопки New на панели инструментов или при нажатии клавиш Ctrl+N будет вызван слот newFile().

Создание действий Open (открыть), Save (сохранить) и Save As (сохранить как) очень похоже на создание действия New, поэтому мы сразу переходим к строке «recently opened files» (недавно открытые файлы) меню File:

09 for (int i = 0; i < MaxRecentFiles; ++i)

10 {

11 recentFileActions[i] = new QAction(this);

12 recentFileActions[i]->setVisible(false);

13 connect(recentFileActions[i], SIGNAL(triggered()),

14 this, SLOT(openRecentFile()));

15 }

Мы заполняем действиями массив recentFileActions. Каждое действие скрыто и подключается к слоту openRecentFile(). Далее мы покажем, как действия в списке недавно используемых файлов сделать видимыми, чтобы можно было ими воспользоваться.

Теперь перейдем к действию Select All (выделить все):

16 selectAllAction = new QAction(tr("&All"), this);

17 selectAllAction->setShortcut(tr("Ctrl+A"));

18 selectAllAction->setStatusTip(tr("Select all the cells in the spreadsheet"));

19 connect(selectAllAction, SIGNAL(triggered()),

20 spreadsheet, SLOT(selectAll()));

Слот selectAll() обеспечивается в QAbstractItemView, который является одним из базовых классов QTableWidget, поэтому нам самим не надо его реализовывать.

Давайте теперь перейдем к действию Show Grid (показать сетку) из меню Options (опции):

21 showGridAction = new QAction(tr("&Show Grid"), this);

22 showGridAction->setCheckable(true);

23 showGridAction->setChecked(spreadsheet->showGrid());

24 showGridAction->setStatusTip(tr("Show or hide the spreadsheet's grid"));

25 connect(showGridAction, SIGNAL(toggled(bool)),

26 spreadsheet, SLOT(setShowGrid(bool)));

Действие Show Grid является включаемым. Оно имеет маркер флажка в меню и реализуется как кнопка—переключатель на панели инструментов. Когда это действие включено, на компоненте Spreadsheet отображается сетка. При запуске приложения мы инициализируем это действие в соответствии со значениями, которые принимаются по умолчанию компонентом Spreadsheet, и поэтому работа этого переключателя будет с самого начала синхронизирована. Затем мы соединяем сигнал toggled(bool) действия Show Grid со слотом setShowGrid(bool) компонента Spreadsheet, который наследуется от QTableWidget. После добавления этого действия к меню или панели инструментов пользователь сможет включать и выключать сетку.

Действия—переключатели Show Grid и Auto—Recalculate (автопересчет) работают независимо. Кроме того, Qt обеспечивает возможность определения взаимоисключающих действий путем применения своего собственного класса QActionGroup.

27 aboutQtAction = new QAction(tr("About &Qt"), this);

28 aboutQtAction->setStatusTip(tr("Show the Qt library's About box"));

29 connect(aboutQtAction, SIGNAL(triggered()),

30 qApp, SLOT(aboutQt()));

31 }

Для действия About Qt (справка по средствам разработки Qt) мы используем слот aboutQt() объекта QApplication, который доступен через глобальную переменную qApp.

Рис. 3.4. Диалоговое окно About Qt.

Действия нами созданы, и теперь мы можем перейти к построению системы меню с этими действиями.

01 void MainWindow::createMenus()

02 {

03 fileMenu = menuBar()->addMenu(tr("&File"));

04 fileMenu->addAction(newAction);

05 fileMenu->addAction(openAction);

06 fileMenu->addAction(saveAction);

07 fileMenu->addAction(saveAsAction);

08 separatorAction = fileMenu->addSeparator();

09 for (int i = 0; i < MaxRecentFiles; ++i)

10 fileMenu->addAction(recentFileActions[i]);

11 fileMenu->addSeparator();

12 fileMenu->addAction(exitAction);

В Qt все меню являются экземплярами класса QMenu. Функция addMenu() создает виджет QMenu с заданным текстом и добавляет его в строку меню. Функция QMainWindow::menuBar() возвращает указатель на QMenuBar. Строка меню создается при первом вызове menuBar().

Сначала мы создаем меню File (файл) и затем добавляем к нему действия New, Open, Save и Save As (создать, открыть, сохранить и сохранить как). Мы вставляем разделитель для визуального выделения группы взаимосвязанных пунктов меню. Мы используем цикл for для добавления (первоначально скрытых) действий из массива recentFileActions, а в конце добавляем действие exitAction.

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

13 editMenu = menuBar()->addMenu(tr("&Edit"));

14 editMenu->addAction(cutAction);

15 editMenu->addAction(copyAction);

16 editMenu->addAction(pasteAction);

17 editMenu->addAction(deleteAction);


18 selectSubMenu = editMenu->addMenu(tr("&Select"));

19 selectSubMenu->addAction(selectRowAction);

20 selectSubMenu->addAction(selectColumnAction);

21 selectSubMenu->addAction(selectAllAction);


22 editMenu->addSeparator();

23 editMenu->addAction(findAction);

24 editMenu->addAction(goToCellAction);

В меню Edit (правка) включается подменю. Это подменю (как и меню, к которому оно принадлежит) является экземпляром класса QPopupMenu. Мы просто создаем подменю путем указания this в качестве его родителя и вставляем его в то место меню Edit, где мы собираемся его расположить.

Теперь мы создаем меню Edit (правка), добавляя действия при помощи QMenu::addAction(), как мы это делали для меню File, и добавляя подменю в нужную позицию при помощи QMenu::addMenu(). Подменю, как и меню, к которому оно относится, имеет тип QMenu.

25 toolsMenu = menuBar()->addMenu(tr("&Tools"));

26 toolsMenu->addAction(recalculateAction);

27 toolsMenu->addAction(sortAction);


28 optionsMenu = menuBar()->addMenu(tr("&Options"));

29 optionsMenu->addAction(showGridAction);

30 optionsMenu->addAction(autoRecalcAction);


31 menuBar()->addSeparator();

32 helpMenu = menuBar()->addMenu(tr("&Help"));

33 helpMenu->addAction(aboutAction);

34 helpMenu->addAction(aboutQtAction);

35 }

Подобным же образом мы создаем меню Tools, Options и Help (инструменты, опции и помощь). Мы вставляем разделитель между меню Options и Help. В системах Motif и CDE этот разделитель сдвигает меню Help вправо; в других случаях этот разделитель игнорируется.

Рис. 3.5. Полоса главного меню в стилях систем Motif и Windows.

01 void MainWindow::createContextMenu()

02 {

03 spreadsheet->addAction(copyAction);

04 spreadsheet->addAction(pasteAction);

05 spreadsheet->addAction(cutAction);

06 spreadsheet->setContextMenuPolicy(Qt::ActionsContextMenu);

07 }

Любой виджет в Qt может иметь связанный с ним список действий QAction. Для обеспечения в приложении контекстного меню мы добавляем необходимые нам действия в виджет Spreadsheet и устанавливаем политику контекстного меню виджета на отображение контекстного меню с этими действиями. Контекстные меню вызываются при щелчке правой клавишей мышки по виджету или при нажатии специальной клавиши клавиатуры, зависящей от платформы.

Рис. 3.6. Контекстное меню приложения Электронная таблица.

Более сложный способ обеспечения контекстного меню заключается в переопределении функции QWidget::contextMenuEvent(), создании виджета QMenu, заполнении его требуемыми действиями и вызове для него функции exec().

01 void Mainwindow::createToolBars()

02 {

03 fileToolBar = addToolBar(tr("&File"));

04 fileToolBar->addAction(newAction);

05 fileToolBar->addAction(openAction);

06 fileToolBar->addAction(saveAction);

07 editToolBar = addToolBar(tr("&Edif));

08 editToolBar->addAction(cutAction);

09 editToolBar->addAction(copyAction);

10 editToolBar->addAction(pasteAction);

11 editToolBar->addSeparator();

12 editToolBar->addAction(findAction);

13 editToolBar->addAction(goToCellAction);

14 }

Создание панелей инструментов очень похоже на создание меню. Мы создаем панель инструментов File и панель инструментов Edit. Как и меню, панель инструментов может иметь разделители.

Рис. 3.7. Панели инструментов приложения Электронная таблица.