📄 qcombobox.cpp
字号:
/*! \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 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 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();}#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 basic \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 changeItem() functions are suitably overloaded. For editable comboboxes, the function clearEdit() is provided, to clear the displayed string without changing the combobox's contents. A combobox emits two signals, activated() and highlighted(), when a new item has been activated (selected) or highlighted (made current). Both signals exist in two versions, one with a QString argument and one with an \c int argument. If the user highlights or activates a pixmap, only the \c int signals are emitted. Whenever the text of an editable combobox is changed the editTextChanged() signal is emitted. When the user enters a new string in an editable combobox, the widget may or may not insert it, and it can insert it in several locations. The default policy is is \l AtBottom but you can change this using setInsertPolicy(). It is possible to constrain the input to an editable combobox using QValidator; see setValidator(). By default, any input is accepted. A combobox can be populated using the insert functions, insertStringList() and insertItem() for example. Items can be changed with changeItem(). An item can be removed with removeItem() and all items can be removed with clear(). The text of the current item is returned by currentText(), and the text of a numbered item is returned with text(). The current item can be set with setCurrentIndex(). The number of items in the combobox is returned by count(); the maximum number of items can be set with setMaxCount(). You can allow editing using setEditable(). For editable comboboxes you can set auto-completion using setAutoCompletion() and whether or not the user can add duplicates is set with setDuplicatesEnabled(). \image qstyle-comboboxes.png Comboboxes in the different built-in styles. \sa QLineEdit, QSpinBox, QRadioButton, QButtonGroup, {fowler}{GUI Design Handbook: Combo Box, Drop-Down List Box}*/void QComboBoxPrivate::init(){ Q_Q(QComboBox); q->setModel(new QStandardItemModel(0, 1, q)); q->setFocusPolicy(Qt::WheelFocus); q->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);}QComboBoxPrivateContainer* QComboBoxPrivate::viewContainer(){ if (container) return container; Q_Q(QComboBox); container = new QComboBoxPrivateContainer(new QComboBoxListView(), q); container->itemView()->setModel(model); container->itemView()->setTextElideMode(Qt::ElideMiddle); QStyleOptionComboBox opt = getStyleOption(); if (q->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, q)) q->setItemDelegate(new QComboMenuDelegate(container->itemView(), q)); container->setLayoutDirection(Qt::LayoutDirection( q->style()->styleHint(QStyle::SH_ComboBox_LayoutDirection, &opt, q))); QObject::connect(container, SIGNAL(itemSelected(QModelIndex)), q, SLOT(_q_itemSelected(QModelIndex))); QObject::connect(container->itemView()->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), q, SLOT(_q_emitHighlighted(QModelIndex))); QObject::connect(container, SIGNAL(resetButton()), q, SLOT(_q_resetButton())); return container;}void QComboBoxPrivate::_q_resetButton(){ updateArrow(QStyle::State_None);}void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight){ Q_Q(QComboBox); if (topLeft.parent() != root) return; if (sizeAdjustPolicy == QComboBox::AdjustToContents) { sizeHint = QSize(); q->updateGeometry(); } if (currentIndex.row() >= topLeft.row() && currentIndex.row() <= bottomRight.row()) { if (lineEdit) { lineEdit->setText(q->itemText(currentIndex.row())); updateLineEditGeometry(); } q->update(); }}void QComboBoxPrivate::_q_rowsAboutToBeInserted(const QModelIndex & parent, int /*start*/, int /*end*/){ if (parent != root) return; indexBeforeChange = currentIndex.row();}void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int end){ Q_UNUSED(start); Q_UNUSED(end); Q_Q(QComboBox); if (parent != root) return; if (sizeAdjustPolicy == QComboBox::AdjustToContents) { sizeHint = QSize(); q->updateGeometry(); } // set current index if combo was previously empty if (start == 0 && (end - start + 1) == q->count() && !currentIndex.isValid()) { q->setCurrentIndex(0); // need to emit changed if model updated index "silently" } else if (currentIndex.row() != indexBeforeChange) { if (lineEdit) { lineEdit->setText(q->itemText(currentIndex.row())); updateLineEditGeometry(); } q->update(); _q_emitCurrentIndexChanged(currentIndex.row()); }}void QComboBoxPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int /*start*/, int /*end*/){ if (parent != root) return; indexBeforeChange = currentIndex.row();}void QComboBoxPrivate::_q_rowsRemoved(const QModelIndex &parent, int /*start*/, int /*end*/){ Q_Q(QComboBox); if (parent != root) return; if (sizeAdjustPolicy == QComboBox::AdjustToContents) { sizeHint = QSize(); q->updateGeometry(); } // model has changed the currentIndex if (currentIndex.row() != indexBeforeChange) { if (!currentIndex.isValid() && q->count()) { q->setCurrentIndex(qMin(q->count() - 1, qMax(indexBeforeChange, 0))); return; } if (lineEdit) { lineEdit->setText(q->itemText(currentIndex.row())); updateLineEditGeometry(); } q->update(); _q_emitCurrentIndexChanged(currentIndex.row()); }}QStyleOptionComboBox QComboBoxPrivate::getStyleOption() const{ Q_Q(const QComboBox); QStyleOptionComboBox opt; opt.init(q); if (!q->isEditable() && q->hasFocus()) opt.state |= QStyle::State_Selected; opt.subControls = QStyle::SC_All; if (arrowState == QStyle::State_Sunken) { opt.activeSubControls = QStyle::SC_ComboBoxArrow; opt.state |= arrowState; } else { opt.activeSubControls = hoverControl; } opt.editable = q->isEditable(); opt.frame = frame; if (currentIndex.isValid()) { opt.currentText = q->currentText(); opt.currentIcon = q->itemIcon(currentIndex.row()); } opt.iconSize = q->iconSize(); if (container && container->isVisible()) opt.state |= QStyle::State_On; return opt;}void QComboBoxPrivate::updateLineEditGeometry(){ if (!lineEdit) return; Q_Q(QComboBox); QStyleOptionComboBox opt = getStyleOption(); QRect editRect = q->style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxEditField, q); if (!q->itemIcon(q->currentIndex()).isNull()) { QRect comboRect(editRect); editRect.setWidth(editRect.width() - q->iconSize().width() - 4); editRect = QStyle::alignedRect(q->layoutDirection(), Qt::AlignRight, editRect.size(), comboRect); } lineEdit->setGeometry(editRect);}void QComboBoxPrivate::_q_returnPressed(){ Q_Q(QComboBox); if (lineEdit && !lineEdit->text().isEmpty()) { QString text = lineEdit->text(); // check for duplicates (if not enabled) and quit int index = -1; if (!duplicatesEnabled) { index = q->findText(text); if (index != -1) { q->setCurrentIndex(index); emitActivated(currentIndex); return; } } switch (insertPolicy) { case QComboBox::InsertAtTop: index = 0; break; case QComboBox::InsertAtBottom: index = q->count(); break; case QComboBox::InsertAtCurrent: case QComboBox::InsertAfterCurrent: case QComboBox::InsertBeforeCurrent: if (!q->count() || !currentIndex.isValid()) index = 0; else if (insertPolicy == QComboBox::InsertAtCurrent) q->setItemText(q->currentIndex(), text); else if (insertPolicy == QComboBox::InsertAfterCurrent) index = q->currentIndex() + 1; else if (insertPolicy == QComboBox::InsertBeforeCurrent) index = q->currentIndex(); break; case QComboBox::NoInsert: default: break; } if (index >= 0) { q->insertItem(index, text); q->setCurrentIndex(index); emitActivated(currentIndex); } }}/* Handles auto completion.*/void QComboBoxPrivate::_q_complete(){ if (skipCompletion || !lineEdit || !autoCompletion) { skipCompletion = false; return; } QString text = lineEdit->text(); if (!text.isEmpty()) { Qt::MatchFlags flags(Qt::MatchWrap|Qt::MatchStartsWith); if (autoCompletionCaseSensitivity == Qt::CaseSensitive) flags |= Qt::MatchCaseSensitive; QModelIndexList list = model->match(currentIndex, Qt::EditRole, text, 1, flags); if (!list.count()) return; QString completed = model->data(list.first(), Qt::EditRole).toString(); int start = completed.length(); int length = text.length() - start; // negative length lineEdit->setText(completed); lineEdit->setSelection(start, length); }}void QComboBoxPrivate::_q_itemSelected(const QModelIndex &item){ Q_Q(QComboBox); if (item != currentIndex) { q->setCurrentIndex(item.row()); } else if (lineEdit) { lineEdit->selectAll(); lineEdit->setText(q->itemText(currentIndex.row())); } emitActivated(currentIndex);}void QComboBoxPrivate::emitActivated(const QModelIndex &index){ Q_Q(QComboBox); if (!index.isValid()) return; QString text(q->model()->data(index, Qt::EditRole).toString()); emit q->activated(index.row()); emit q->activated(text);}void QComboBoxPrivate::_q_emitHighlighted(const QModelIndex &index){ Q_Q(QComboBox); if (!index.isValid()) return; QString text(q->model()->data(index, Qt::EditRole).toString()); emit q->highlighted(index.row()); emit q->highlighted(text);}void QComboBoxPrivate::_q_emitCurrentIndexChanged(int index){ Q_Q(QComboBox); QModelIndex mi = q->model()->index(index, modelColumn, q->rootModelIndex()); QString text; if (mi.isValid()) text = q->model()->data(mi, Qt::EditRole).toString(); emit q->currentIndexChanged(index); emit q->currentIndexChanged(text);}/*! Destroys the combobox.*/QComboBox::~QComboBox(){ // ### check delegateparent and delete delegate if us? Q_D(QComboBox); disconnect(d->model, SIGNAL(destroyed()), this, SLOT(_q_modelDestroyed()));}/*! \property QComboBox::maxVisibleItems \brief the maximum allowed size on screen of the combobox This property is ignored for non-editable comboboxes in Mac style.*/int QComboBox::maxVisibleItems() const{ Q_D(const QComboBox); return d->maxVisibleItems;}void QComboBox::setMaxVisibleItems(int maxItems){ Q_D(QComboBox); if (maxItems > 0) d->maxVisibleItems = maxItems;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -