92 int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q);
93 QRect result = q->rect();
94 result.adjust(hmargin, 0, -hmargin, 0);
97 if (q->isRightToLeft())
98 result.setLeft(result.left() +
extension->sizeHint().width());
100 result.setWidth(result.width() -
extension->sizeHint().width());
103 if (leftWidget && leftWidget->isVisible()) {
104 QSize sz = leftWidget->sizeHint();
105 if (q->isRightToLeft())
106 result.setRight(result.right() - sz.width());
108 result.setLeft(result.left() + sz.width());
111 if (rightWidget && rightWidget->isVisible()) {
112 QSize sz = rightWidget->sizeHint();
113 if (q->isRightToLeft())
114 result.setLeft(result.left() + sz.width());
116 result.setRight(result.right() - sz.width());
132 int q_width = q->width()-(q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q)*2);
134 if (leftWidget || rightWidget) {
135 int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr, q)
136 + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q);
137 int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin,
nullptr, q)
138 + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q);
139 if (leftWidget && leftWidget->isVisible()) {
140 QSize sz = leftWidget->sizeHint();
141 q_width -= sz.width();
142 q_start = sz.width();
143 QPoint pos(hmargin, (q->height() - leftWidget->height()) / 2);
144 QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz));
145 leftWidget->setGeometry(vRect);
147 if (rightWidget && rightWidget->isVisible()) {
148 QSize sz = rightWidget->sizeHint();
149 q_width -= sz.width();
150 QPoint pos(q->width() - sz.width() - hmargin, vmargin);
151 QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz));
152 rightWidget->setGeometry(vRect);
157 if (q->isNativeMenuBar()) {
163 currentAction =
nullptr;
164#ifndef QT_NO_SHORTCUT
166 for(
int j = 0; j < shortcutIndexMap.size(); ++j)
167 q->releaseShortcut(shortcutIndexMap.value(j));
168 shortcutIndexMap.clear();
169 const int actionsCount = actions.size();
170 shortcutIndexMap.reserve(actionsCount);
171 for (
int i = 0; i < actionsCount; i++)
172 shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text())));
177 hiddenActions.clear();
179 QRect menuRect =
this->menuRect(
false);
182 bool hasHiddenActions =
false;
183 for (
int i = 0; i < actions.size(); ++i) {
184 const QRect &rect = actionRects.at(i);
185 if (rect.isValid() && !menuRect.contains(rect)) {
186 hasHiddenActions =
true;
192 if (hasHiddenActions) {
193 menuRect =
this->menuRect(
true);
194 for (
int i = 0; i < actions.size(); ++i) {
195 const QRect &rect = actionRects.at(i);
196 if (rect.isValid() && !menuRect.contains(rect)) {
197 hiddenActions.append(actions.at(i));
202 if (hiddenActions.size() > 0) {
209 pop->addActions(hiddenActions);
211 int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr, q);
212 int x = q->isRightToLeft()
213 ? menuRect.left() - extension->sizeHint().width() + 1
215 extension->setGeometry(x, vmargin,
extension->sizeHint().width(), menuRect.height() - vmargin*2);
250 if (b && !q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation,
nullptr, q)) {
256 QWidget *fw = QApplication::focusWidget();
257 if (fw && fw != q && fw->window() != QApplication::activePopupWidget())
258 keyboardFocusWidget = fw;
260 q->setFocus(Qt::MenuBarFocusReason);
264 if (keyboardFocusWidget) {
265 if (QApplication::focusWidget() == q)
266 keyboardFocusWidget->setFocus(Qt::MenuBarFocusReason);
267 keyboardFocusWidget =
nullptr;
276 if (!action || !action->menu() || closePopupMode)
279 if (action->isEnabled() && action->menu()->isEnabled()) {
281 activeMenu = action->menu();
282 auto *activeMenuPriv = activeMenu->d_func();
283 activeMenuPriv->causedPopup.widget = q;
284 activeMenuPriv->causedPopup.action = action;
286 QRect adjustedActionRect = actionRect(action);
287 QPoint popupPos = adjustedActionRect.bottomLeft() + QPoint(0, 1);
290 QScreen *menubarScreen = q->window()->windowHandle()->screen();
291 QPoint screenTestPos = q->mapToGlobal(popupPos + QPoint(adjustedActionRect.width() / 2, 0));
292 QPointer<QScreen> popupScreen = menubarScreen->virtualSiblingAt(screenTestPos);
294 popupScreen = menubarScreen;
295 std::swap(popupScreen, activeMenuPriv->popupScreen);
296 const QSize popup_size = activeMenu->sizeHint();
297 std::swap(popupScreen, activeMenuPriv->popupScreen);
302 QPoint pos(q->mapToGlobal(popupPos).x(), screenTestPos.y());
304 QRect screenRect = popupScreen->geometry();
305 pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y()));
306 const bool fitUp = (pos.y() - popup_size.height() >= screenRect.top());
307 const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom());
308 const bool rtl = q->isRightToLeft();
309 const int actionWidth = adjustedActionRect.width();
311 if (!fitUp && !fitDown) {
312 bool shouldShiftToRight = !rtl;
313 if (rtl && popup_size.width() > pos.x())
314 shouldShiftToRight =
true;
315 else if (actionWidth + popup_size.width() + pos.x() > screenRect.right())
316 shouldShiftToRight =
false;
318 if (shouldShiftToRight) {
319 pos.rx() += actionWidth + (rtl ? popup_size.width() : 0);
323 pos.rx() -= popup_size.width();
326 pos.rx() += actionWidth;
329 if (!defaultPopDown || (fitUp && !fitDown))
330 pos.setY(qMax(screenRect.y(), q->mapToGlobal(QPoint(0, adjustedActionRect.top()-popup_size.height())).y()));
331 QMenuPrivate::get(activeMenu)->topData()->initialScreen = popupScreen;
332 activeMenu->popup(pos);
334 activeMenu->d_func()->setFirstActionActive();
336 q->update(actionRect(action));
341 if (currentAction == action && popup == popupState)
344 autoReleaseTimer.stop();
346 doChildEffects = (popup && !activeMenu);
349 if (QMenu *menu = activeMenu) {
350 activeMenu =
nullptr;
351 hoverAction =
nullptr;
353 fw = q->window()->focusWidget();
354 q->setFocus(Qt::NoFocusReason);
360 q->update(actionRect(currentAction));
363#if QT_CONFIG(statustip)
364 QAction *previousAction = currentAction;
366 currentAction = action;
367 if (action && action->isEnabled()) {
368 activateAction(action, QAction::Hover);
371 q->update(actionRect(action));
372#if QT_CONFIG(statustip)
373 }
else if (previousAction) {
375 QStatusTipEvent tip(empty);
376 QCoreApplication::sendEvent(q, &tip);
380 fw->setFocus(Qt::NoFocusReason);
391 actionRects.resize(actions.size());
392 actionRects.fill(QRect());
394 const QStyle *style = q->style();
396 const int itemSpacing = style->pixelMetric(QStyle::PM_MenuBarItemSpacing,
nullptr, q);
397 int max_item_height = 0, separator = -1, separator_start = 0, separator_len = 0;
400 const QFontMetrics fm = q->fontMetrics();
401 const int hmargin = style->pixelMetric(QStyle::PM_MenuBarHMargin,
nullptr, q),
402 vmargin = style->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr, q),
403 icone = style->pixelMetric(QStyle::PM_SmallIconSize,
nullptr, q);
404 for(
int i = 0; i < actions.size(); i++) {
405 QAction *action = actions.at(i);
406 if (!action->isVisible())
412 if (action->isSeparator()) {
413 if (style->styleHint(QStyle::SH_DrawMenuBarSeparator,
nullptr, q))
417 const QString s = action->text();
418 QIcon is = action->icon();
421 sz = sz.expandedTo(QSize(icone, icone));
422 else if (!s.isEmpty())
423 sz = fm.size(Qt::TextShowMnemonic, s);
427 QStyleOptionMenuItemV2 opt;
428 q->initStyleOption(&opt, action);
429 sz = q->style()->sizeFromContents(QStyle::CT_MenuBarItem, &opt, sz, q);
433 int iWidth = sz.width() + itemSpacing;
435 separator_start += iWidth;
437 separator_len += iWidth;
440 max_item_height = qMax(max_item_height, sz.height());
442 actionRects[i] = QRect(0, 0, sz.width(), sz.height());
447 const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr, q);
448 int x = fw + ((start == -1) ? hmargin : start) + itemSpacing;
449 int y = fw + vmargin;
450 for(
int i = 0; i < actions.size(); i++) {
451 QRect &rect = actionRects[i];
456 rect.setHeight(max_item_height);
459 if (separator != -1 && i >= separator) {
460 int left = (max_width - separator_len - hmargin - itemSpacing) + (x - separator_start - hmargin);
461 if (left < separator_start) {
462 separator_start = x = hmargin;
463 y += max_item_height;
472 x += rect.width() + itemSpacing;
475 rect = QStyle::visualRect(q->layoutDirection(), q->rect(), rect);
506 if (QAction *action = qobject_cast<QAction *>(q->sender())) {
507 emit q->hovered(action);
508#if QT_CONFIG(accessibility)
509 if (QAccessible::isActive()) {
510 int actionIndex = actions.indexOf(action);
511 QAccessibleEvent focusEvent(q, QAccessible::Focus);
512 focusEvent.setChild(actionIndex);
513 QAccessible::updateAccessibility(&focusEvent);
526void QMenuBar::initStyleOption(QStyleOptionMenuItem *option,
const QAction *action)
const
528 if (!option || !action)
531 option->palette = palette();
532 option->state = QStyle::State_None;
533 if (isEnabled() && action->isEnabled())
534 option->state |= QStyle::State_Enabled;
536 option->palette.setCurrentColorGroup(QPalette::Disabled);
537 option->fontMetrics = fontMetrics();
538 if (d->currentAction && d->currentAction == action) {
539 option->state |= QStyle::State_Selected;
540 if (d->popupState && !d->closePopupMode)
541 option->state |= QStyle::State_Sunken;
543 if (hasFocus() || d->currentAction)
544 option->state |= QStyle::State_HasFocus;
545 if (d->hoverAction == action) {
546 if (
auto optionV2 = qstyleoption_cast<QStyleOptionMenuItemV2 *>(option))
547 optionV2->mouseDown = d->mouseDown;
548 option->state |= QStyle::State_MouseOver;
550 option->menuRect = rect();
551 option->menuItemType = QStyleOptionMenuItem::Normal;
552 option->checkType = QStyleOptionMenuItem::NotCheckable;
553 option->text = action->text();
554 option->icon = action->icon();
677 q->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
678 q->setAttribute(Qt::WA_CustomWhatsThis);
680 if (!QCoreApplication::testAttribute(Qt::AA_DontUseNativeMenuBar))
681 platformMenuBar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar();
685 q->setBackgroundRole(QPalette::Button);
687 q->setMouseTracking(q->style()->styleHint(QStyle::SH_MenuBar_MouseTracking,
nullptr, q));
689 extension =
new QMenuBarExtension(q);
690 extension->setFocusPolicy(Qt::NoFocus);
897void QMenuBar::paintEvent(QPaintEvent *e)
901 QRegion emptyArea(rect());
904 for (
int i = 0; i < d->actions.size(); ++i) {
905 QAction *action = d->actions.at(i);
906 QRect adjustedActionRect = d->actionRect(action);
907 if (adjustedActionRect.isEmpty() || !d->isVisible(action))
909 if (!e->rect().intersects(adjustedActionRect))
912 emptyArea -= adjustedActionRect;
913 QStyleOptionMenuItemV2 opt;
914 initStyleOption(&opt, action);
915 opt.rect = adjustedActionRect;
916 p.setClipRect(adjustedActionRect);
917 style()->drawControl(QStyle::CE_MenuBarItem, &opt, &p,
this);
920 if (
int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr,
this)) {
922 borderReg += QRect(0, 0, fw, height());
923 borderReg += QRect(width()-fw, 0, fw, height());
924 borderReg += QRect(0, 0, width(), fw);
925 borderReg += QRect(0, height()-fw, width(), fw);
926 p.setClipRegion(borderReg);
927 emptyArea -= borderReg;
928 QStyleOptionFrame frame;
930 frame.palette = palette();
931 frame.state = QStyle::State_None;
932 frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, &frame,
this);
933 frame.midLineWidth = 0;
934 style()->drawPrimitive(QStyle::PE_PanelMenuBar, &frame, &p,
this);
936 p.setClipRegion(emptyArea);
937 QStyleOptionMenuItem menuOpt;
938 menuOpt.palette = palette();
939 menuOpt.state = QStyle::State_None;
940 menuOpt.menuItemType = QStyleOptionMenuItem::EmptyArea;
941 menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
942 menuOpt.rect = rect();
943 menuOpt.menuRect = rect();
944 style()->drawControl(QStyle::CE_MenuBarEmptyArea, &menuOpt, &p,
this);
963void QMenuBar::mousePressEvent(QMouseEvent *e)
966 if (e->button() != Qt::LeftButton)
971 QAction *action = d->actionAt(e->position().toPoint());
972 if (!action || !d->isVisible(action) || !action->isEnabled()) {
973 d->setCurrentAction(
nullptr);
974#if QT_CONFIG(whatsthis)
975 if (QWhatsThis::inWhatsThisMode())
976 QWhatsThis::showText(e->globalPosition().toPoint(), d->whatsThis,
this);
981 if (d->currentAction == action && d->popupState) {
982 if (QMenu *menu = d->activeMenu) {
983 d->activeMenu =
nullptr;
984 menu->setAttribute(Qt::WA_NoMouseReplay);
989 d->setCurrentAction(action,
true);
991 d->hoverAction = action;
992 update(d->actionRect(d->hoverAction));
998void QMenuBar::mouseReleaseEvent(QMouseEvent *e)
1001 if (e->button() != Qt::LeftButton)
1006 d->mouseDown =
false;
1007 QAction *action = d->actionAt(e->position().toPoint());
1010 if (!d->isVisible(action))
1012 if ((d->closePopupMode && action == d->currentAction) || !action || !action->menu()) {
1015 d->setCurrentAction(action,
false);
1017 d->activateAction(action, QAction::Trigger);
1019 d->closePopupMode = 0;
1020 d->hoverAction = action;
1021 update(d->actionRect(d->hoverAction));
1027void QMenuBar::keyPressEvent(QKeyEvent *e)
1030 d->updateGeometries();
1032 if (isRightToLeft()) {
1033 if (key == Qt::Key_Left)
1034 key = Qt::Key_Right;
1035 else if (key == Qt::Key_Right)
1038 if (key == Qt::Key_Tab)
1039 key = Qt::Key_Right;
1040 else if (key == Qt::Key_Backtab)
1043 bool key_consumed =
false;
1049 case Qt::Key_Return: {
1050 if (!style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation,
nullptr,
this) || !d->currentAction)
1052 if (d->currentAction->menu()) {
1053 d->popupAction(d->currentAction,
true);
1054 }
else if (key == Qt::Key_Enter || key == Qt::Key_Return || key == Qt::Key_Space) {
1055 d->activateAction(d->currentAction, QAction::Trigger);
1056 d->setCurrentAction(d->currentAction,
false);
1057 d->setKeyboardMode(
false);
1059 key_consumed =
true;
1063 case Qt::Key_Left: {
1064 if (d->currentAction) {
1065 int index = d->actions.indexOf(d->currentAction);
1066 if (QAction *nextAction = d->getNextAction(index, key == Qt::Key_Left ? -1 : +1)) {
1067 d->setCurrentAction(nextAction, d->popupState,
true);
1068 key_consumed =
true;
1074 key_consumed =
false;
1077#ifndef QT_NO_SHORTCUT
1078 if (!key_consumed && e->matches(QKeySequence::Cancel)) {
1079 d->setCurrentAction(
nullptr);
1080 d->setKeyboardMode(
false);
1081 key_consumed =
true;
1085 if (!key_consumed &&
1087 (e->modifiers()&(Qt::MetaModifier|Qt::AltModifier))) && e->text().size()==1 && !d->popupState) {
1089 QAction *first =
nullptr, *currentSelected =
nullptr, *firstAfterCurrent =
nullptr;
1091 const QChar c = e->text().at(0).toUpper();
1092 for(
int i = 0; i < d->actions.size(); ++i) {
1093 if (d->actionRects.at(i).isNull())
1095 QAction *act = d->actions.at(i);
1096 QString s = act->text();
1098 qsizetype ampersand = s.indexOf(u'&');
1099 if (ampersand >= 0) {
1100 if (s[ampersand+1].toUpper() == c) {
1104 if (act == d->currentAction)
1105 currentSelected = act;
1106 else if (!firstAfterCurrent && currentSelected)
1107 firstAfterCurrent = act;
1113 QAction *next_action =
nullptr;
1114 if (clashCount >= 1) {
1115 if (clashCount == 1 || !d->currentAction || (currentSelected && !firstAfterCurrent))
1116 next_action = first;
1118 next_action = firstAfterCurrent;
1121 key_consumed =
true;
1122 d->setCurrentAction(next_action,
true,
true);
1134void QMenuBar::mouseMoveEvent(QMouseEvent *e)
1137 if (!(e->buttons() & Qt::LeftButton)) {
1138 d->mouseDown =
false;
1142 if (e->source() != Qt::MouseEventNotSynthesized)
1146 bool popupState = d->popupState || d->mouseDown;
1147 QAction *action = d->actionAt(e->position().toPoint());
1148 QAction *oldHoverAction = d->hoverAction;
1149 if ((action && d->isVisible(action)) || !popupState)
1150 d->setCurrentAction(action, popupState);
1151 if (oldHoverAction != action)
1152 update(d->actionRect(oldHoverAction));
1153 d->hoverAction = action;
1210void QMenuBar::actionEvent(QActionEvent *e)
1213 d->itemsDirty =
true;
1215 if (d->platformMenuBar) {
1216 QPlatformMenuBar *nativeMenuBar = d->platformMenuBar;
1220 auto action =
static_cast<QAction *>(e->action());
1221 if (e->type() == QEvent::ActionAdded) {
1222 QPlatformMenu *menu = d->getPlatformMenu(action);
1224 d->copyActionToPlatformMenu(action, menu);
1226 QPlatformMenu *beforeMenu = d->findInsertionPlatformMenu(action);
1227 d->platformMenuBar->insertMenu(menu, beforeMenu);
1229 }
else if (e->type() == QEvent::ActionRemoved) {
1230 QPlatformMenu *menu = d->getPlatformMenu(action);
1232 d->platformMenuBar->removeMenu(menu);
1233 }
else if (e->type() == QEvent::ActionChanged) {
1234 QPlatformMenu *cur = d->platformMenuBar->menuForTag(
reinterpret_cast<quintptr>(e->action()));
1235 QPlatformMenu *menu = d->getPlatformMenu(action);
1241 d->platformMenuBar->removeMenu(cur);
1243 d->copyActionToPlatformMenu(action, menu);
1245 QPlatformMenu *beforeMenu = d->findInsertionPlatformMenu(action);
1246 d->platformMenuBar->insertMenu(menu, beforeMenu);
1249 d->copyActionToPlatformMenu(action, menu);
1250 d->platformMenuBar->syncMenu(menu);
1255 if (e->type() == QEvent::ActionAdded) {
1256 connect(e->action(), SIGNAL(triggered()),
this, SLOT(_q_actionTriggered()));
1257 connect(e->action(), SIGNAL(hovered()),
this, SLOT(_q_actionHovered()));
1258 }
else if (e->type() == QEvent::ActionRemoved) {
1259 e->action()->disconnect(
this);
1263 if (isVisible() || isNativeMenuBar())
1264 d->updateGeometries();
1308 QWidget *newParent = q->parentWidget();
1313 QWidget *newWindow = newParent ? newParent->window() :
nullptr;
1315 QList<QPointer<QWidget>> newParents;
1322 const auto copy = oldParents;
1323 for (
const QPointer<QWidget> &w : copy) {
1325 if (newParent == w) {
1326 newParents.append(w);
1327 if (newParent != newWindow)
1328 newParent = newParent->parentWidget();
1330 w->removeEventFilter(q);
1336 while (newParent && newParent != newWindow) {
1338 newParents.append(newParent);
1339 newParent->installEventFilter(q);
1340 newParent = newParent->parentWidget();
1343 if (newParent && newWindow) {
1345 newParents.append(newParent);
1346 newParent->installEventFilter(q);
1348 oldParents = newParents;
1355 newWindow->createWinId();
1366void QMenuBar::changeEvent(QEvent *e)
1369 if (e->type() == QEvent::StyleChange) {
1370 d->itemsDirty =
true;
1371 setMouseTracking(style()->styleHint(QStyle::SH_MenuBar_MouseTracking,
nullptr,
this));
1373 resize(parentWidget()->width(), heightForWidth(parentWidget()->width()));
1374 d->updateGeometries();
1375 }
else if (e->type() == QEvent::ParentChange) {
1376 d->handleReparent();
1377 }
else if (e->type() == QEvent::FontChange
1378 || e->type() == QEvent::ApplicationFontChange) {
1379 d->itemsDirty =
true;
1380 d->updateGeometries();
1383 QWidget::changeEvent(e);
1389bool QMenuBar::event(QEvent *e)
1392 switch (e->type()) {
1393 case QEvent::KeyPress: {
1394 QKeyEvent *ke =
static_cast<QKeyEvent *>(e);
1396 if (!d->keyboardState) {
1397 d->setCurrentAction(0);
1401 if (ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab) {
1407#ifndef QT_NO_SHORTCUT
1408 case QEvent::Shortcut: {
1409 QShortcutEvent *se =
static_cast<QShortcutEvent *>(e);
1410 int shortcutId = se->shortcutId();
1411 for(
int j = 0; j < d->shortcutIndexMap.size(); ++j) {
1412 if (shortcutId == d->shortcutIndexMap.value(j))
1413 d->_q_internalShortcutActivated(j);
1418 d->_q_updateLayout();
1420#ifndef QT_NO_SHORTCUT
1421 case QEvent::ShortcutOverride: {
1422 QKeyEvent *kev =
static_cast<QKeyEvent *>(e);
1424 if (kev->matches(QKeySequence::Cancel) && d->currentAction) {
1431#if QT_CONFIG(whatsthis)
1432 case QEvent::QueryWhatsThis:
1433 e->setAccepted(d->whatsThis.size());
1434 if (QAction *action = d->actionAt(
static_cast<QHelpEvent*>(e)->pos())) {
1435 if (action->whatsThis().size() || action->menu())
1440 case QEvent::LayoutDirectionChange:
1441 d->_q_updateLayout();
1446 return QWidget::event(e);
1452bool QMenuBar::eventFilter(QObject *object, QEvent *event)
1455 if (object && (event->type() == QEvent::ParentChange))
1456 d->handleReparent();
1458 if (object == d->leftWidget || object == d->rightWidget) {
1459 switch (event->type()) {
1460 case QEvent::ShowToParent:
1461 case QEvent::HideToParent:
1462 d->_q_updateLayout();
1469 if (isNativeMenuBar() && event->type() == QEvent::ShowToParent) {
1474 QWidget *widget = qobject_cast<QWidget *>(object);
1475 QWindow *handle = widget ? widget->windowHandle() :
nullptr;
1476 if (handle !=
nullptr)
1477 d->platformMenuBar->handleReparent(handle);
1480 if (style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation,
nullptr,
this)) {
1481 if (d->altPressed) {
1482 switch (event->type()) {
1483 case QEvent::KeyPress:
1484 case QEvent::KeyRelease:
1486 QKeyEvent *kev =
static_cast<QKeyEvent*>(event);
1487 if (kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta) {
1488 if (event->type() == QEvent::KeyPress)
1490 d->setKeyboardMode(!d->keyboardState);
1494 case QEvent::MouseButtonPress:
1495 case QEvent::MouseButtonRelease:
1496 case QEvent::MouseMove:
1497 case QEvent::FocusIn:
1498 case QEvent::FocusOut:
1499 case QEvent::ActivationChange:
1500 case QEvent::Shortcut:
1501 d->altPressed =
false;
1502 qApp->removeEventFilter(
this);
1507 }
else if (isVisible()) {
1508 if (event->type() == QEvent::ShortcutOverride) {
1509 QKeyEvent *kev =
static_cast<QKeyEvent*>(event);
1510 if ((kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta)
1511 && kev->modifiers() == Qt::AltModifier) {
1512 d->altPressed =
true;
1513 qApp->installEventFilter(
this);
1548QSize QMenuBar::minimumSizeHint()
const
1550 Q_D(
const QMenuBar);
1551 const bool as_gui_menubar = !isNativeMenuBar();
1555 const_cast<QMenuBarPrivate*>(d)->updateGeometries();
1556 const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin,
nullptr,
this);
1557 const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr,
this);
1558 int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr,
this);
1559 int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar,
nullptr,
this);
1560 if (as_gui_menubar) {
1561 int w = parentWidget() ? parentWidget()->width() : QGuiApplication::primaryScreen()->virtualGeometry().width();
1562 d->calcActionRects(w - (2 * fw), 0);
1563 for (
int i = 0; ret.isNull() && i < d->actions.size(); ++i)
1564 ret = d->actionRects.at(i).size();
1565 if (!d->extension->isHidden())
1566 ret += QSize(d->extension->sizeHint().width(), 0);
1567 ret += QSize(2*fw + hmargin, 2*fw + vmargin);
1569 int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
1570 if (d->leftWidget) {
1571 QSize sz = d->leftWidget->minimumSizeHint();
1572 ret.setWidth(ret.width() + sz.width());
1573 if (sz.height() + margin > ret.height())
1574 ret.setHeight(sz.height() + margin);
1576 if (d->rightWidget) {
1577 QSize sz = d->rightWidget->minimumSizeHint();
1578 ret.setWidth(ret.width() + sz.width());
1579 if (sz.height() + margin > ret.height())
1580 ret.setHeight(sz.height() + margin);
1582 if (as_gui_menubar) {
1583 QStyleOptionMenuItem opt;
1585 opt.menuRect = rect();
1586 opt.state = QStyle::State_None;
1587 opt.menuItemType = QStyleOptionMenuItem::Normal;
1588 opt.checkType = QStyleOptionMenuItem::NotCheckable;
1589 opt.palette = palette();
1590 return style()->sizeFromContents(QStyle::CT_MenuBar, &opt, ret,
this);
1598QSize QMenuBar::sizeHint()
const
1600 Q_D(
const QMenuBar);
1601 const bool as_gui_menubar = !isNativeMenuBar();
1605 const_cast<QMenuBarPrivate*>(d)->updateGeometries();
1606 const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin,
nullptr,
this);
1607 const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr,
this);
1608 int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr,
this);
1609 int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar,
nullptr,
this);
1610 if (as_gui_menubar) {
1611 const int w = parentWidget() ? parentWidget()->width() : QGuiApplication::primaryScreen()->virtualGeometry().width();
1612 d->calcActionRects(w - (2 * fw), 0);
1613 for (
int i = 0; i < d->actionRects.size(); ++i) {
1614 const QRect &actionRect = d->actionRects.at(i);
1615 ret = ret.expandedTo(QSize(actionRect.x() + actionRect.width(), actionRect.y() + actionRect.height()));
1619 ret += QSize(fw + hmargin, fw + vmargin);
1621 int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
1622 if (d->leftWidget) {
1623 QSize sz = d->leftWidget->sizeHint();
1624 sz.rheight() += margin;
1625 ret = ret.expandedTo(sz);
1627 if (d->rightWidget) {
1628 QSize sz = d->rightWidget->sizeHint();
1629 ret.setWidth(ret.width() + sz.width());
1630 if (sz.height() + margin > ret.height())
1631 ret.setHeight(sz.height() + margin);
1633 if (as_gui_menubar) {
1634 QStyleOptionMenuItem opt;
1636 opt.menuRect = rect();
1637 opt.state = QStyle::State_None;
1638 opt.menuItemType = QStyleOptionMenuItem::Normal;
1639 opt.checkType = QStyleOptionMenuItem::NotCheckable;
1640 opt.palette = palette();
1641 return style()->sizeFromContents(QStyle::CT_MenuBar, &opt, ret,
this);
1649int QMenuBar::heightForWidth(
int)
const
1651 Q_D(
const QMenuBar);
1652 const bool as_gui_menubar = !isNativeMenuBar();
1654 const_cast<QMenuBarPrivate*>(d)->updateGeometries();
1656 const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin,
nullptr,
this);
1657 int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth,
nullptr,
this);
1658 int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar,
nullptr,
this);
1659 if (as_gui_menubar) {
1660 for (
int i = 0; i < d->actionRects.size(); ++i)
1661 height = qMax(height, d->actionRects.at(i).height());
1663 height += spaceBelowMenuBar;
1665 height += 2*vmargin;
1667 int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
1669 height = qMax(d->leftWidget->sizeHint().height() + margin, height);
1671 height = qMax(d->rightWidget->sizeHint().height() + margin, height);
1672 if (as_gui_menubar) {
1673 QStyleOptionMenuItem opt;
1675 opt.menuRect = rect();
1676 opt.state = QStyle::State_None;
1677 opt.menuItemType = QStyleOptionMenuItem::Normal;
1678 opt.checkType = QStyleOptionMenuItem::NotCheckable;
1679 return style()->sizeFromContents(QStyle::CT_MenuBar, &opt, QSize(0, height),
this).height();
1690 QAction *act = actions.at(id);
1691 if (act && act->menu()) {
1692 if (QPlatformMenu *platformMenu = act->menu()->platformMenu()) {
1693 platformMenu->showPopup(q->windowHandle(), actionRects.at(id),
nullptr);
1698 keyboardFocusWidget = QApplication::focusWidget();
1700 if (act && !act->menu()) {
1701 activateAction(act, QAction::Trigger);
1703 autoReleaseTimer.start(100, q);
1704 }
else if (act && q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation,
nullptr, q)) {