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 }
128
129 subMenu = newSubMenu;
131 emit q->subMenuChanged();
132}
133
135{
136 Q_Q(QQuickMenuItem);
137 q->setEnabled(subMenu && subMenu->isEnabled());
138}
139
140static inline QString arrowName() { return QStringLiteral("arrow"); }
141
143{
144 Q_Q(QQuickAbstractButton);
145 quickCancelDeferred(q, arrowName());
146}
147
149{
150 Q_Q(QQuickMenuItem);
151 if (arrow.wasExecuted())
152 return;
153
154 if (!arrow || complete)
155 quickBeginDeferred(q, arrowName(), arrow);
156 if (complete)
157 quickCompleteDeferred(q, arrowName(), arrow);
158}
159
160bool QQuickMenuItemPrivate::acceptKeyClick(Qt::Key key) const
161{
162 return key == Qt::Key_Return || key == Qt::Key_Enter
163 || QQuickAbstractButtonPrivate::acceptKeyClick(key);
164}
165
167{
168 return QQuickTheme::palette(QQuickTheme::Menu);
169}
170
171/*!
172 \qmlsignal void QtQuick.Controls::MenuItem::triggered()
173
174 This signal is emitted when the menu item is triggered by the user.
175*/
176
177QQuickMenuItem::QQuickMenuItem(QQuickItem *parent)
178 : QQuickAbstractButton(*(new QQuickMenuItemPrivate), parent)
179{
180 connect(this, &QQuickAbstractButton::clicked, this, &QQuickMenuItem::triggered);
181}
182
183/*!
184 \qmlproperty bool QtQuick.Controls::MenuItem::highlighted
185
186 This property holds whether the menu item is highlighted by the user.
187
188 A menu item can be highlighted by mouse hover or keyboard navigation.
189
190 The default value is \c false.
191
192 \sa Menu::currentIndex
193*/
194bool QQuickMenuItem::isHighlighted() const
195{
196 Q_D(const QQuickMenuItem);
197 return d->highlighted;
198}
199
200void QQuickMenuItem::setHighlighted(bool highlighted)
201{
202 Q_D(QQuickMenuItem);
203 if (highlighted == d->highlighted)
204 return;
205
206 d->highlighted = highlighted;
207 emit highlightedChanged();
208}
209
210/*!
211 \since QtQuick.Controls 2.3 (Qt 5.10)
212 \qmlproperty Item QtQuick.Controls::MenuItem::arrow
213
214 This property holds the sub-menu arrow item.
215
216 \sa {Customizing Menu}
217*/
218QQuickItem *QQuickMenuItem::arrow() const
219{
220 QQuickMenuItemPrivate *d = const_cast<QQuickMenuItemPrivate *>(d_func());
221 if (!d->arrow)
222 d->executeArrow();
223 return d->arrow;
224}
225
226void QQuickMenuItem::setArrow(QQuickItem *arrow)
227{
228 Q_D(QQuickMenuItem);
229 if (d->arrow == arrow)
230 return;
231
232 if (!d->arrow.isExecuting())
233 d->cancelArrow();
234
235 QQuickControlPrivate::hideOldItem(d->arrow);
236 d->arrow = arrow;
237 if (arrow && !arrow->parentItem())
238 arrow->setParentItem(this);
239 if (!d->arrow.isExecuting())
240 emit arrowChanged();
241}
242
243/*!
244 \since QtQuick.Controls 2.3 (Qt 5.10)
245 \qmlproperty Menu QtQuick.Controls::MenuItem::menu
246 \readonly
247
248 This property holds the menu that contains this menu item,
249 or \c null if the item is not in a menu.
250*/
251QQuickMenu *QQuickMenuItem::menu() const
252{
253 Q_D(const QQuickMenuItem);
254 return d->menu;
255}
256
257/*!
258 \since QtQuick.Controls 2.3 (Qt 5.10)
259 \qmlproperty Menu QtQuick.Controls::MenuItem::subMenu
260 \readonly
261
262 This property holds the sub-menu that this item presents in
263 the parent menu, or \c null if this item is not a sub-menu item.
264*/
265QQuickMenu *QQuickMenuItem::subMenu() const
266{
267 Q_D(const QQuickMenuItem);
268 return d->subMenu;
269}
270
271void QQuickMenuItem::componentComplete()
272{
273 Q_D(QQuickMenuItem);
274 d->executeArrow(true);
275 QQuickAbstractButton::componentComplete();
276}
277
278QFont QQuickMenuItem::defaultFont() const
279{
280 return QQuickTheme::font(QQuickTheme::Menu);
281}
282
283qreal QQuickMenuItem::implicitTextPadding() const
284{
285 return d_func()->implicitTextPadding;
286}
287
288void QQuickMenuItem::setImplicitTextPadding(qreal newImplicitTextPadding)
289{
290 Q_D(QQuickMenuItem);
291 if (qFuzzyCompare(d->implicitTextPadding, newImplicitTextPadding))
292 return;
293 d->implicitTextPadding = newImplicitTextPadding;
294 emit implicitTextPaddingChanged();
295}
296
297qreal QQuickMenuItem::textPadding() const
298{
299 Q_D(const QQuickMenuItem);
300 return d->menu ? QQuickMenuPrivate::get(d->menu)->textPadding : 0;
301}
302
303#if QT_CONFIG(accessibility)
304QAccessible::Role QQuickMenuItem::accessibleRole() const
305{
306 return QAccessible::MenuItem;
307}
308#endif
309
310#ifndef QT_NO_DEBUG_STREAM
311QDebug operator<<(QDebug debug, const QQuickMenuItem *menuItem)
312{
313 QDebugStateSaver saver(debug);
314 debug.nospace();
315 if (!menuItem) {
316 debug << "QQuickMenuItem(nullptr)";
317 return debug;
318 }
319
320 debug << menuItem->metaObject()->className() << '(' << static_cast<const void *>(menuItem);
321 if (!menuItem->objectName().isEmpty())
322 debug << ", name=" << menuItem->objectName();
323 debug << ", text=" << menuItem->text();
324 debug << ')';
325 return debug;
326}
327#endif // QT_NO_DEBUG_STREAM
328
329QT_END_NAMESPACE
330
331#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
static QString arrowName()
QDebug operator<<(QDebug debug, const QQuickMenuItem *menuItem)