📄 qmenu.cpp
字号:
if (d->eventLoop) d->eventLoop->exit(); d->setCurrentAction(0);#ifndef QT_NO_ACCESSIBILITY QAccessible::updateAccessibility(this, 0, QAccessible::PopupMenuEnd);#endif#ifndef QT_NO_MENUBAR if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->causedPopup.widget)) mb->d_func()->setCurrentAction(0);#endif d->mouseDown = false; d->hasHadMouse = false; d->causedPopup.widget = 0; d->causedPopup.action = 0;}/*! \reimp*/void QMenu::paintEvent(QPaintEvent *e){ Q_D(QMenu); QPainter p(this); QRegion emptyArea = QRegion(rect()); //draw the items that need updating.. for (int i = 0; i < d->actionList.count(); ++i) { QAction *action = d->actionList.at(i); QRect adjustedActionRect = d->actionRect(action); if (!e->rect().intersects(adjustedActionRect)) continue; //set the clip region to be extra safe (and adjust for the scrollers) QRegion adjustedActionReg(adjustedActionRect); emptyArea -= adjustedActionReg; p.setClipRegion(adjustedActionReg); QStyleOptionMenuItem opt = d->getStyleOption(action); opt.rect = adjustedActionRect; style()->drawControl(QStyle::CE_MenuItem, &opt, &p, this); } const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this); QStyleOptionMenuItem menuOpt; menuOpt.initFrom(this); menuOpt.palette = palette(); menuOpt.state = QStyle::State_None; menuOpt.checkType = QStyleOptionMenuItem::NotCheckable; menuOpt.menuRect = rect(); menuOpt.maxIconWidth = 0; menuOpt.tabWidth = 0; //draw the scroller regions.. if (d->scroll) { const int scrollerHeight = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this); menuOpt.menuItemType = QStyleOptionMenuItem::Scroller; menuOpt.state |= QStyle::State_Enabled; if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) { menuOpt.rect.setRect(fw, fw, width() - (fw * 2), scrollerHeight); emptyArea -= QRegion(menuOpt.rect); p.setClipRect(menuOpt.rect); style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this); } if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown) { menuOpt.rect.setRect(fw, height() - scrollerHeight - fw, width() - (fw * 2), scrollerHeight); emptyArea -= QRegion(menuOpt.rect); menuOpt.state |= QStyle::State_DownArrow; p.setClipRect(menuOpt.rect); style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this); } } //paint the tear off.. if (d->tearoff) { menuOpt.menuItemType = QStyleOptionMenuItem::TearOff; menuOpt.rect.setRect(fw, fw, width() - (fw * 2), style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this)); if (d->scroll && d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) menuOpt.rect.translate(0, style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this)); emptyArea -= QRegion(menuOpt.rect); p.setClipRect(menuOpt.rect); menuOpt.state = QStyle::State_None; if (d->tearoffHighlighted) menuOpt.state |= QStyle::State_Selected; style()->drawControl(QStyle::CE_MenuTearoff, &menuOpt, &p, this); } //draw border if (fw) { QRegion borderReg; borderReg += QRect(0, 0, fw, height()); //left borderReg += QRect(width()-fw, 0, fw, height()); //right borderReg += QRect(0, 0, width(), fw); //top borderReg += QRect(0, height()-fw, width(), fw); //bottom p.setClipRegion(borderReg); emptyArea -= borderReg; QStyleOptionFrame frame; frame.rect = rect(); frame.palette = palette(); frame.state = QStyle::State_None; frame.lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); frame.midLineWidth = 0; style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, &p, this); } //finally the rest of the space p.setClipRegion(emptyArea); menuOpt.state = QStyle::State_None; menuOpt.menuItemType = QStyleOptionMenuItem::EmptyArea; menuOpt.checkType = QStyleOptionMenuItem::NotCheckable; menuOpt.rect = rect(); menuOpt.menuRect = rect(); style()->drawControl(QStyle::CE_MenuEmptyArea, &menuOpt, &p, this);}#ifndef QT_NO_WHEELEVENT/*! \reimp*/void QMenu::wheelEvent(QWheelEvent *e){ Q_D(QMenu); if (d->scroll && rect().contains(e->pos())) d->scrollMenu(e->delta() > 0 ? QMenuPrivate::QMenuScroller::ScrollUp : QMenuPrivate::QMenuScroller::ScrollDown);}#endif/*! \reimp*/void QMenu::mousePressEvent(QMouseEvent *e){ Q_D(QMenu); if (d->mouseEventTaken(e)) return; if (!rect().contains(e->pos())) { if (d->noReplayFor && QRect(d->noReplayFor->mapToGlobal(QPoint()), d->noReplayFor->size()).contains(e->globalPos())) setAttribute(Qt::WA_NoMouseReplay); if (d->eventLoop) // synchronous operation d->syncAction = 0; d->hideUpToMenuBar(); return; } d->mouseDown = true; QAction *action = d->actionAt(e->pos()); d->setCurrentAction(action, 20); update();}/*! \reimp*/void QMenu::mouseReleaseEvent(QMouseEvent *e){ Q_D(QMenu); if (d->mouseEventTaken(e)) return; d->mouseDown = false; QAction *action = d->actionAt(e->pos()); for(QWidget *caused = this; caused;) { if (QMenu *m = qobject_cast<QMenu*>(caused)) { caused = m->d_func()->causedPopup.widget; if (m->d_func()->eventLoop) // synchronous operation m->d_func()->syncAction = d->currentAction; } else { break; } } if (action && action == d->currentAction) { if (action->menu()) action->menu()->d_func()->setFirstActionActive(); else d->activateAction(action, QAction::Trigger); } else if (d->motions > 6) { d->hideUpToMenuBar(); }}/*! \reimp*/void QMenu::changeEvent(QEvent *e){ Q_D(QMenu); if (e->type() == QEvent::StyleChange || e->type() == QEvent::FontChange || e->type() == QEvent::LayoutDirectionChange) { d->itemsDirty = 1; setMouseTracking(style()->styleHint(QStyle::SH_Menu_MouseTracking, 0, this)); if (isVisible()) resize(sizeHint()); if (!style()->styleHint(QStyle::SH_Menu_Scrollable, 0, this)) { delete d->scroll; d->scroll = 0; } else if (!d->scroll) { d->scroll = new QMenuPrivate::QMenuScroller; d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone; } } else if (e->type() == QEvent::EnabledChange) { if (d->tornPopup) // torn-off menu d->tornPopup->setEnabled(isEnabled()); d->menuAction->setEnabled(isEnabled()); } QWidget::changeEvent(e);}/*! \reimp*/boolQMenu::event(QEvent *e){ Q_D(QMenu); switch (e->type()) { case QEvent::KeyPress: { QKeyEvent *ke = (QKeyEvent*)e; if (ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab) { keyPressEvent(ke); return true; } } break; case QEvent::Resize: d->itemsDirty = 1; d->updateActions(); break; case QEvent::Show: d->updateActions(); break;#ifndef QT_NO_WHATSTHIS case QEvent::QueryWhatsThis: e->setAccepted(d->whatsThis.size()); if (QAction *action = d->actionAt(static_cast<QHelpEvent*>(e)->pos())) { if (action->whatsThis().size() || action->menu()) e->accept(); } return true;#endif default: break; } return QWidget::event(e);}/*! \reimp*/void QMenu::keyPressEvent(QKeyEvent *e){ Q_D(QMenu); int key = e->key(); if (isRightToLeft()) { // in reverse mode open/close key for submenues are reversed if (key == Qt::Key_Left) key = Qt::Key_Right; else if (key == Qt::Key_Right) key = Qt::Key_Left; } if (key == Qt::Key_Tab) //means down key = Qt::Key_Down; bool key_consumed = false; switch(key) { case Qt::Key_Home: key_consumed = true; if (d->scroll) { for(int i = 0; i < d->actionList.size(); ++i) { QAction *act = d->actionList.at(i); if (!act->isSeparator() && (style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this) || act->isEnabled())) { if(d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) d->scrollMenu(act, QMenuPrivate::QMenuScroller::ScrollTop, true); else d->setCurrentAction(act); break; } } } break; case Qt::Key_End: key_consumed = true; if (d->scroll) { for(int i = d->actionList.size()-1; i >= 0; --i) { QAction *act = d->actionList.at(i); if (!act->isSeparator() && (style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this) || act->isEnabled())) { if(d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown) d->scrollMenu(act, QMenuPrivate::QMenuScroller::ScrollBottom, true); else d->setCurrentAction(act); break; } } } break; case Qt::Key_PageUp: key_consumed = true; if (d->currentAction && d->scroll) d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollUp, true, true); break; case Qt::Key_PageDown: key_consumed = true; if (d->currentAction && d->scroll) d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollDown, true, true); break; case Qt::Key_Up: case Qt::Key_Down: { key_consumed = true; QAction *nextAction = 0; QMenuPrivate::QMenuScroller::ScrollLocation scroll_loc = QMenuPrivate::QMenuScroller::ScrollStay; if (!d->currentAction) { if(key == Qt::Key_Down) { for(int i = 0; i < d->actionList.size(); ++i) { QAction *act = d->actionList.at(i); if (!act->isSeparator() && (style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this) || act->isEnabled())) { nextAction = act; break; } } } else { for(int i = d->actionList.size()-1; i >= 0; --i) { QAction *act = d->actionList.at(i); if (!act->isSeparator() && (style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this) || act->isEnabled())) { nextAction = act; break; } } } } else { for(int i=0, y=0; !nextAction && i < (int)d->actionList.count(); i++) { QAction *act = d->actionList.at(i); if (act == d->currentAction) { if (key == Qt::Key_Up) { for(int next_i = i-1; true; next_i--) { if (next_i == -1) { if (d->scroll) break; next_i = d->actionList.count()-1; } QAction *next = d->actionList.at(next_i); if (next == d->currentAction) break; if (next->isSeparator() || (!next->isEnabled() && !style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this))) continue; nextAction = next; if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)) { int topVisible = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this); if (d->tearoff) topVisible += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this); if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.value(nextAction).height()) scroll_loc = QMenuPrivate::QMenuScroller::ScrollTop; } break; } if (!nextAction && d->tearoff) d->tearoffHighlighted = 1; } else { y += d->actionRects.value(act).height(); for(int next_i = i+1; true; next_i++) { if (next_i == d->actionList.count()) { if (d->scroll) break; next_i = 0; } QAction *next = d->actionList.at(next_i); if (next == d->currentAction) break; if (next->isSeparator() || (!next->isEnabled() && !style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this))) continue; nextAction = next; if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)) { const int scrollerHeight = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this); int bottomVisible = height()-scrollerHeight; if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) bottomVisible -= scrollerHeight; if (d->tearoff) bottomVisible -= style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this); if ((y + d->scroll->scrollOffset + d->ac
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -