📄 qmenubar.cpp
字号:
setAltMode( FALSE ); } } return FALSE; // don't stop event}/*! \internal Receives signals from menu items.*/void QMenuBar::subActivated( int id ){ emit activated( id );}/*! \internal Receives signals from menu items.*/void QMenuBar::subHighlighted( int id ){ emit highlighted( id );}/*! \internal Receives signals from menu accelerator.*/#ifndef QT_NO_ACCELvoid QMenuBar::accelActivated( int id ){ if ( !isEnabled() ) // the menu bar is disabled return; setActiveItem( indexOf( id ) );}#endif/*! \internal This slot receives signals from menu accelerator when it is about to be destroyed.*/#ifndef QT_NO_ACCELvoid QMenuBar::accelDestroyed(){ autoaccel = 0; // don't delete it twice!}#endifbool QMenuBar::tryMouseEvent( QPopupMenu *, QMouseEvent *e ){ QPoint pos = mapFromGlobal( e->globalPos() ); if ( !rect().contains( pos ) ) // outside return FALSE; int item = itemAtPos( pos ); if ( item == -1 && (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease) ) { hidePopups(); goodbye(); return FALSE; } QMouseEvent ee( e->type(), pos, e->globalPos(), e->button(), e->state() ); event( &ee ); return TRUE;}void QMenuBar::tryKeyEvent( QPopupMenu *, QKeyEvent *e ){ event( e );}void QMenuBar::goodbye( bool cancelled ){ mouseBtDn = FALSE; popupvisible = 0; if ( cancelled && style() == WindowsStyle ) setAltMode( TRUE ); else setAltMode( FALSE );}void QMenuBar::openActPopup(){#ifndef QT_NO_POPUPMENU if ( actItem < 0 ) return;// setWindowsAltMode( FALSE, actItem ); QPopupMenu *popup = mitems->at(actItem)->popup(); if ( !popup || !popup->isEnabled() ) return; QRect r = itemRect( actItem ); QPoint pos = r.bottomLeft() + QPoint(0,1); int ph = popup->sizeHint().height(); pos = mapToGlobal(pos); int sh = QApplication::desktop()->height(); if ( defaultup || (pos.y() + ph > sh) ) { QPoint t = mapToGlobal( r.topLeft() ); t.ry() -= (QCOORD)ph; if ( !defaultup || t.y() >= 0 ) pos = t; } //avoid circularity if ( popup->isVisible() ) return; if (popup->parentMenu != this ){ // reuse if (popup->parentMenu) popup->parentMenu->menuDelPopup(popup); menuInsPopup(popup); } popup->snapToMouse = FALSE; popup->popup( pos ); popup->snapToMouse = TRUE;#endif}/*! \internal Hides all popup menu items.*/void QMenuBar::hidePopups(){#ifndef QT_NO_POPUPMENU QMenuItemListIt it(*mitems); register QMenuItem *mi; while ( (mi=it.current()) ) { ++it; if ( mi->popup() ) { mi->popup()->hide(); } }#endif}/*! Reimplements QWidget::show() in order to set up the correct keyboard accelerators and raise itself to the top of the widget stack.*/void QMenuBar::show(){#ifndef QT_NO_ACCEL setupAccelerators();#endif if ( parentWidget() ) resize( parentWidget()->width(), height() ); calculateRects(); QWidget::show();#ifndef QT_NO_MAINWINDOW if ( parent() && parent()->inherits( "QMainWindow" ) ) //### ugly workaround ( (QMainWindow*)parent() )->triggerLayout();#endif raise();}/*! Reimplements QWidget::hide() in order to deselect any selected item and calls setUpLayout() for the mainwindow.*/void QMenuBar::hide(){ QWidget::hide(); setAltMode( FALSE ); hidePopups();#ifndef QT_NO_MAINWINDOW if ( parent() && parent()->inherits( "QMainWindow" ) ) //### ugly workaround ( (QMainWindow*)parent() )->triggerLayout();#endif}/*! \internal Needs to change the size of the menu bar when a new font is set.*/void QMenuBar::fontChange( const QFont & f ){ badSize = TRUE; updateGeometry(); if ( isVisible() ) calculateRects(); QWidget::fontChange( f );}/***************************************************************************** Item geometry functions *****************************************************************************//*! This function serves two different purposes. If the parameter is negative, it updates the irects member for the current width and resizes. Otherwise, it does the same calculations for the GIVEN width, and returns the height to which it WOULD have resized. A bit tricky, but both operations require almost identical steps.*/int QMenuBar::calculateRects( int max_width ){ polish(); bool update = ( max_width < 0 ); if ( update ) { rightSide = 0; if ( !badSize ) // size was not changed return 0; if ( irects ) // Avoid purify complaint. delete [] irects; if ( mitems->isEmpty() ) { irects = 0; return 0; } int i = mitems->count(); // workaround for gcc 2.95.2 irects = new QRect[ i ]; // create rectangle array CHECK_PTR( irects ); max_width = width(); } QFontMetrics fm = fontMetrics(); int max_height = 0; int max_item_height = 0; int nlitems = 0; // number on items on cur line int gs = style(); int x = style().defaultFrameWidth(); int y = style().defaultFrameWidth(); if( gs == MotifStyle ) { x += motifBarHMargin; y += motifBarVMargin; } int i = 0; int separator = -1; while ( i < (int)mitems->count() ) { // for each menu item... QMenuItem *mi = mitems->at(i); int w=0, h=0; if ( mi->widget() ) { if ( mi->widget()->parentWidget() != this ) { mi->widget()->reparent( this, QPoint(0,0), TRUE ); } w = mi->widget()->sizeHint().expandedTo( QApplication::globalStrut() ).width()+2; h = mi->widget()->sizeHint().expandedTo( QApplication::globalStrut() ).height()+2; if ( i && separator < 0 ) separator = i; } else if ( mi->pixmap() ) { // pixmap item w = QMAX( mi->pixmap()->width() + 4, QApplication::globalStrut().width() ); h = QMAX( mi->pixmap()->height() + 4, QApplication::globalStrut().height() ); } else if ( !mi->text().isNull() ) { // text item QString s = mi->text(); w = fm.boundingRect( s ).width() + 2*motifItemHMargin; w -= s.contains('&')*fm.width('&'); w += s.contains("&&")*fm.width('&'); w = QMAX( w, QApplication::globalStrut().width() ); h = QMAX( fm.height() + motifItemVMargin, QApplication::globalStrut().height() ); } else if ( mi->isSeparator() ) { // separator item if ( style() == MotifStyle ) separator = i; //### only motif? } if ( !mi->isSeparator() || mi->widget() ) { if ( gs == MotifStyle ) { w += 2*motifItemFrame; h += 2*motifItemFrame; } if ( x + w + style().defaultFrameWidth() - max_width > 0 && nlitems > 0 ) { nlitems = 0; x = style().defaultFrameWidth(); y += h; if( gs == MotifStyle ) { x += motifBarHMargin; y += motifBarVMargin; } separator = -1; } if ( y + h + 2*style().defaultFrameWidth() > max_height ) max_height = y + h + 2*style().defaultFrameWidth(); if ( h > max_item_height ) max_item_height = h; } if ( update ) { irects[i].setRect( x, y, w, h ); } x += w; nlitems++; i++; } if ( update ) { if ( separator >= 0 ) { int moveBy = max_width - x; rightSide = x; while( --i >= separator ) { irects[i].moveBy( moveBy, 0 ); } } else { rightSide = width()-frameWidth(); } if ( max_height != height() ) resize( max_width, max_height ); for ( i = 0; i < (int)mitems->count(); i++ ) { irects[i].setHeight( max_item_height ); QMenuItem *mi = mitems->at(i); if ( mi->widget() ) { QRect r ( QPoint(0,0), mi->widget()->sizeHint() ); r.moveCenter( irects[i].center() ); mi->widget()->setGeometry( r ); } } badSize = FALSE; } return max_height;}/*! Returns the height that the menu would resize itself to if its parent (and hence itself) resized to the given width. This can be useful for simple layout tasks where the height of the menubar is needed after items have been inserted. See examples/showimg/showimg.cpp for an example of the usage.*/int QMenuBar::heightForWidth(int max_width) const{ // Okay to cast away const, as we are not updating. if ( max_width < 0 ) max_width = 0; return ((QMenuBar*)this)->calculateRects( max_width );}/*! \internal Return the bounding rectangle for the menu item at position \e index.*/QRect QMenuBar::itemRect( int index ){ calculateRects(); return irects ? irects[index] : QRect(0,0,0,0);}/*! \internal Return the item at \e pos, or -1 if there is no item there, or if it is a separator item.*/int QMenuBar::itemAtPos( const QPoint &pos ){ calculateRects(); if ( !irects ) return -1; int i = 0; while ( i < (int)mitems->count() ) { if ( irects[i].contains( pos ) ) { QMenuItem *mi = mitems->at(i); return mi->isSeparator() ? -1 : i; } ++i; } return -1; // no match}/*! When a menubar is used above an unframed widget, it may look better with a separating line when displayed with \link QWidget::style() WindowsStyle\endlink. This function sets the usage of such a separator to appear either QMenuBar::Never, or QMenuBar::InWindowsStyle. The default is QMenuBar::Never. \sa Separator separator()*/void QMenuBar::setSeparator( Separator when ){ mseparator = when;}/*! Returns the currently set Separator usage. \sa Separator setSeparator()*/QMenuBar::Separator QMenuBar::separator() const{ return mseparator ? InWindowsStyle : Never;}/***************************************************************************** Event handlers *****************************************************************************//*! Called from QFrame::paintEvent().*/void QMenuBar::drawContents( QPainter *p ){ QColorGroup g; GUIStyle gs = style().guiStyle(); bool e; for ( int i=0; i<(int)mitems->count(); i++ ) { QMenuItem *mi = mitems->at( i ); if ( !mi->text().isNull() || mi->pixmap() ) { QRect r = irects[i]; e = mi->isEnabled(); if ( e ) g = colorGroup(); else g = palette().disabled(); if ( gs == WindowsStyle || style().defaultFrameWidth() < 2) { p->fillRect( r,palette().normal().brush( QColorGroup::Button ) ); if ( i == actItem && ( hasFocus() || hasmouse || popupvisible ) ) { QBrush b = palette().normal().brush( QColorGroup::Button ); if ( actItemDown ) p->setBrushOrigin(p->brushOrigin() + QPoint(1,1)); qDrawShadeRect( p, r.left(), r.top(), r.width(), r.height(), g, actItemDown, 1, 0, &b ); if ( actItemDown ) { r.setRect( r.left()+2, r.top()+2, r.width()-2, r.height()-2 ); p->setBrushOrigin(p->brushOrigin() - QPoint(1,1)); } } } else { // motif if ( i == actItem && actItemDown ) // active item qDrawShadePanel( p, r, palette().normal(), FALSE, motifItemFrame, &palette().normal().brush( QColorGroup::Button )); else // other item p->fillRect(r, palette().normal().brush( QColorGroup::Button )); } style().drawMenuBarItem( p, r.left(), r.top(), r.width(), r.height(),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -