blob: 0cf74a7dac950ed6a203afe2b381700c28f27d86 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example mainwindows/menus
\title Menus Example
\ingroup examples-mainwindow
\ingroup examples-layout
\brief The Menus example demonstrates how menus can be used in a main
window application.
A menu widget can be either a pull-down menu in a menu bar or a
standalone context menu. Pull-down menus are shown by the menu bar
when the user clicks on the respective item or presses the
specified shortcut key. Context menus are usually invoked by some
special keyboard key or by right-clicking.
\image menus-example.png
A menu consists of a list of \e action items. In applications,
many common commands can be invoked via menus, toolbar buttons as
well as keyboard shortcuts. Since the user expects the commands to
be performed in the same way, regardless of the user interface
used, it is useful to represent each command as an action.
The Menus example consists of one single class, \c MainWindow, derived
from the QMainWindow class. When choosing one of the
action items in our application, it will display the item's path
in its central widget.
\section1 MainWindow Class Definition
QMainWindow provides a main application window, with a menu bar,
tool bars, dock widgets and a status bar around a large central
widget.
\snippet mainwindows/menus/mainwindow.h 0
In this example, we will see how to implement pull-down menus as
well as a context menu. In order to implement a custom context
menu we must reimplement QWidget's \l
{QWidget::}{contextMenuEvent()} function to receive the context
menu events for our main window.
\snippet mainwindows/menus/mainwindow.h 1
We must also implement a collection of private slots to respond to
the user activating any of our menu entries. Note that these
slots are left out of this documentation since they are trivial,
i.e., most of them are only displaying the action's path in the
main window's central widget.
\snippet mainwindows/menus/mainwindow.h 2
We have chosen to simplify the constructor by implementing two
private convenience functions to create the various actions, to
add them to menus and to insert the menus into our main window's
menu bar.
\snippet mainwindows/menus/mainwindow.h 3
Finally, we declare the various menus and actions as well as a
simple information label in the application wide scope.
The QMenu class provides a menu widget for use in menu bars,
context menus, and other popup menus while the QAction class
provides an abstract user interface action that can be inserted
into widgets.
In some situations it is useful to group actions together, e.g.,
we have a \uicontrol {Left Align} action, a \uicontrol {Right Align} action, a
\uicontrol {Justify} action, and a \uicontrol {Center} action, and we want
only one of these actions to be active at any one time. One simple
way of achieving this is to group the actions together in an
action group using the QActionGroup class.
\section1 MainWindow Class Implementation
In the constructor, we start off by creating a regular QWidget and
make it our main window's central widget. Note that the main
window takes ownership of the widget pointer and deletes it at the
appropriate time.
\snippet mainwindows/menus/mainwindow.cpp 0
\codeline
\snippet mainwindows/menus/mainwindow.cpp 1
Then we create the information label as well as a top and bottom
filler that we add to a layout which we install on the central
widget. QMainWindow objects come with their own customized layout
and setting a layout on a the actual main window, or creating a
layout with a main window as a parent, is considered an error. You
should always set your own layout on the central widget instead.
\snippet mainwindows/menus/mainwindow.cpp 2
To create the actions and menus we call our two convenience
functions: \c createActions() and \c createMenus(). We will get
back to these shortly.
QMainWindow's \l {QMainWindow::statusBar()}{statusBar()} function
returns the status bar for the main window (if the status bar does
not exist, this function will create and return an empty status
bar). We initialize the status bar and window title, resize the
window to an appropriate size as well as ensure that the main
window cannot be resized to a smaller size than the given
one.
Now, let's take a closer look at the \c createActions() convenience
function that creates the various actions:
\snippet mainwindows/menus/mainwindow.cpp 4
\dots
A QAction object may contain an icon, a text, a shortcut, a status
tip, a "What's This?" text, and a tooltip. Most of these can be
set in the constructor, but they can also be set independently
using the provided convenience functions.
In the \c createActions() function, we first create a \c newAct
action. We make \uicontrol Ctrl+N its shortcut using the
QAction::setShortcut() function, and we set its status tip using the
QAction::setStatusTip() function (the status tip is displayed on all
status bars provided by the action's top-level parent widget). We
also connect its \l {QAction::}{triggered()} signal to the \c
newFile() slot.
The rest of the actions are created in a similar manner. Please
see the source code for details.
\snippet mainwindows/menus/mainwindow.cpp 7
Once we have created the \uicontrol {Left Align}, \uicontrol {Right Align},
\uicontrol {Justify}, and a \uicontrol {Center} actions, we can also create
the previously mentioned action group.
Each action is added to the group using QActionGroup's \l
{QActionGroup::}{addAction()} function. Note that an action also
can be added to a group by creating it with the group as its
parent. Since an action group is exclusive by default, only one of
the actions in the group is checked at any one time (this can be
altered using the QActionGroup::setExclusive() function).
When all the actions are created, we use the \c createMenus()
function to add the actions to the menus and to insert the menus
into the menu bar:
\snippet mainwindows/menus/mainwindow.cpp 8
QMenuBar's \l {QMenuBar::addMenu()}{addMenu()} function appends a
new QMenu with the given title, to the menu bar (note that the
menu bar takes ownership of the menu). We use QWidget's \l
{QWidget::addAction()}{addAction()} function to add each action to
the corresponding menu.
Alternatively, the QMenu class provides several \l
{QMenu::addAction()}{addAction()} convenience functions that create
and add new actions from given texts and/or icons. You can also
provide a member that will automatically connect to the new
action's \l {QAction::triggered()}{triggered()} signal, and a
shortcut represented by a QKeySequence instance.
The QMenu::addSeparator() function creates and returns a new
separator action, i.e. an action for which QAction::isSeparator()
returns true, and adds the new action to the menu's list of
actions.
\snippet mainwindows/menus/mainwindow.cpp 12
Note the \uicontrol Format menu. First of all, it is added as a submenu
to the \uicontrol Edit Menu using QMenu's \l
{QMenu::addMenu()}{addMenu()} function. Secondly, take a look at the
alignment actions: In the \c createActions() function we added the
\c leftAlignAct, \c rightAlignAct, \c justifyAct and \c centerAct
actions to an action group. Nevertheless, we must add each action
to the menu separately while the action group does its magic
behind the scene.
\snippet mainwindows/menus/mainwindow.cpp 3
To provide a custom context menu, we must reimplement QWidget's \l
{QWidget::}{contextMenuEvent()} function to receive the widget's
context menu events (note that the default implementation simply
ignores these events).
Whenever we receive such an event, we create a menu containing the
\uicontrol Cut, \uicontrol Copy and \uicontrol Paste actions. Context menus can be
executed either asynchronously using the \l {QMenu::}{popup()}
function or synchronously using the \l {QMenu::}{exec()}
function. In this example, we have chosen to show the menu using
its \l {QMenu::}{exec()} function. By passing the event's position
as argument we ensure that the context menu appears at the
expected position.
*/