📄 qcombobox.cpp
字号:
QWidget::setFont( font ); if ( d->usingListBox() ) d->listBox()->setFont( font ); else d->popup()->setFont( font ); if (d->ed) d->ed->setFont( font ); if ( d->autoresize ) adjustSize();}/*!\reimp*/void QComboBox::resizeEvent( QResizeEvent * e ){ if ( d->ed ) { d->updateLinedGeometry(); } QWidget::resizeEvent( e );}/*!\reimp*/void QComboBox::paintEvent( QPaintEvent * ){ QPainter p( this ); const QColorGroup & g = colorGroup(); if ( width() < 5 || height() < 5 ) { qDrawShadePanel( &p, rect(), g, FALSE, 2, &g.brush( QColorGroup::Button ) ); return; } if ( !d->usingListBox() ) { // motif 1.x style int dist, buttonH, buttonW; getMetrics( &dist, &buttonW, &buttonH ); int xPos = width() - dist - buttonW - 1; qDrawShadePanel( &p, rect(), g, FALSE, style().defaultFrameWidth(), &g.brush( QColorGroup::Button ) ); qDrawShadePanel( &p, xPos, (height() - buttonH)/2, buttonW, buttonH, g, FALSE, style().defaultFrameWidth() ); QRect clip( 4, 2, xPos - 2 - 4 - 5, height() - 4 ); QString str = d->popup()->text( this->d->current ); if ( !str.isNull() ) { p.drawText( clip, AlignCenter | SingleLine, str ); } else { QPixmap *pix = d->popup()->pixmap( this->d->current ); if ( pix ) { p.setClipRect( clip ); p.drawPixmap( 4, (height()-pix->height())/2, *pix ); p.setClipping( FALSE ); } } if ( hasFocus() ) p.drawRect( xPos - 5, 4, width() - xPos + 1 , height() - 8 ); } else if ( style() == MotifStyle ) { // motif 2.0 style style().drawComboButton( &p, 0, 0, width(), height(), g, d->arrowDown, d->ed != 0 ); if ( hasFocus() ) { style().drawFocusRect(&p, style(). comboButtonFocusRect(0,0,width(),height()), g, &g.button()); } if ( !d->ed ) { QRect clip = style().comboButtonRect( 0, 0, width(), height() ); p.setPen( g.foreground() ); p.setClipRect( clip ); p.setPen( g.foreground() ); QListBoxItem * item = d->listBox()->item( d->current ); if ( item ) { int itemh = item->height( d->listBox() ); p.translate( clip.x(), clip.y() + (clip.height() - itemh)/2 ); item->paint( &p ); } } else if ( d->listBox() && d->listBox()->item( d->current ) ) { QRect r( style().comboButtonRect( 0, 0, width(), height() ) ); QListBoxItem * item = d->listBox()->item( d->current ); const QPixmap *pix = item->pixmap(); if ( pix ) { p.fillRect( r.x(), r.y(), pix->width() + 4, r.height(), colorGroup().brush( QColorGroup::Base ) ); p.drawPixmap( r.x() + 2, r.y() + ( r.height() - pix->height() ) / 2, *pix ); } } p.setClipping( FALSE ); } else { // windows 95 style style().drawComboButton(&p, 0, 0, width(), height(), g, d->arrowDown, d->ed != 0, isEnabled() ); int fm = style().pixelMetric(QStyle::ComboBoxFocusMargin); // 1 int hm = style().pixelMetric(QStyle::ComboBoxTextHMargin); // 2 int vm = style().pixelMetric(QStyle::ComboBoxTextVMargin); // 1 QRect tmpR = style().comboButtonRect(0,0,width(),height()); QRect textR(tmpR.x()+fm, tmpR.y()+fm, tmpR.width()-fm*2, tmpR.height()-fm*2); if ( hasFocus()) { if (!d->ed) { p.fillRect( textR.x(), textR.y(), textR.width(), textR.height(), g.brush( QColorGroup::Highlight ) ); } style().drawFocusRect(&p, style().comboButtonFocusRect(0,0,width(),height()), g, &g.highlight()); } textR.setRect(tmpR.x()+hm, tmpR.y()+vm, tmpR.width()-hm*2, tmpR.height()-vm*2); p.setClipRect( textR ); if ( hasFocus() ) { p.setPen( g.highlightedText() ); p.setBackgroundColor( g.highlight() ); } else { p.setPen( g.text() ); p.setBackgroundColor( g.background() ); } if ( !d->ed ) { QListBoxItem * item = d->listBox()->item( d->current ); if ( item ) { int itemh = item->height( d->listBox() ); p.translate( textR.x(), textR.y() + (textR.height() - itemh)/2 ); item->paint( &p ); } } else if ( d->listBox() && d->listBox()->item( d->current ) ) { p.setClipping( FALSE ); QRect r( style().comboButtonRect( 0, 0, width(), height() ) ); QListBoxItem * item = d->listBox()->item( d->current ); const QPixmap *pix = item->pixmap(); if ( pix ) { p.fillRect( r.x(), r.y(), pix->width() + hm*2, r.height(), colorGroup().brush( QColorGroup::Base ) ); p.drawPixmap( r.x() + hm, r.y() + ( r.height() - pix->height() ) / 2, *pix ); } } p.setClipping( FALSE ); }}/*! \internal Returns the button arrow rectangle for windows style combo boxes.*/QRect QComboBox::arrowRect() const{ return QRect( width() - 2 - 16, 2, 16, height() - 4 );}/*!\reimp*/void QComboBox::mousePressEvent( QMouseEvent *e ){ if ( e->button() != LeftButton ) return;#ifdef Q_WS_REPLAYSONPOPDOWN if ( d->discardNextMousePress ) { d->discardNextMousePress = FALSE; return; }#endif if ( count() ) { d->arrowPressed = FALSE; if ( style() == WindowsStyle ) { popup(); if ( arrowRect().contains( e->pos() ) ) { d->arrowPressed = TRUE; d->arrowDown = TRUE; repaint( FALSE ); } } else if ( d->usingListBox() ) { popup(); QTimer::singleShot( 200, this, SLOT(internalClickTimeout())); d->shortClick = TRUE; } else { popup(); QTimer::singleShot( 200, this, SLOT(internalClickTimeout())); d->shortClick = TRUE; } }}/*!\reimp*/void QComboBox::mouseMoveEvent( QMouseEvent * ){}/*!\reimp*/void QComboBox::mouseReleaseEvent( QMouseEvent * ){}/*!\reimp*/void QComboBox::mouseDoubleClickEvent( QMouseEvent *e ){ mousePressEvent( e );}/*!\reimp*/void QComboBox::keyPressEvent( QKeyEvent *e ){ bool setActive = FALSE;#ifdef QT_KEYPAD_MODE if( qt_modalEditingEnabled ) { switch( e->key() ) { case Key_Select: if ( !(d->ed && d->ed->isModalEditing()) && !isModalEditing() ) { setActive = TRUE; if ( d->ed ) d->orgTxt = d->ed->text(); } else { if ( d->ed ){ d->ed->setModalEditing( FALSE ); update(); }else{ setModalEditing( FALSE ); } return; } break; case Key_Back: case Key_No: if ( isModalEditing() ) { if ( d->ed && d->ed->text() != d->orgTxt ) d->ed->setText( d->orgTxt ); setModalEditing( FALSE ); } else { e->ignore(); } return; default: if ( !isModalEditing() || (d->ed && !d->ed->isModalEditing()) ) { e->ignore(); return; } } }#endif int c; if ( ( e->key() == Key_F4 && e->state() == 0 ) || ( e->key() == Key_Down && (e->state() & AltButton) ) || ( !d->ed && e->key() == Key_Space || setActive ) ) { if ( count() ) { if ( !d->usingListBox() ) d->popup()->setActiveItem( this->d->current ); popup(); } return; } else if ( d->usingListBox() && e->key() == Key_Up ) { c = currentItem(); if ( c > 0 ) setCurrentItem( c-1 ); else setCurrentItem( count()-1 ); } else if ( d->usingListBox() && e->key() == Key_Down ) { c = currentItem(); if ( ++c < count() ) setCurrentItem( c ); else setCurrentItem( 0 ); } else { e->ignore(); return; } c = currentItem(); if ( !text( c ).isNull() ) emit activated( text( c ) ); emit highlighted( c ); emit activated( c );}/*!\reimp*/void QComboBox::focusInEvent( QFocusEvent * e ){ QWidget::focusInEvent( e );}/*! \internal Calculates the listbox height needed to contain all items, or as many as the list box is supposed to contain.*/static int listHeight( QListBox *l, int sl ){ if ( l->count() > 0 ) return QMIN( l->count(), (uint)sl) * l->item( 0 )->height(l); else return l->sizeHint().height();}/*! Popups the combo box popup list. If the list is empty, no selections appear.*/void QComboBox::popup(){ if ( !count() ) return; if ( d->usingListBox() ) { // Send all listbox events to eventFilter(): d->listBox()->installEventFilter( this ); d->listBox()->viewport()->installEventFilter( this ); d->mouseWasInsidePopup = FALSE; d->listBox()->resize( width(), listHeight( d->listBox(), d->sizeLimit ) + d->listBox()->frameWidth() * 2 ); QWidget *desktop = QApplication::desktop(); int sw = desktop->width(); // screen width int sh = desktop->height(); // screen height QPoint pos = mapToGlobal( QPoint(0,height()) ); // ### Similar code is in QPopupMenu int x = pos.x(); int y = pos.y(); int w = d->listBox()->width(); int h = d->listBox()->height(); // the complete widget must be visible if ( x + w > sw ) x = sw - w; else if ( x < 0 ) x = 0; if (y + h > sh ) { if ( sh - y > y ) { d->listBox()->resize(w, sh - y); } else { if ( y - h - height() >= 0 ) { y = y - h - height(); } else { d->listBox()->resize(w, y); y = 0; } } } d->listBox()->move( x,y ); d->listBox()->raise(); bool block = d->listBox()->signalsBlocked(); d->listBox()->blockSignals( TRUE ); d->listBox()->setCurrentItem( d->listBox()->item( d->current ) ); d->listBox()->blockSignals( block ); d->listBox()->setAutoScrollBar( TRUE );#ifndef QT_NO_EFFECTS if ( QApplication::isEffectEnabled( UI_AnimateCombo ) ) { if ( d->listBox()->y() < mapToGlobal(QPoint(0,0)).y() ) qScrollEffect( d->listBox(), QEffects::UpScroll ); else qScrollEffect( d->listBox() ); } else#endif d->listBox()->show(); } else { d->popup()->installEventFilter( this ); d->popup()->popup( mapToGlobal( QPoint(0,0) ), this->d->current ); } d->poppedUp = TRUE;#ifdef QT_KEYPAD_MODE if( qt_modalEditingEnabled ) d->listBox()->setModalEditing( TRUE );#endif}/*! \reimp*/void QComboBox::updateMask(){ QBitmap bm( size() ); bm.fill( color0 ); { QPainter p( &bm, this ); p.setPen( color1 ); p.setBrush( color1 ); style().drawComboButtonMask(&p, 0, 0, width(), height() ); } setMask( bm );}/*! \internal Pops down (removes) the combo box popup list box.*/void QComboBox::popDownListBox(){ ASSERT( d->usingListBox() );#ifdef QT_KEYPAD_MODE if( qt_modalEditingEnabled ) { if ( d->ed ) d->ed->setModalEditing( TRUE ); else d->listBox()->setModalEditing( FALSE ); }#endif d->listBox()->removeEventFilter( this ); d->listBox()->viewport()->removeEventFilter( this ); d->listBox()->hide(); d->listBox()->setCurrentItem( d->current ); if ( d->arrowDown ) { d->arrowDown = FALSE; repaint( FALSE ); } d->poppedUp = FALSE;}/*! \internal Re-indexes the identifiers in the popup list.*/void QComboBox::reIndex(){ if ( !d->usingListBox() ) { int cnt = count(); while ( cnt-- ) d->popup()->setId( cnt, cnt ); }}/*! \internal Repaints the combo box.*/void QComboBox::currentChanged(){ if ( d->autoresize ) adjustSize(); update();}/*! \reimp \internal The event filter steals events from the popup or listbox when they are popped up. It makes the popup stay up after a short click in motif style. In windows style it toggles the arrow button of the combo box field, and activates an item and takes down the listbox when the mouse button is released.*/bool QComboBox::eventFilter( QObject *object, QEvent *event ){ if ( !event ) return TRUE; else if ( object == d->ed ) { if ( event->type() == QEvent::KeyPress ) {#ifdef QT_KEYPAD_MODE if( qt_modalEditingEnabled ) { // can't pass these back to QWidget::event as they will be interpreted as TAB switch ( ((QKeyEvent *)event)->key() ) { case Key_Up: case Key_Down: case Key_Right: case Key_Left: case Key_Back: case Key_No: return FALSE; break; default: break; } }#endif keyPressEvent( (QKeyEvent *)event ); if ( ((QKeyEvent *)event)->isAccepted() ) { d->completeNow = FALSE; return TRUE; } else if ( ((QKeyEvent *)event)->key() != Key_End ) { d->completeNow = TRUE; d->completeAt = d->ed->cursorPosition(); } } else if ( event->type() == QEvent::KeyRelease ) { d->completeNow = FALSE; keyReleaseEvent( (QKeyEvent *)event ); return ((QKeyEvent *)event)->isAccepted(); } else if ( (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut ) ) { d->completeNow = FALSE; // to get the focus indication right#ifdef QT_KEYPAD_MODE if( qt_modalEditingEnabled ) { if (hasFocus()) d->ed->selectAll(); }#endif update();#ifdef QT_KEYPAD_MODE } else if ( event->type() == QEvent::LeaveModalEdit || event->type() == QEvent::EnterModalEdit ) { if( qt_modalEditingEnabled ) { update(); }#endif } else if ( d->useCompletion && d->completeNow ) { if ( !d->ed->text().isNull() && d->ed->cursorPosition() > d->completeAt && d->ed->cursorPosition() == (int)d->ed->text().length() ) { d->completeNow = FALSE; QString ct( d->ed->text() ); QString it; int i =0; int foundAt = -1; int foundLength = 100000; // lots while( i<count() ) { it = text( i ); if ( it.length() >= ct.length() ) { it.truncate( ct.length() ); int itlen = text( i ).length(); if ( ( it.lower() == ct.lower() ) && itlen < foundLength ) { foundAt = i; foundLength = text( i ).length(); break; } } i++; } if ( foundAt > -1 ) { it = text( foundAt ); if ( !d->ed->hasMarkedText() ) { d->ed->validateAndSet( it, ct.length(), ct.length(), it.length() ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -