Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickmenuitem.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
9
10#include <QtGui/qpa/qplatformtheme.h>
11#include <QtQuick/private/qquickevents_p_p.h>
12
14
15/*!
16 \qmltype MenuItem
17 \inherits AbstractButton
18//! \nativetype QQuickMenuItem
19 \inqmlmodule QtQuick.Controls
20 \since 5.7
21 \ingroup qtquickcontrols-menus
22 \brief Presents an item within a Menu.
23
24 MenuItem is a convenience type that implements the AbstractButton API,
25 providing a familiar way to respond to menu items being \l triggered, for
26 example.
27
28 MenuItem inherits its API from AbstractButton. For instance, you can set
29 \l {AbstractButton::text}{text} and \l {Icons in Qt Quick Controls}{icon}
30 using the AbstractButton API.
31
32 \code
33 Button {
34 id: fileButton
35 text: "File"
36 onClicked: menu.open()
37
38 Menu {
39 id: menu
40
41 MenuItem {
42 text: "New..."
43 onTriggered: document.reset()
44 }
45 MenuItem {
46 text: "Open..."
47 onTriggered: openDialog.open()
48 }
49 MenuItem {
50 text: "Save"
51 onTriggered: saveDialog.open()
52 }
53 }
54 }
55 \endcode
56
57 \sa {Customizing Menu}, Menu, {Menu Controls}
58*/
59
60/*!
61 \qmlproperty real QtQuick.Controls::MenuItem::textPadding
62 \readonly
63 \since 6.8
64
65 This property holds the maximum \l implicitTextPadding found
66 among all the menu items inside the same \l menu.
67
68 This property can be used by the style to ensure that all MenuItems
69 inside the same Menu end up aligned with respect to the
70 \l {AbstractButton::} {text}.
71
72 A \l Menu can consist of meny different MenuItems, some can be checkable,
73 some can have an icon, and some will just contain text. And very often,
74 a style wants to make sure that the text inside all of them ends up
75 left-aligned (or right-aligned for \l {Control::} {mirrored} items).
76 By letting each MenuItem assign its own minimum text padding to
77 \l implicitTextPadding (taking icons and checkmarks into account), but
78 using \l textPadding to actually position the
79 \l {AbstractButton::} {text}, all MenuItems should end up being aligned
80
81 In order for this to work, all MenuItems should set \l implicitTextPadding
82 to be the minimum space needed from the left edge of the
83 \l {Control::} {contentItem} to the text.
84
85 \sa implicitTextPadding
86*/
87
88/*!
89 \qmlproperty real QtQuick.Controls::MenuItem::implicitTextPadding
90 \since 6.8
91
92 This property holds the minimum space needed from the left edge of the
93 \l {Control::} {contentItem} to the text. It's used to calculate a common
94 \l textPadding among all the MenuItems inside a \l Menu.
95
96 \sa textPadding
97*/
98
99void QQuickMenuItemPrivate::setMenu(QQuickMenu *newMenu)
100{
101 Q_Q(QQuickMenuItem);
102 if (menu == newMenu)
103 return;
104
105 menu = newMenu;
106 emit q->menuChanged();
107}
108
109void QQuickMenuItemPrivate::setSubMenu(QQuickMenu *newSubMenu)
110{
111 Q_Q(QQuickMenuItem);
112 if (subMenu == newSubMenu)
113 return;
114
115 if (subMenu) {
116 QObject::disconnect(subMenu, &QQuickMenu::titleChanged, q, &QQuickAbstractButton::setText);
117 QObject::disconnect(subMenu, &QQuickMenu::iconChanged, q, &QQuickAbstractButton::setIcon);
118 QObjectPrivate::disconnect(subMenu, &QQuickPopup::enabledChanged, this, &QQuickMenuItemPrivate::updateEnabled);
119 }
120
121 if (newSubMenu) {
122 QObject::connect(newSubMenu, &QQuickMenu::titleChanged, q, &QQuickAbstractButton::setText);
123 QObject::connect(newSubMenu, &QQuickMenu::iconChanged, q, &QQuickAbstractButton::setIcon);
124 QObjectPrivate::connect(newSubMenu, &QQuickPopup::enabledChanged, this, &QQuickMenuItemPrivate::updateEnabled);
125 q->setText(newSubMenu->title());
126 q->setIcon(newSubMenu->icon());
127#if QT_CONFIG(wayland)
128 QQuickMenuPrivate::get(newSubMenu)->extendedWindowType = QNativeInterface::Private::QWaylandWindow::SubMenu;
129#endif
130 }
131
132 subMenu = newSubMenu;
134 emit q->subMenuChanged();
135}
136
138{
139 Q_Q(QQuickMenuItem);
140 q->setEnabled(subMenu && subMenu->isEnabled());
141}
142
143static inline QString arrowName() { return QStringLiteral("arrow"); }
144
146{
147 Q_Q(QQuickAbstractButton);
148 quickCancelDeferred(q, arrowName());
149}
150
152{
153 Q_Q(QQuickMenuItem);
154 if (arrow.wasExecuted())
155 return;
156
157 if (!arrow || complete)
158 quickBeginDeferred(q, arrowName(), arrow);
159 if (complete)
160 quickCompleteDeferred(q, arrowName(), arrow);
161}
162
163bool QQuickMenuItemPrivate::acceptKeyClick(Qt::Key key) const
164{
165 return key == Qt::Key_Return || key == Qt::Key_Enter
166 || QQuickAbstractButtonPrivate::acceptKeyClick(key);
167}
168
170{
171 return QQuickTheme::palette(QQuickTheme::Menu);
172}
173
174/*!
175 \qmlsignal void QtQuick.Controls::MenuItem::triggered()
176
177 This signal is emitted when the menu item is triggered by the user.
178*/
179
180QQuickMenuItem::QQuickMenuItem(QQuickItem *parent)
181 : QQuickAbstractButton(*(new QQuickMenuItemPrivate), parent)
182{
183 connect(this, &QQuickAbstractButton::clicked, this, &QQuickMenuItem::triggered);
184}
185
186/*!
187 \qmlproperty bool QtQuick.Controls::MenuItem::highlighted
188
189 This property holds whether the menu item is highlighted by the user.
190
191 A menu item can be highlighted by mouse hover or keyboard navigation.
192
193 The default value is \c false.
194
195 \sa Menu::currentIndex
196*/
197bool QQuickMenuItem::isHighlighted() const
198{
199 Q_D(const QQuickMenuItem);
200 return d->highlighted;
201}
202
203void QQuickMenuItem::setHighlighted(bool highlighted)
204{
205 Q_D(QQuickMenuItem);
206 if (highlighted == d->highlighted)
207 return;
208
209 d->highlighted = highlighted;
210 emit highlightedChanged();
211}
212
213/*!
214 \since QtQuick.Controls 2.3 (Qt 5.10)
215 \qmlproperty Item QtQuick.Controls::MenuItem::arrow
216
217 This property holds the sub-menu arrow item.
218
219 \sa {Customizing Menu}
220*/
221QQuickItem *QQuickMenuItem::arrow() const
222{
223 QQuickMenuItemPrivate *d = const_cast<QQuickMenuItemPrivate *>(d_func());
224 if (!d->arrow)
225 d->executeArrow();
226 return d->arrow;
227}
228
229void QQuickMenuItem::setArrow(QQuickItem *arrow)
230{
231 Q_D(QQuickMenuItem);
232 if (d->arrow == arrow)
233 return;
234
235 if (!d->arrow.isExecuting())
236 d->cancelArrow();
237
238 QQuickControlPrivate::hideOldItem(d->arrow);
239 d->arrow = arrow;
240 if (arrow && !arrow->parentItem())
241 arrow->setParentItem(this);
242 if (!d->arrow.isExecuting())
243 emit arrowChanged();
244}
245
246/*!
247 \since QtQuick.Controls 2.3 (Qt 5.10)
248 \qmlproperty Menu QtQuick.Controls::MenuItem::menu
249 \readonly
250
251 This property holds the menu that contains this menu item,
252 or \c null if the item is not in a menu.
253*/
254QQuickMenu *QQuickMenuItem::menu() const
255{
256 Q_D(const QQuickMenuItem);
257 return d->menu;
258}
259
260/*!
261 \since QtQuick.Controls 2.3 (Qt 5.10)
262 \qmlproperty Menu QtQuick.Controls::MenuItem::subMenu
263 \readonly
264
265 This property holds the sub-menu that this item presents in
266 the parent menu, or \c null if this item is not a sub-menu item.
267*/
268QQuickMenu *QQuickMenuItem::subMenu() const
269{
270 Q_D(const QQuickMenuItem);
271 return d->subMenu;
272}
273
274void QQuickMenuItem::componentComplete()
275{
276 Q_D(QQuickMenuItem);
277 d->executeArrow(true);
278 QQuickAbstractButton::componentComplete();
279}
280
281QFont QQuickMenuItem::defaultFont() const
282{
283 return QQuickTheme::font(QQuickTheme::Menu);
284}
285
286qreal QQuickMenuItem::implicitTextPadding() const
287{
288 return d_func()->implicitTextPadding;
289}
290
291void QQuickMenuItem::setImplicitTextPadding(qreal newImplicitTextPadding)
292{
293 Q_D(QQuickMenuItem);
294 if (qFuzzyCompare(d->implicitTextPadding, newImplicitTextPadding))
295 return;
296 d->implicitTextPadding = newImplicitTextPadding;
297 emit implicitTextPaddingChanged();
298}
299
300qreal QQuickMenuItem::textPadding() const
301{
302 Q_D(const QQuickMenuItem);
303 return d->menu ? QQuickMenuPrivate::get(d->menu)->textPadding : 0;
304}
305
306#if QT_CONFIG(accessibility)
307QAccessible::Role QQuickMenuItem::accessibleRole() const
308{
309 return QAccessible::MenuItem;
310}
311#endif
312
313#ifndef QT_NO_DEBUG_STREAM
314QDebug operator<<(QDebug debug, const QQuickMenuItem *menuItem)
315{
316 QDebugStateSaver saver(debug);
317 debug.nospace();
318 if (!menuItem) {
319 debug << "QQuickMenuItem(nullptr)";
320 return debug;
321 }
322
323 debug << menuItem->metaObject()->className() << '(' << static_cast<const void *>(menuItem);
324 if (!menuItem->objectName().isEmpty())
325 debug << ", name=" << menuItem->objectName();
326 debug << ", text=" << menuItem->text();
327 debug << ')';
328 return debug;
329}
330#endif // QT_NO_DEBUG_STREAM
331
332QT_END_NAMESPACE
333
334#include "moc_qquickmenuitem_p.cpp"
QPalette defaultPalette() const override
void setSubMenu(QQuickMenu *subMenu)
void executeArrow(bool complete=false)
bool acceptKeyClick(Qt::Key key) const override
Combined button and popup list for selecting options.
static QString arrowName()
QDebug operator<<(QDebug debug, const QQuickMenuItem *menuItem)