Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquickmenubar.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 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
4#include "qquickmenubar_p.h"
5#include "qquickmenubar_p_p.h"
7#include "qquickmenu_p.h"
8#include "qquickmenu_p_p.h"
9
10#include <QtGui/private/qguiapplication_p.h>
11#include <QtGui/qpa/qplatformtheme.h>
12
13#include <QtQml/qqmlcontext.h>
14#include <QtQml/qqmlcomponent.h>
15#include <QtQml/qqmlengine.h>
16
18
23
50{
51 Q_Q(QQuickMenuBar);
52 if (!delegate)
53 return nullptr;
54
56 if (!context)
58
61 if (!item) {
62 delete object;
63 return nullptr;
64 }
65
66 if (QQuickMenuBarItem *menuBarItem = qobject_cast<QQuickMenuBarItem *>(item))
67 menuBarItem->setMenu(menu);
70
71 return item;
72}
73
75{
76 if (!delegate)
77 return;
78
80}
81
88
89void QQuickMenuBarPrivate::toggleCurrentMenu(bool visible, bool activate)
90{
91 if (!currentItem || visible == popupMode)
92 return;
93
95
96 triggering = true;
97 popupMode = visible;
98 if (menu)
99 menu->setVisible(visible);
100 if (!visible)
102 else if (menu && activate)
103 menu->setCurrentIndex(0);
104 triggering = false;
105}
106
108{
109 if (currentItem == item)
110 return;
111
112 if (currentItem) {
114 if (popupMode) {
116 menu->dismiss();
117 }
118 }
119
120 if (item) {
121 item->setHighlighted(true);
122 if (popupMode) {
123 if (QQuickMenu *menu = item->menu())
124 menu->open();
125 }
126 }
127
129}
130
132{
133 int index = currentItem ? contentModel->indexOf(currentItem, nullptr) : -1;
134 if (index >= contentModel->count() - 1)
135 index = -1;
136 activateItem(qobject_cast<QQuickMenuBarItem *>(itemAt(++index)));
137}
138
140{
142 if (index <= 0)
144 activateItem(qobject_cast<QQuickMenuBarItem *>(itemAt(--index)));
145}
146
148{
149 Q_Q(QQuickMenuBar);
150 QQuickMenuBarItem *item = qobject_cast<QQuickMenuBarItem *>(q->sender());
151 if (!item || item == currentItem || !item->isHovered() || !item->isEnabled() || QQuickMenuBarItemPrivate::get(item)->touchId != -1)
152 return;
153
155}
156
158{
159 Q_Q(QQuickMenuBar);
160 QQuickMenuBarItem *item = qobject_cast<QQuickMenuBarItem *>(q->sender());
161 if (!item)
162 return;
163
164 if (item == currentItem) {
166 } else {
167 popupMode = true;
169 }
170}
171
173{
175 return;
176
177 popupMode = false;
178 activateItem(nullptr);
179}
180
182{
183 Q_Q(const QQuickMenuBar);
184 const int count = contentModel->count();
185 qreal totalWidth = qMax(0, count - 1) * spacing;
186 for (int i = 0; i < count; ++i) {
187 QQuickItem *item = q->itemAt(i);
188 if (item)
189 totalWidth += item->implicitWidth();
190 }
191 return totalWidth;
192}
193
195{
196 Q_Q(const QQuickMenuBar);
197 const int count = contentModel->count();
198 qreal maxHeight = 0;
199 for (int i = 0; i < count; ++i) {
200 QQuickItem *item = q->itemAt(i);
201 if (item)
202 maxHeight = qMax(maxHeight, item->implicitHeight());
203 }
204 return maxHeight;
205}
206
213
220
221void QQuickMenuBarPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj)
222{
223 QQuickMenuBar *menuBar = static_cast<QQuickMenuBar *>(prop->object);
224 if (QQuickMenu *menu = qobject_cast<QQuickMenu *>(obj))
227}
228
229void QQuickMenuBarPrivate::menus_append(QQmlListProperty<QQuickMenu> *prop, QQuickMenu *obj)
230{
231 QQuickMenuBar *menuBar = static_cast<QQuickMenuBar *>(prop->object);
233}
234
235qsizetype QQuickMenuBarPrivate::menus_count(QQmlListProperty<QQuickMenu> *prop)
236{
237 QQuickMenuBar *menuBar = static_cast<QQuickMenuBar *>(prop->object);
238 return menuBar->count();
239}
240
241QQuickMenu *QQuickMenuBarPrivate::menus_at(QQmlListProperty<QQuickMenu> *prop, qsizetype index)
242{
243 QQuickMenuBar *menuBar = static_cast<QQuickMenuBar *>(prop->object);
244 return menuBar->menuAt(index);
245}
246
247void QQuickMenuBarPrivate::menus_clear(QQmlListProperty<QQuickMenu> *prop)
248{
249 QQuickMenuBar *menuBar = static_cast<QQuickMenuBar *>(prop->object);
250 QQuickMenuBarPrivate::get(menuBar)->contentModel->clear();
251}
252
257
266
276{
277 Q_D(const QQuickMenuBar);
278 return d->delegate;
279}
280
282{
283 Q_D(QQuickMenuBar);
284 if (d->delegate == delegate)
285 return;
286
287 d->delegate = delegate;
289}
290
297{
298 Q_D(const QQuickMenuBar);
299 QQuickMenuBarItem *item = qobject_cast<QQuickMenuBarItem *>(d->itemAt(index));
300 if (!item)
301 return nullptr;
302 return item->menu();
303}
304
311{
312 Q_D(QQuickMenuBar);
313 addItem(d->createItem(menu));
314}
315
322{
323 Q_D(QQuickMenuBar);
324 insertItem(index, d->createItem(menu));
325}
326
333{
334 Q_D(QQuickMenuBar);
335 if (!menu)
336 return;
337
338 const int count = d->contentModel->count();
339 for (int i = 0; i < count; ++i) {
340 QQuickMenuBarItem *item = qobject_cast<QQuickMenuBarItem *>(itemAt(i));
341 if (!item || item->menu() != menu)
342 continue;
343
345 break;
346 }
347
348 menu->deleteLater();
349}
350
359{
360 Q_D(QQuickMenuBar);
361 QQuickMenuBarItem *item = qobject_cast<QQuickMenuBarItem *>(itemAt(index));
362 if (!item)
363 return nullptr;
364
365 QQuickMenu *menu = item->menu();
366 if (!menu)
367 return nullptr;
368
369 d->removeItem(index, item);
370 item->deleteLater();
371 return menu;
372}
373
409QQmlListProperty<QQuickMenu> QQuickMenuBarPrivate::menus()
410{
411 Q_Q(QQuickMenuBar);
412 return QQmlListProperty<QQuickMenu>(q, nullptr,
417}
418
428
430{
431 Q_D(QQuickMenuBar);
432
433 if (d->altPressed) {
434 switch (event->type()) {
435 case QEvent::KeyRelease: {
436 const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);
437 if ((keyEvent->key() == Qt::Key_Alt || keyEvent->key() == Qt::Key_Meta)
438 && keyEvent->modifiers() == Qt::NoModifier) {
439 for (int i = 0; i < count(); ++i) {
440 if (auto *item = qobject_cast<QQuickMenuBarItem *>(d->itemAt(i))) {
441 d->activateItem(item);
443 setFocus(true);
444 break;
445 }
446 }
447 }
449 }
458 case QEvent::TouchEnd:
459 case QEvent::FocusIn:
460 case QEvent::FocusOut:
462 case QEvent::Shortcut:
463 d->altPressed = false;
464 qApp->removeEventFilter(this);
465 break;
466 default:
467 break;
468 }
469 } else if (isVisible() && event->type() == QEvent::ShortcutOverride) {
470 const bool altKeyNavigation = QGuiApplicationPrivate::platformTheme()
472 if (altKeyNavigation) {
473 const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);
474 if ((keyEvent->key() == Qt::Key_Alt || keyEvent->key() == Qt::Key_Meta)
475 && keyEvent->modifiers() == Qt::AltModifier) {
476 d->altPressed = true;
477 qApp->installEventFilter(this);
478 }
479 }
480 }
481 return QObject::eventFilter(object, event);
482}
483
485{
486 Q_D(QQuickMenuBar);
488
489 switch (event->key()) {
490 case Qt::Key_Up:
491 d->toggleCurrentMenu(false, false);
492 break;
493
494 case Qt::Key_Down:
495 d->toggleCurrentMenu(true, true);
496 break;
497
498 case Qt::Key_Left:
499 case Qt::Key_Right:
500 if (isMirrored() == (event->key() == Qt::Key_Left))
501 d->activateNextItem();
502 else
503 d->activatePreviousItem();
504 break;
505 // This is triggered when no popup is open but a menu bar item is highlighted and has focus.
506 case Qt::Key_Escape:
507 if (d->currentItem) {
508 d->activateItem(nullptr);
509 setFocus(false);
510 }
511 break;
512 default:
513#if QT_CONFIG(shortcut)
514 if (!event->text().isEmpty() && event->modifiers() == Qt::NoModifier) {
515 const QKeyCombination mnemonic(Qt::AltModifier, Qt::Key(event->key()));
516 for (int i = 0; i < count(); ++i) {
517 if (auto *item = qobject_cast<QQuickMenuBarItem *>(d->itemAt(i))) {
518 if (item->shortcut() == mnemonic) {
519 d->activateItem(item);
520 d->toggleCurrentMenu(true, true);
521 }
522 }
523 }
524 }
525#endif
526 break;
527 }
528}
529
531{
533
534 switch (event->key()) {
535 case Qt::Key_Up:
536 case Qt::Key_Down:
537 case Qt::Key_Left:
538 case Qt::Key_Right:
539 case Qt::Key_Escape:
540 event->accept();
541 break;
542
543 default:
544 event->ignore();
545 break;
546 }
547}
548
550{
551 Q_D(QQuickMenuBar);
553 if (!d->popupMode && d->currentItem)
554 d->activateItem(nullptr);
555}
556
558{
559 return qobject_cast<QQuickMenuBarItem *>(item);
560}
561
563{
564 Q_D(QQuickMenuBar);
566 switch (change) {
567 case ItemSceneChange:
568 if (d->windowContentItem)
569 d->windowContentItem->removeEventFilter(this);
570 if (value.window) {
571 d->windowContentItem = value.window->contentItem();
572 if (d->windowContentItem)
573 d->windowContentItem->installEventFilter(this);
574 }
575 break;
576 default:
577 break;
578 }
579}
580
582{
583 Q_D(QQuickMenuBar);
585 if (QQuickMenuBarItem *menuBarItem = qobject_cast<QQuickMenuBarItem *>(item)) {
586 QQuickMenuBarItemPrivate::get(menuBarItem)->setMenuBar(this);
589 if (QQuickMenu *menu = menuBarItem->menu())
591 }
592 d->updateImplicitContentSize();
594}
595
601
616
621
622#if QT_CONFIG(accessibility)
623QAccessible::Role QQuickMenuBar::accessibleRole() const
624{
625 return QAccessible::MenuBar;
626}
627#endif
628
630
631#include "moc_qquickmenubar_p.cpp"
\inmodule QtCore
Definition qcoreevent.h:45
@ TabletMove
Definition qcoreevent.h:121
@ ShortcutOverride
Definition qcoreevent.h:158
@ FocusOut
Definition qcoreevent.h:67
@ KeyRelease
Definition qcoreevent.h:65
@ MouseMove
Definition qcoreevent.h:63
@ FocusIn
Definition qcoreevent.h:66
@ ActivationChange
Definition qcoreevent.h:135
@ MouseButtonPress
Definition qcoreevent.h:60
@ TouchUpdate
Definition qcoreevent.h:242
@ TouchBegin
Definition qcoreevent.h:241
@ TabletRelease
Definition qcoreevent.h:127
@ TabletPress
Definition qcoreevent.h:126
@ MouseButtonRelease
Definition qcoreevent.h:61
\reentrant
Definition qfont.h:22
bool isEnabled() const
Returns true if the item is enabled; otherwise, false is returned.
void setParentItem(QGraphicsItem *parent)
Sets this item's parent item to newParent.
static QPlatformTheme * platformTheme()
\inmodule QtGui
Definition qevent.h:246
The QKeyEvent class describes a key event.
Definition qevent.h:424
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifier flags that existed immediately after the event occurred.
Definition qevent.cpp:1468
int key() const
Returns the code of the key that was pressed or released.
Definition qevent.h:434
QAction * addMenu(QMenu *menu)
Appends menu to the menu bar.
Definition qmenubar.cpp:768
static QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot, Qt::ConnectionType type=Qt::AutoConnection)
Definition qobject_p.h:299
static bool disconnect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot)
Definition qobject_p.h:328
\inmodule QtCore
Definition qobject.h:103
virtual bool eventFilter(QObject *watched, QEvent *event)
Filters events if this object has been installed as an event filter for the watched object.
Definition qobject.cpp:1555
void deleteLater()
\threadsafe
Definition qobject.cpp:2435
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
The QQmlComponent class encapsulates a QML component definition.
virtual QObject * beginCreate(QQmlContext *)
Create an object instance from this component, within the specified context.
virtual void completeCreate()
This method provides advanced control over component instance creation.
QQmlContext * creationContext() const
Returns the QQmlContext the component was created in.
The QQmlContext class defines a context within a QML engine.
Definition qqmlcontext.h:25
int count() const override
\qmlproperty int QtQml.Models::ObjectModel::count
int indexOf(QObject *object, QObject *objectContext) const override
static void contentData_append(QQmlListProperty< QObject > *prop, QObject *obj)
static QObject * contentData_at(QQmlListProperty< QObject > *prop, qsizetype index)
static qsizetype contentData_count(QQmlListProperty< QObject > *prop)
QQuickItem * itemAt(int index) const
static void contentData_clear(QQmlListProperty< QObject > *prop)
QQmlObjectModel * contentModel
virtual void itemMoved(int index, QQuickItem *item)
Q_INVOKABLE void addItem(QQuickItem *item)
\qmlmethod void QtQuick.Controls::Container::addItem(Item item)
virtual void itemAdded(int index, QQuickItem *item)
Q_INVOKABLE void removeItem(QQuickItem *item)
virtual void itemRemoved(int index, QQuickItem *item)
Q_INVOKABLE QQuickItem * itemAt(int index) const
\qmlmethod Item QtQuick.Controls::Container::itemAt(int index)
void itemChange(ItemChange change, const ItemChangeData &data) override
Called when change occurs for this item.
Q_INVOKABLE void insertItem(int index, QQuickItem *item)
\qmlmethod void QtQuick.Controls::Container::insertItem(int index, Item item)
QQuickDeferredPointer< QQuickItem > contentItem
void setFocusReason(Qt::FocusReason reason)
void hoveredChanged()
bool isMirrored() const
\qmlproperty bool QtQuick.Controls::Control::mirrored \readonly
virtual void itemImplicitWidthChanged(QQuickItem *)
virtual void itemImplicitHeightChanged(QQuickItem *)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
void setFocus(bool)
void setFlag(Flag flag, bool enabled=true)
Enables the specified flag for this item if enabled is true; if enabled is false, the flag is disable...
bool isVisible() const
Q_INVOKABLE void forceActiveFocus()
\qmlmethod point QtQuick::Item::mapToItem(Item item, real x, real y) \qmlmethod point QtQuick::Item::...
virtual void keyReleaseEvent(QKeyEvent *event)
This event handler can be reimplemented in a subclass to receive key release events for an item.
ItemChange
Used in conjunction with QQuickItem::itemChange() to notify the item about certain types of changes.
Definition qquickitem.h:144
void setFocusPolicy(Qt::FocusPolicy policy)
Sets the focus policy of this item to policy.
virtual void hoverLeaveEvent(QHoverEvent *event)
This event handler can be reimplemented in a subclass to receive hover-leave events for an item.
static QQuickMenuBarItemPrivate * get(QQuickMenuBarItem *item)
bool isHighlighted() const
\qmlproperty bool QtQuick.Controls::MenuBarItem::highlighted
void setHighlighted(bool highlighted)
static void menus_append(QQmlListProperty< QQuickMenu > *prop, QQuickMenu *obj)
QQmlListProperty< QQuickMenu > menus()
\qmlproperty list<Menu> QtQuick.Controls::MenuBar::menus
qreal getContentWidth() const override
QPalette defaultPalette() const override
QPointer< QQuickMenuBarItem > currentItem
QQuickItem * createItem(QQuickMenu *menu)
void toggleCurrentMenu(bool visible, bool activate)
static QQuickMenuBarPrivate * get(QQuickMenuBar *menuBar)
void itemImplicitWidthChanged(QQuickItem *item) override
QQuickItem * beginCreateItem(QQuickMenu *menu)
Provides a window menu bar.
static void contentData_append(QQmlListProperty< QObject > *prop, QObject *obj)
QQmlListProperty< QObject > contentData()
static QQuickMenu * menus_at(QQmlListProperty< QQuickMenu > *prop, qsizetype index)
void activateItem(QQuickMenuBarItem *item)
QQmlComponent * delegate
qreal getContentHeight() const override
void itemImplicitHeightChanged(QQuickItem *item) override
static void menus_clear(QQmlListProperty< QQuickMenu > *prop)
static qsizetype menus_count(QQmlListProperty< QQuickMenu > *prop)
void hoverLeaveEvent(QHoverEvent *event) override
This event handler can be reimplemented in a subclass to receive hover-leave events for an item.
Q_INVOKABLE void insertMenu(int index, QQuickMenu *menu)
\qmlmethod void QtQuick.Controls::MenuBar::insertMenu(int index, Menu menu)
bool isContent(QQuickItem *item) const override
void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override
Called when change occurs for this item.
void itemAdded(int index, QQuickItem *item) override
bool eventFilter(QObject *object, QEvent *event) override
Filters events if this object has been installed as an event filter for the watched object.
Q_INVOKABLE QQuickMenu * menuAt(int index) const
\qmlmethod Menu QtQuick.Controls::MenuBar::menuAt(int index)
void delegateChanged()
Q_INVOKABLE QQuickMenu * takeMenu(int index)
\qmlmethod Menu QtQuick.Controls::MenuBar::takeMenu(int index)
void itemMoved(int index, QQuickItem *item) override
void keyReleaseEvent(QKeyEvent *event) override
This event handler can be reimplemented in a subclass to receive key release events for an item.
Q_INVOKABLE void addMenu(QQuickMenu *menu)
\qmlmethod void QtQuick.Controls::MenuBar::addMenu(Menu menu)
void setDelegate(QQmlComponent *delegate)
Q_INVOKABLE void removeMenu(QQuickMenu *menu)
\qmlmethod void QtQuick.Controls::MenuBar::removeMenu(Menu menu)
QQmlComponent * delegate
void keyPressEvent(QKeyEvent *event) override
This event handler can be reimplemented in a subclass to receive key press events for an item.
void menusChanged()
void itemRemoved(int index, QQuickItem *item) override
QFont defaultFont() const override
QQuickMenuBar(QQuickItem *parent=nullptr)
void aboutToHide()
static QPalette palette(Scope scope)
static QFont font(Scope scope)
virtual void setVisible(bool visible)
Definition qwidget.cpp:8255
Combined button and popup list for selecting options.
@ ClickFocus
Definition qnamespace.h:109
@ Key_Escape
Definition qnamespace.h:663
@ Key_Right
Definition qnamespace.h:679
@ Key_Left
Definition qnamespace.h:677
@ Key_Alt
Definition qnamespace.h:686
@ Key_Up
Definition qnamespace.h:678
@ Key_Down
Definition qnamespace.h:680
@ Key_Meta
Definition qnamespace.h:685
@ NoModifier
@ AltModifier
@ MenuBarFocusReason
static void * context
#define Q_FALLTHROUGH()
#define qApp
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLuint index
[2]
GLenum GLenum GLsizei count
GLuint object
[3]
struct _cl_event * event
GLhandleARB obj
[2]
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:75
void QQml_setParent_noEvent(QObject *object, QObject *parent)
Makes the object a child of parent.
QQuickItem * qobject_cast< QQuickItem * >(QObject *o)
Definition qquickitem.h:492
#define emit
ptrdiff_t qsizetype
Definition qtypes.h:165
double qreal
Definition qtypes.h:187
QGraphicsItem * item
QMenu menu
[5]
QMenuBar * menuBar
[0]
\inmodule QtQuick
Definition qquickitem.h:159