📄 qcombobox.cpp
字号:
void QComboBoxPrivateContainer::updateScrollers(){#ifndef QT_NO_SCROLLBAR if (!top || !bottom) return; if (isVisible() == false) return; QStyleOptionComboBox opt = comboStyleOption(); if (combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo) && view->verticalScrollBar()->minimum() < view->verticalScrollBar()->maximum()) { bool needTop = view->verticalScrollBar()->value() > (view->verticalScrollBar()->minimum() + spacing()); bool needBottom = view->verticalScrollBar()->value() < (view->verticalScrollBar()->maximum() - spacing()*2); if (needTop) top->show(); else top->hide(); if (needBottom) bottom->show(); else bottom->hide(); } else { top->hide(); bottom->hide(); }#endif // QT_NO_SCROLLBAR}/* Cleans up when the view is destroyed.*/void QComboBoxPrivateContainer::viewDestroyed(){ view = 0; setItemView(new QComboBoxListView());}/* Sets currentIndex on entered if the LeftButton is not pressed. This means that if mouseTracking(...) is on, we setCurrentIndex and select even when LeftButton is not pressed.*/void QComboBoxPrivateContainer::setCurrentIndex(const QModelIndex &index){ view->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);}/* Returns the item view used for the combobox popup.*/QAbstractItemView *QComboBoxPrivateContainer::itemView() const{ return view;}/*! Sets the item view to be used for the combobox popup.*/void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView){ Q_ASSERT(itemView); // clean up old one if (view) { view->removeEventFilter(this); view->viewport()->removeEventFilter(this);#ifndef QT_NO_SCROLLBAR disconnect(view->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(updateScrollers())); disconnect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(updateScrollers()));#endif disconnect(view, SIGNAL(entered(QModelIndex)), this, SLOT(setCurrentIndex(QModelIndex))); disconnect(view, SIGNAL(destroyed()), this, SLOT(viewDestroyed())); delete view; view = 0; } // setup the item view view = itemView; view->setParent(this); view->setAttribute(Qt::WA_MacShowFocusRect, false); qobject_cast<QBoxLayout*>(layout())->insertWidget(top ? 1 : 0, view); view->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); view->installEventFilter(this); view->viewport()->installEventFilter(this); view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); QStyleOptionComboBox opt = comboStyleOption(); const bool usePopup = combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo);#ifndef QT_NO_SCROLLBAR if (usePopup) view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);#endif if (combo->style()->styleHint(QStyle::SH_ComboBox_ListMouseTracking, &opt, combo) || usePopup) { view->setMouseTracking(true); } view->setSelectionMode(QAbstractItemView::SingleSelection); view->setFrameStyle(QFrame::NoFrame); view->setLineWidth(0); view->setEditTriggers(QAbstractItemView::NoEditTriggers);#ifndef QT_NO_SCROLLBAR connect(view->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(updateScrollers())); connect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(updateScrollers()));#endif connect(view, SIGNAL(entered(QModelIndex)), this, SLOT(setCurrentIndex(QModelIndex))); connect(view, SIGNAL(destroyed()), this, SLOT(viewDestroyed()));}/*! Returns the spacing between the items in the view.*/int QComboBoxPrivateContainer::spacing() const{ QListView *lview = qobject_cast<QListView*>(view); if (lview) return lview->spacing(); return 0;}void QComboBoxPrivateContainer::updateTopBottomMargin(){ if (!layout() || layout()->count() < 1) return; QBoxLayout *boxLayout = qobject_cast<QBoxLayout *>(layout()); if (!boxLayout) return; const QStyleOptionComboBox opt = comboStyleOption(); const bool usePopup = combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo); const int margin = usePopup ? combo->style()->pixelMetric(QStyle::PM_MenuVMargin, &opt, combo) : 0; QSpacerItem *topSpacer = boxLayout->itemAt(0)->spacerItem(); if (topSpacer) topSpacer->changeSize(0, margin, QSizePolicy::Minimum, QSizePolicy::Fixed); QSpacerItem *bottomSpacer = boxLayout->itemAt(boxLayout->count() - 1)->spacerItem(); if (bottomSpacer && bottomSpacer != topSpacer) bottomSpacer->changeSize(0, margin, QSizePolicy::Minimum, QSizePolicy::Fixed); boxLayout->invalidate();}void QComboBoxPrivateContainer::changeEvent(QEvent *e){ if (e->type() == QEvent::StyleChange) { QStyleOptionComboBox opt = comboStyleOption(); view->setMouseTracking(combo->style()->styleHint(QStyle::SH_ComboBox_ListMouseTracking, &opt, combo) || combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo)); setFrameStyle(combo->style()->styleHint(QStyle::SH_ComboBox_PopupFrameStyle, &opt, combo)); } QWidget::changeEvent(e);}bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e){ switch (e->type()) { case QEvent::KeyPress: switch (static_cast<QKeyEvent*>(e)->key()) { case Qt::Key_Enter: case Qt::Key_Return:#ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Select:#endif if (view->currentIndex().isValid() && (view->currentIndex().flags() & Qt::ItemIsEnabled) ) { combo->hidePopup(); emit itemSelected(view->currentIndex()); } return true; case Qt::Key_Down: if (!(static_cast<QKeyEvent*>(e)->modifiers() & Qt::AltModifier)) break; // fall through case Qt::Key_F4: case Qt::Key_Escape:#ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Back:#endif combo->hidePopup(); return true; default: break; } break; case QEvent::MouseMove: { if (isVisible()) { QMouseEvent *m = static_cast<QMouseEvent *>(e); QPoint vector = m->pos() - initialClickPosition; if (vector.manhattanLength() > 9 && blockMouseReleaseTimer.isActive()) blockMouseReleaseTimer.stop(); } break; } case QEvent::MouseButtonRelease: { QMouseEvent *m = static_cast<QMouseEvent *>(e); if (isVisible() && view->rect().contains(m->pos()) && view->currentIndex().isValid() && !blockMouseReleaseTimer.isActive() && (view->currentIndex().flags() & Qt::ItemIsEnabled)) { combo->hidePopup(); emit itemSelected(view->currentIndex()); return true; } break; } default: break; } return QFrame::eventFilter(o, e);}void QComboBoxPrivateContainer::showEvent(QShowEvent *){ combo->update();}void QComboBoxPrivateContainer::hideEvent(QHideEvent *){ emit resetButton(); combo->update();}void QComboBoxPrivateContainer::mousePressEvent(QMouseEvent *e){ QStyleOptionComboBox opt = comboStyleOption(); opt.subControls = QStyle::SC_All; opt.activeSubControls = QStyle::SC_ComboBoxArrow; QStyle::SubControl sc = combo->style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt, combo->mapFromGlobal(e->globalPos()), combo); if ((combo->isEditable() && sc == QStyle::SC_ComboBoxArrow) || (!combo->isEditable() && sc != QStyle::SC_None)) setAttribute(Qt::WA_NoMouseReplay); QFrame::mousePressEvent(e);}void QComboBoxPrivateContainer::mouseReleaseEvent(QMouseEvent *e){ Q_UNUSED(e); if (!blockMouseReleaseTimer.isActive()){ combo->hidePopup(); emit resetButton(); }}QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const{ QStyleOptionComboBox opt; opt.state = QStyle::State_None; opt.rect = combo->rect(); opt.palette = combo->palette(); opt.init(combo); opt.subControls = QStyle::SC_All; opt.activeSubControls = QStyle::SC_None; opt.editable = combo->isEditable(); return opt;}/*! \enum QComboBox::InsertPolicy This enum specifies what the QComboBox should do when a new string is entered by the user. \value NoInsert The string will not be inserted into the combobox. \value InsertAtTop The string will be inserted as the first item in the combobox. \value InsertAtCurrent The current item will be \e replaced by the string. \value InsertAtBottom The string will be inserted after the last item in the combobox. \value InsertAfterCurrent The string is inserted after the current item in the combobox. \value InsertBeforeCurrent The string is inserted before the current item in the combobox. \value InsertAlphabetically The string is inserted in the alphabetic order in the combobox. \omitvalue NoInsertion \omitvalue AtTop \omitvalue AtCurrent \omitvalue AtBottom \omitvalue AfterCurrent \omitvalue BeforeCurrent*//*! \enum QComboBox::SizeAdjustPolicy This enum specifies how the size hint of the QComboBox should adjust when new content is added or content changes. \value AdjustToContents The combobox will always adjust to the contents \value AdjustToContentsOnFirstShow The combobox will adjust to its contents the first time it is show. \value AdjustToMinimumContentsLength Use AdjustToContents or AdjustToContentsOnFirstShow instead. \value AdjustToMinimumContentsLengthWithIcon The combobox will adjust to \l minimumContentsLength plus space for an icon. For performance reasons use this policy on large models.*//*! \fn void QComboBox::activated(int index) This signal is sent when an item in the combobox is activated by the user. The item's \a index is given.*//*! \fn void QComboBox::activated(const QString &text) This signal is sent when an item in the combobox is activated by the user. The item's \a text is given.*//*! \fn void QComboBox::highlighted(int index) This signal is sent when an item in the combobox popup list is highlighted by the user. The item's \a index is given.*//*! \fn void QComboBox::highlighted(const QString &text) This signal is sent when an item in the combobox popup list is highlighted by the user. The item's \a text is given.*//*! \fn void QComboBox::currentIndexChanged(int index) \since 4.1 This signal is sent whenever the currentIndex in the combobox changes either through user interaction or programmatically. The item's \a index is given or -1 if the combobox becomes empty or the currentIndex was reset.*//*! \fn void QComboBox::currentIndexChanged(const QString &text) \since 4.1 This signal is sent whenever the currentIndex in the combobox changes either through user interaction or programmatically. The item's \a text is given.*//*! Constructs a combobox with the given \a parent, using the default model QStandardItemModel.*/QComboBox::QComboBox(QWidget *parent) : QWidget(*new QComboBoxPrivate(), parent, 0){ Q_D(QComboBox); d->init();}/*! \internal*/QComboBox::QComboBox(QComboBoxPrivate &dd, QWidget *parent) : QWidget(dd, parent, 0){ Q_D(QComboBox); d->init();}#ifdef QT3_SUPPORT/*! Use one of the constructors that doesn't take the \a name argument and then use setObjectName() instead.*/QComboBox::QComboBox(QWidget *parent, const char *name) : QWidget(*new QComboBoxPrivate(), parent, 0){ Q_D(QComboBox); d->init(); setObjectName(QString::fromAscii(name));}/*! Use one of the constructors that doesn't take the \a name argument and then use setObjectName() instead.*/QComboBox::QComboBox(bool rw, QWidget *parent, const char *name) : QWidget(*new QComboBoxPrivate(), parent, 0){ Q_D(QComboBox); d->init(); setEditable(rw); setObjectName(QString::fromAscii(name));}#endif //QT3_SUPPORT/*! \class QComboBox qcombobox.h \brief The QComboBox widget is a combined button and popup list. \ingroup basicwidgets \mainclass A QComboBox provides a means of presenting a list of options to the user in a way that takes up the minimum amount of screen space. A combobox is a selection widget that displays the current item, and can pop up a list of selectable items. A combobox may be editable, allowing the user to modify each item in the list. Comboboxes can contain pixmaps as well as strings; the insertItem() and setItemText() functions are suitably overloaded. For editable comboboxes, the function clearEditText() is provided, to clear the displayed string without changing the combobox's contents. There are two signals emitted if the current item of a combobox changes, currentIndexChanged() and activated().
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -