📄 qmenu.cpp
字号:
if (d->scroll) d->scrollMenu(act, QMenuPrivate::QMenuScroller::ScrollCenter);}/*! Returns the currently highlighted action, or 0 if no action is currently highlighted.*/QAction *QMenu::activeAction() const{ return d_func()->currentAction;}/*! Removes all the menu's actions. Actions owned by the menu and not shown in any other widget are deleted. \sa removeAction()*/void QMenu::clear(){ QList<QAction*> acts = actions(); for(int i = 0; i < acts.size(); i++) { removeAction(acts[i]); if (acts[i]->parent() == this && acts[i]->d_func()->widgets.isEmpty()) delete acts[i]; }}/*! If a menu does not fit on the screen it lays itself out so that it does fit. It is style dependent what layout means (for example, on Windows it will use multiple columns). This functions returns the number of columns necessary.*/int QMenu::columnCount() const{ return d_func()->ncols;}/*! Returns the item at \a pt; returns 0 if there is no item there.*/QAction *QMenu::actionAt(const QPoint &pt) const{ if (QAction *ret = d_func()->actionAt(pt)) return ret; return 0;}/*! Returns the geometry of action \a act.*/QRect QMenu::actionGeometry(QAction *act) const{ return d_func()->actionRect(act);}/*! \reimp*/QSize QMenu::sizeHint() const{ Q_D(const QMenu); ensurePolished(); QMap<QAction*, QRect> actionRects; QList<QAction*> actionList; d->calcActionRects(actionRects, actionList); QSize s; QStyleOption opt(0); opt.rect = rect(); opt.palette = palette(); opt.state = QStyle::State_None; for (QMap<QAction*, QRect>::const_iterator i = actionRects.begin(); i != actionRects.constEnd(); ++i) { if (i.value().bottom() > s.height()) s.setHeight(i.value().y()+i.value().height()); if (i.value().right() > s.width()) s.setWidth(i.value().right()); } if (d->tearoff) s.rheight() += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, this); if (const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, this)) { s.rwidth() += fw*2; s.rheight() += fw*2; } s.rwidth() += 2 * style()->pixelMetric(QStyle::PM_MenuHMargin, &opt, this); s.rheight() += 2 * style()->pixelMetric(QStyle::PM_MenuVMargin, &opt, this); s += QSize(d->leftmargin + d->rightmargin, d->topmargin + d->bottommargin); return style()->sizeFromContents(QStyle::CT_Menu, &opt, s.expandedTo(QApplication::globalStrut()), this);}/*! Displays the menu so that the action \a atAction will be at the specified \e global position \a p. To translate a widget's local coordinates into global coordinates, use QWidget::mapToGlobal(). When positioning a menu with exec() or popup(), bear in mind that you cannot rely on the menu's current size(). For performance reasons, the menu adapts its size only when necessary, so in many cases, the size before and after the show is different. Instead, use sizeHint() which calculates the proper size depending on the menu's current contents. \sa QWidget::mapToGlobal(), exec()*/void QMenu::popup(const QPoint &p, QAction *atAction){ Q_D(QMenu); if (d->scroll) { //reset scroll state from last popup d->scroll->scrollOffset = 0; d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone; } d->tearoffHighlighted = 0; d->motions = 0; d->doChildEffects = true; ensurePolished(); // Get the right font emit aboutToShow(); d->updateActions(); QPoint pos = p; QSize size = sizeHint(); QRect screen = QApplication::desktop()->availableGeometry(p); const int desktopFrame = style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, this); if (d->ncols > 1) { pos.setY(screen.top()+desktopFrame); } else if (atAction) { for(int i=0, above_height=0; i<(int)d->actionList.count(); i++) { QAction *action = d->actionList.at(i); if (action == atAction) { int newY = pos.y()-above_height; if (d->scroll && newY < desktopFrame) { d->scroll->scrollFlags = d->scroll->scrollFlags | QMenuPrivate::QMenuScroller::ScrollUp; d->scroll->scrollOffset = newY; newY = desktopFrame; } pos.setY(newY); if (d->scroll && d->scroll->scrollFlags != QMenuPrivate::QMenuScroller::ScrollNone && !style()->styleHint(QStyle::SH_Menu_FillScreenWithScroll, 0, this)) { int below_height = above_height + d->scroll->scrollOffset; for(int i2 = i; i2 < (int)d->actionList.count(); i2++) below_height += d->actionRects.value(d->actionList.at(i2)).height(); size.setHeight(below_height); } break; } else { above_height += d->actionRects.value(action).height(); } } } QPoint mouse = QCursor::pos(); const bool snapToMouse = (p == mouse); //handle popup falling "off screen" if (qApp->layoutDirection() == Qt::RightToLeft) { if(snapToMouse) //position flowing left from the mouse pos.setX(mouse.x()-size.width()); if (pos.x() < screen.left()+desktopFrame) pos.setX(qMax(p.x(), screen.left()+desktopFrame)); else if (pos.x()+size.width() > screen.right()-desktopFrame) pos.setX(qMax(p.x()-size.width(), screen.right()-desktopFrame-size.width())); } else { if (pos.x()+size.width() > screen.right()-desktopFrame) pos.setX(qMin(p.x()-size.width(), screen.right()-desktopFrame-size.width())); else if (pos.x() < screen.left()+desktopFrame) pos.setX(p.x()); } if (pos.y() + size.height() > screen.bottom() - desktopFrame) { if(snapToMouse) pos.setY(qMin(mouse.y() - (size.height() + desktopFrame), screen.bottom()-desktopFrame-size.height())); else pos.setY(qMax(p.y() - (size.height() + desktopFrame), screen.bottom()-desktopFrame-size.height())); } else if (pos.y() < screen.top() + desktopFrame) { pos.setY(screen.top() + desktopFrame); } if (d->scroll) { if(pos.y() < screen.top()) pos.setY(screen.top()); if(pos.y()+size.height() > screen.bottom() - desktopFrame) { d->scroll->scrollFlags |= uint(QMenuPrivate::QMenuScroller::ScrollDown); size.setHeight(screen.bottom()-desktopFrame-pos.y()); } } else { if(pos.y()+size.height() > screen.bottom()) pos.setY(desktopFrame+screen.top()+(screen.height()-desktopFrame-size.height())); else if(pos.y() < screen.top()) pos.setY(screen.top()); } setGeometry(QRect(pos, size));#ifndef QT_NO_EFFECTS int hGuess = qApp->layoutDirection() == Qt::RightToLeft ? QEffects::LeftScroll : QEffects::RightScroll; int vGuess = QEffects::DownScroll; if (qApp->layoutDirection() == Qt::RightToLeft) { if ((snapToMouse && (pos.x() + size.width()/2 > mouse.x())) || (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width()/2 > d->causedPopup.widget->x())) hGuess = QEffects::RightScroll; } else { if ((snapToMouse && (pos.x() + size.width()/2 < mouse.x())) || (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width()/2 < d->causedPopup.widget->x())) hGuess = QEffects::LeftScroll; }#ifndef QT_NO_MENUBAR if ((snapToMouse && (pos.y() + size.height()/2 < mouse.y())) || (qobject_cast<QMenuBar*>(d->causedPopup.widget) && pos.y() + size.width()/2 < d->causedPopup.widget->mapToGlobal(d->causedPopup.widget->pos()).y())) vGuess = QEffects::UpScroll;#endif if (QApplication::isEffectEnabled(Qt::UI_AnimateMenu)) { bool doChildEffects = true;#ifndef QT_NO_MENUBAR if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->causedPopup.widget)) { doChildEffects = mb->d_func()->doChildEffects; mb->d_func()->doChildEffects = false; } else#endif if (QMenu *m = qobject_cast<QMenu*>(d->causedPopup.widget)) { doChildEffects = m->d_func()->doChildEffects; m->d_func()->doChildEffects = false; } if (doChildEffects) { if (QApplication::isEffectEnabled(Qt::UI_FadeMenu)) qFadeEffect(this); else if (d->causedPopup.widget) qScrollEffect(this, qobject_cast<QMenu*>(d->causedPopup.widget) ? hGuess : vGuess); else qScrollEffect(this, hGuess | vGuess); } else { // kill any running effect qFadeEffect(0); qScrollEffect(0); show(); } } else#endif { show(); }#ifndef QT_NO_ACCESSIBILITY QAccessible::updateAccessibility(this, 0, QAccessible::PopupMenuStart);#endif}/*! Executes this menu synchronously. This is equivalent to \c{exec(pos())}. This returns the triggered QAction in either the popup menu or one of its submenus, or 0 if no item was triggered (normally because the user pressed Esc). In most situations you'll want to specify the position yourself, for example, the current mouse position: \code exec(QCursor::pos()); \endcode or aligned to a widget: \code exec(somewidget.mapToGlobal(QPoint(0,0))); \endcode or in reaction to a QMouseEvent *e: \code exec(e->globalPos()); \endcode*/QAction *QMenu::exec(){ return exec(pos());}/*! \overload Executes this menu synchronously. Pops up the menu so that the action \a action will be at the specified \e global position \a p. To translate a widget's local coordinates into global coordinates, use QWidget::mapToGlobal(). This returns the triggered QAction in either the popup menu or one of its submenus, or 0 if no item was triggered (normally because the user pressed Esc). Note that all signals are emitted as usual. If you connect a QAction to a slot and call the menu's exec(), you get the result both via the signal-slot connection and in the return value of exec(). Common usage is to position the menu at the current mouse position: \code exec(QCursor::pos()); \endcode or aligned to a widget: \code exec(somewidget.mapToGlobal(QPoint(0, 0))); \endcode or in reaction to a QMouseEvent *e: \code exec(e->globalPos()); \endcode When positioning a menu with exec() or popup(), bear in mind that you cannot rely on the menu's current size(). For performance reasons, the menu adapts its size only when necessary. So in many cases, the size before and after the show is different. Instead, use sizeHint() which calculates the proper size depending on the menu's current contents. \sa popup(), QWidget::mapToGlobal()*/QAction *QMenu::exec(const QPoint &p, QAction *action){ Q_D(QMenu); QEventLoop eventLoop; d->eventLoop = &eventLoop; popup(p, action); QPointer<QObject> guard = this; (void) eventLoop.exec(); if (guard.isNull()) return 0; action = d->syncAction; d->syncAction = 0; d->eventLoop = 0; return action;}/*! \overload Executes this menu synchronously. The menu's actions are specified by the list of \a actions. The menu will pop up so that the specified action, \a at, appears at global position \a pos. If \a at is not specified then the menu appears at position \a pos. The function returns the triggered QAction in either the popup menu or one of its submenus, or 0 if no item was triggered (normally because the user pressed Esc). This is equivalent to: \code QMenu menu; QAction *at = actions[0]; // Assumes actions is not empty foreach (QAction *a, actions) menu.addAction(a); menu.exec(pos, at); \endcode \sa popup(), QWidget::mapToGlobal()*/QAction *QMenu::exec(QList<QAction*> actions, const QPoint &pos, QAction *at){ QMenu menu; for(QList<QAction*>::Iterator it = actions.begin(); it != actions.end(); ++it) menu.addAction((*it)); return menu.exec(pos, at);}/*! \reimp*/void QMenu::hideEvent(QHideEvent *){ Q_D(QMenu);#ifdef QT3_SUPPORT emit aboutToHide();#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -