📄 qcombobox.cpp
字号:
/*! Sets the root model item \a index for the items in the combobox. \sa rootModelIndex()*/void QComboBox::setRootModelIndex(const QModelIndex &index){ Q_D(QComboBox); d->root = QPersistentModelIndex(index); view()->setRootIndex(index); update();}/*! \property QComboBox::currentIndex \brief the index of the current item in the combobox. The index can change when inserting or removing items. Returns -1 if no current item is set or the combobox is empty.*/int QComboBox::currentIndex() const{ Q_D(const QComboBox); return d->currentIndex.row();}void QComboBox::setCurrentIndex(int index){ Q_D(QComboBox); if (!model()) return; QModelIndex mi = model()->index(index, d->modelColumn, rootModelIndex()); if (mi == d->currentIndex) return; d->currentIndex = QPersistentModelIndex(mi); if (d->lineEdit) { d->lineEdit->setText(itemText(d->currentIndex.row())); d->updateLineEditGeometry(); } update(); d->_q_emitCurrentIndexChanged(d->currentIndex.row());}/*! \property QComboBox::currentText \brief the text of the current item*/QString QComboBox::currentText() const{ Q_D(const QComboBox); if (d->lineEdit) return d->lineEdit->text(); else if (d->currentIndex.isValid()) return model()->data(d->currentIndex, Qt::EditRole).toString(); else return QString();}/*! Returns the text for the given \a index in the combobox.*/QString QComboBox::itemText(int index) const{ Q_D(const QComboBox); QModelIndex mi = model()->index(index, d->modelColumn, rootModelIndex()); return model()->data(mi, Qt::EditRole).toString();}/*! Returns the icon for the given \a index in the combobox.*/QIcon QComboBox::itemIcon(int index) const{ Q_D(const QComboBox); QModelIndex item = model()->index(index, d->modelColumn, rootModelIndex()); return qvariant_cast<QIcon>(model()->data(item, Qt::DecorationRole));}/*! Returns the data for the given \a role in the given \a index in the combobox, or QVariant::Invalid if there is no data for this role.*/QVariant QComboBox::itemData(int index, int role) const{ Q_D(const QComboBox); QModelIndex mi = model()->index(index, d->modelColumn, rootModelIndex()); return model()->data(mi, role);}/*! \fn void QComboBox::insertItem(int index, const QString &text, const QVariant &userData) Inserts the \a text and \a userData into the combobox at the given \a index.*//*! Inserts the \a icon, \a text and \a userData into the combobox at the given \a index.*/void QComboBox::insertItem(int index, const QIcon &icon, const QString &text, const QVariant &userData){ Q_D(QComboBox); if (index < 0) index = 0; else if (index > count()) index = count(); if (index >= d->maxCount) return; QModelIndex item; disconnect(model(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(_q_rowsInserted(QModelIndex,int,int))); disconnect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); if (model()->insertRows(index, 1, rootModelIndex())) { item = model()->index(index, d->modelColumn, rootModelIndex()); QMap<int, QVariant> values; if (!text.isNull()) values.insert(Qt::EditRole, text); if (!icon.isNull()) values.insert(Qt::DecorationRole, icon); if (!userData.isNull()) values.insert(Qt::UserRole, userData); if (!values.isEmpty()) model()->setItemData(item, values); d->_q_rowsInserted(rootModelIndex(), index, index); } connect(model(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(_q_rowsInserted(QModelIndex,int,int))); connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); int mc = count(); if (mc > d->maxCount) model()->removeRows(mc - 1, mc - d->maxCount, rootModelIndex());}/*! Inserts the strings from the \a list into the combobox as separate items, starting at the \a index specified.*/void QComboBox::insertItems(int index, const QStringList &list){ Q_D(QComboBox); if (list.isEmpty()) return; if (index < 0) index = 0; else if (index < 0 || index > count()) index = count(); int insertCount = qMin(d->maxCount - index, list.count()); if (insertCount <= 0) return; disconnect(model(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(_q_rowsInserted(QModelIndex,int,int))); disconnect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); if (model()->insertRows(index, insertCount, rootModelIndex())) { QModelIndex item; for (int i = 0; i < insertCount; ++i) { item = model()->index(i+index, d->modelColumn, rootModelIndex()); model()->setData(item, list.at(i), Qt::EditRole); } d->_q_rowsInserted(rootModelIndex(), index, index + insertCount - 1); } connect(model(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(_q_rowsInserted(QModelIndex,int,int))); connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); int mc = count(); if (mc > d->maxCount) model()->removeRows(d->maxCount, mc - d->maxCount, rootModelIndex());}/*! Removes the item at the given \a index from the combobox. This will update the current index if the index is removed.*/void QComboBox::removeItem(int index){ Q_ASSERT(index >= 0 && index < count()); model()->removeRows(index, 1, rootModelIndex());}/*! Sets the \a text for the item on the given \a index in the combobox.*/void QComboBox::setItemText(int index, const QString &text){ Q_D(const QComboBox); QModelIndex item = model()->index(index, d->modelColumn, rootModelIndex()); if (item.isValid()) { model()->setData(item, text, Qt::EditRole); }}/*! Sets the \a icon for the item on the given \a index in the combobox.*/void QComboBox::setItemIcon(int index, const QIcon &icon){ Q_D(const QComboBox); QModelIndex item = model()->index(index, d->modelColumn, rootModelIndex()); if (item.isValid()) { model()->setData(item, icon, Qt::DecorationRole); }}/*! Sets the data \a role for the item on the given \a index in the combobox to the specified \a value.*/void QComboBox::setItemData(int index, const QVariant &value, int role){ Q_D(const QComboBox); QModelIndex item = model()->index(index, d->modelColumn, rootModelIndex()); if (item.isValid()) { model()->setData(item, value, role); }}/*! Returns the list view used for the combobox popup.*/QAbstractItemView *QComboBox::view() const{ Q_D(const QComboBox); return const_cast<QComboBoxPrivate*>(d)->viewContainer()->itemView();}/*! Sets the view to be used in the combobox popup to the given \a itemView. The combobox takes ownership of the view. Note: If you want to use the convenience views (like QListWidget, QTableWidget or QTreeWidget), make sure to call setModel() on the combobox with the convenience widgets model before calling this function.*/void QComboBox::setView(QAbstractItemView *itemView){ Q_D(QComboBox); Q_ASSERT(itemView); if (itemView->model() != d->model) itemView->setModel(d->model); d->viewContainer()->setItemView(itemView);}/*! \reimp*/QSize QComboBox::minimumSizeHint() const{ return sizeHint();}/*! \reimp This implementation caches the size hint to avoid resizing when the contents change dynamically. To invalidate the cached value change the \l sizeAdjustPolicy.*/QSize QComboBox::sizeHint() const{ Q_D(const QComboBox); if (d->sizeHint.isValid()) return d->sizeHint.expandedTo(QApplication::globalStrut()); bool hasIcon = false; const QFontMetrics &fm = fontMetrics(); // text width switch (d->sizeAdjustPolicy) { case AdjustToContents: case AdjustToContentsOnFirstShow: if (count() == 0) { d->sizeHint.rwidth() = 7 * fm.width(QChar('x')); } else { for (int i = 0; i < count(); ++i) { if (!itemIcon(i).isNull()) { hasIcon = true; d->sizeHint.setWidth(qMax(d->sizeHint.width(), fm.width(itemText(i)) + iconSize().width() + 4)); } else { d->sizeHint.setWidth(qMax(d->sizeHint.width(), fm.width(itemText(i)))); } } } break; case AdjustToMinimumContentsLength: // find out if we have any icons for (int i = 0; i < count() && !hasIcon; ++i) hasIcon = !itemIcon(i).isNull(); d->sizeHint.setWidth(d->minimumContentsLength*fm.width('X') + (hasIcon ? iconSize().width() + 4 : 0)); break; default: break; } // height d->sizeHint.setHeight(qMax(fm.lineSpacing(), 14) + 2); if (hasIcon) d->sizeHint.setHeight(qMax(d->sizeHint.height(), iconSize().height() + 2)); // add style and strut values QStyleOptionComboBox opt = d->getStyleOption(); d->sizeHint = style()->sizeFromContents(QStyle::CT_ComboBox, &opt, d->sizeHint, this); return d->sizeHint.expandedTo(QApplication::globalStrut());}/*! Displays the list of items in the combobox. If the list is empty then the no items will be shown.*/void QComboBox::showPopup(){ Q_D(QComboBox); if (count() <= 0) return; // set current item and select it view()->selectionModel()->setCurrentIndex(d->currentIndex, QItemSelectionModel::ClearAndSelect); QComboBoxPrivateContainer* container = d->viewContainer(); // use top item as height for complete listView int itemHeight = view()->sizeHintForIndex(model()->index(0, d->modelColumn, rootModelIndex())).height() + container->spacing(); QStyleOptionComboBox opt = d->getStyleOption(); QRect listRect(style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxListBoxPopup, this)); QRect screen = QApplication::desktop()->availableGeometry(this); QPoint below = mapToGlobal(listRect.bottomLeft()); int belowHeight = screen.bottom() - below.y(); QPoint above = mapToGlobal(listRect.topLeft()); int aboveHeight = above.y() - screen.y(); if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) listRect.setHeight(itemHeight * count()); else listRect.setHeight(itemHeight * qMin(d->maxVisibleItems, count())); listRect.setHeight(listRect.height() + 2*container->spacing() + style()->pixelMetric(QStyle::PM_DefaultFrameWidth) * 2); // make sure the widget fits on screen //### do horizontally as well if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) { listRect.moveTopLeft(above); QRect currentItemRect = view()->visualRect(view()->currentIndex()); if (listRect.height() < screen.height()) { listRect.moveTop(listRect.top() - currentItemRect.top()); } else { if ((listRect.top() - currentItemRect.top()) < screen.top()) { listRect.setTop(screen.top()); int valueToScroll = itemHeight * view()->currentIndex().row() - aboveHeight + 3; view()->verticalScrollBar()->setValue(valueToScroll); } else { listRect.moveTop(listRect.top() - currentItemRect.top()); } listRect.setBottom(qMin(listRect.bottom(), screen.bottom())); } } else if (listRect.height() <= belowHeight) { listRect.moveTopLeft(below); } else if (listRect.height() <= aboveHeight) { listRect.moveBottomLeft(above); } else if (belowHeight >= aboveHeight) { listRect.setHeight(belowHeight); listRect.moveTopLeft(below); } else { listRect.setHeight(aboveHeight); listRect.moveBottomLeft(above); }#ifndef QT_NO_IM if (QInputContext *qic = inputContext()) qic->reset();#endif container->setGeometry(listRect); view()->scrollTo(view()->currentIndex()); container->raise(); container->show(); view()->setFocus();}/*! Hides the list of items in the combobox if it is currently visible; otherwise this function does nothing.*/void QComboBox::hidePopup(){ Q_D(QComboBox); if (d->container && d->container->isVisible()) d->container->hide();#ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled() && isEditable() && hasFocus()) setEditFocus(true);#endif}/*! Clears the combobox, removing all items. Note: If you have set an external model on the combobox this model will still be cleared when calling this function.*/void QComboBox::clear(){ model()->removeRows(0, model()->rowCount(rootModelIndex()), rootModelIndex());}/*! \fn void QComboBox::clearValidator() Use setValidator(0) instead.*//*! Clears the contents of the line edit used for editing in the combobox.*/void QComboBox::clearEditText(){ Q_D(QComboBox); if (d->lineEdit) d->lineEdit->clear();}/*! Sets the \a text in the combobox's text edit.*/void QComboBox::setEditText(const QString &text){ Q_D(QComboBox); if (d->lineEdit) d->lineEdit->setText(text);}/*! \reimp*/void QComboBox::focusInEvent(QFocusEvent *e){ Q_D(QComboBox); update(); if (d->lineEdit) d->lineEdit->event(e);}/*! \reimp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -