QComboBox: add property placeholderText
QComboBox had no option to tell the user that he must select an item - there was no placeholder text like e.g. in QLineEdit. This feature is widely used in html forms so we should support it also. Therefore add a new property 'placeholderText' to specify a text which should be shown when the current selected index is invalid. [ChangeLog][QtWidgets][QComboBox] QComboBox got a new property 'placeholderText' Change-Id: If6dac45c9f43455474e267907b0b0d893301c611 Fixes: QTBUG-1556 Fixes: QTBUG-2776 Fixes: QTBUG-77141 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
5abb976f23
commit
360df2cf74
@ -368,6 +368,8 @@ QSize QComboBoxPrivate::recomputeSizeHint(QSize &sh) const
|
|||||||
}
|
}
|
||||||
if (minimumContentsLength > 0)
|
if (minimumContentsLength > 0)
|
||||||
sh.setWidth(qMax(sh.width(), minimumContentsLength * fm.horizontalAdvance(QLatin1Char('X')) + (hasIcon ? iconSize.width() + 4 : 0)));
|
sh.setWidth(qMax(sh.width(), minimumContentsLength * fm.horizontalAdvance(QLatin1Char('X')) + (hasIcon ? iconSize.width() + 4 : 0)));
|
||||||
|
if (!placeholderText.isEmpty())
|
||||||
|
sh.setWidth(qMax(sh.width(), fm.boundingRect(placeholderText).width()));
|
||||||
|
|
||||||
|
|
||||||
// height
|
// height
|
||||||
@ -1110,8 +1112,9 @@ void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int
|
|||||||
q->updateGeometry();
|
q->updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
// set current index if combo was previously empty
|
// set current index if combo was previously empty and there is no placeholderText
|
||||||
if (start == 0 && (end - start + 1) == q->count() && !currentIndex.isValid()) {
|
if (start == 0 && (end - start + 1) == q->count() && !currentIndex.isValid() &&
|
||||||
|
placeholderText.isEmpty()) {
|
||||||
q->setCurrentIndex(0);
|
q->setCurrentIndex(0);
|
||||||
// need to emit changed if model updated index "silently"
|
// need to emit changed if model updated index "silently"
|
||||||
} else if (currentIndex.row() != indexBeforeChange) {
|
} else if (currentIndex.row() != indexBeforeChange) {
|
||||||
@ -1214,10 +1217,9 @@ void QComboBox::initStyleOption(QStyleOptionComboBox *option) const
|
|||||||
} else {
|
} else {
|
||||||
option->activeSubControls = d->hoverControl;
|
option->activeSubControls = d->hoverControl;
|
||||||
}
|
}
|
||||||
if (d->currentIndex.isValid()) {
|
option->currentText = currentText();
|
||||||
option->currentText = currentText();
|
if (d->currentIndex.isValid())
|
||||||
option->currentIcon = d->itemIcon(d->currentIndex);
|
option->currentIcon = d->itemIcon(d->currentIndex);
|
||||||
}
|
|
||||||
option->iconSize = iconSize();
|
option->iconSize = iconSize();
|
||||||
if (d->container && d->container->isVisible())
|
if (d->container && d->container->isVisible())
|
||||||
option->state |= QStyle::State_On;
|
option->state |= QStyle::State_On;
|
||||||
@ -1771,6 +1773,45 @@ void QComboBox::setIconSize(const QSize &size)
|
|||||||
updateGeometry();
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\property QComboBox::placeholderText
|
||||||
|
\brief Sets a \a placeholderText text shown when no valid index is set
|
||||||
|
|
||||||
|
The \a placeholderText will be shown when an invalid index is set. The
|
||||||
|
text is not accessible in the dropdown list. When this function is called
|
||||||
|
before items are added the placeholder text will be shown, otherwise you
|
||||||
|
have to call setCurrentIndex(-1) programmatically if you want to show the
|
||||||
|
placeholder text.
|
||||||
|
Set an empty placeholder text to reset the setting.
|
||||||
|
|
||||||
|
When the QComboBox is editable, use QLineEdit::setPlaceholderText()
|
||||||
|
instead.
|
||||||
|
|
||||||
|
\since 5.15
|
||||||
|
*/
|
||||||
|
void QComboBox::setPlaceholderText(const QString &placeholderText)
|
||||||
|
{
|
||||||
|
Q_D(QComboBox);
|
||||||
|
if (placeholderText == d->placeholderText)
|
||||||
|
return;
|
||||||
|
|
||||||
|
d->placeholderText = placeholderText;
|
||||||
|
if (currentIndex() == -1) {
|
||||||
|
if (d->placeholderText.isEmpty() && currentIndex() == -1)
|
||||||
|
setCurrentIndex(0);
|
||||||
|
else
|
||||||
|
update();
|
||||||
|
} else {
|
||||||
|
updateGeometry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QComboBox::placeholderText() const
|
||||||
|
{
|
||||||
|
Q_D(const QComboBox);
|
||||||
|
return d->placeholderText;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\property QComboBox::editable
|
\property QComboBox::editable
|
||||||
\brief whether the combo box can be edited by the user
|
\brief whether the combo box can be edited by the user
|
||||||
@ -2249,7 +2290,7 @@ QString QComboBox::currentText() const
|
|||||||
else if (d->currentIndex.isValid())
|
else if (d->currentIndex.isValid())
|
||||||
return d->itemText(d->currentIndex);
|
return d->itemText(d->currentIndex);
|
||||||
else
|
else
|
||||||
return QString();
|
return d->placeholderText;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -3079,6 +3120,9 @@ void QComboBox::paintEvent(QPaintEvent *)
|
|||||||
initStyleOption(&opt);
|
initStyleOption(&opt);
|
||||||
painter.drawComplexControl(QStyle::CC_ComboBox, opt);
|
painter.drawComplexControl(QStyle::CC_ComboBox, opt);
|
||||||
|
|
||||||
|
if (currentIndex() < 0)
|
||||||
|
opt.palette.setBrush(QPalette::ButtonText, opt.palette.brush(QPalette::ButtonText).color().lighter());
|
||||||
|
|
||||||
// draw the icon and text
|
// draw the icon and text
|
||||||
painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
|
painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,7 @@ class Q_WIDGETS_EXPORT QComboBox : public QWidget
|
|||||||
Q_PROPERTY(SizeAdjustPolicy sizeAdjustPolicy READ sizeAdjustPolicy WRITE setSizeAdjustPolicy)
|
Q_PROPERTY(SizeAdjustPolicy sizeAdjustPolicy READ sizeAdjustPolicy WRITE setSizeAdjustPolicy)
|
||||||
Q_PROPERTY(int minimumContentsLength READ minimumContentsLength WRITE setMinimumContentsLength)
|
Q_PROPERTY(int minimumContentsLength READ minimumContentsLength WRITE setMinimumContentsLength)
|
||||||
Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
|
Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
|
||||||
|
Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText)
|
||||||
|
|
||||||
#if QT_CONFIG(completer)
|
#if QT_CONFIG(completer)
|
||||||
#if QT_DEPRECATED_SINCE(5, 13)
|
#if QT_DEPRECATED_SINCE(5, 13)
|
||||||
@ -148,6 +149,9 @@ public:
|
|||||||
QSize iconSize() const;
|
QSize iconSize() const;
|
||||||
void setIconSize(const QSize &size);
|
void setIconSize(const QSize &size);
|
||||||
|
|
||||||
|
void setPlaceholderText(const QString &placeholderText);
|
||||||
|
QString placeholderText() const;
|
||||||
|
|
||||||
bool isEditable() const;
|
bool isEditable() const;
|
||||||
void setEditable(bool editable);
|
void setEditable(bool editable);
|
||||||
void setLineEdit(QLineEdit *edit);
|
void setLineEdit(QLineEdit *edit);
|
||||||
|
@ -417,6 +417,7 @@ public:
|
|||||||
int maxVisibleItems;
|
int maxVisibleItems;
|
||||||
int maxCount;
|
int maxCount;
|
||||||
int modelColumn;
|
int modelColumn;
|
||||||
|
QString placeholderText;
|
||||||
bool inserting;
|
bool inserting;
|
||||||
mutable QSize minimumSizeHint;
|
mutable QSize minimumSizeHint;
|
||||||
mutable QSize sizeHint;
|
mutable QSize sizeHint;
|
||||||
|
@ -397,6 +397,31 @@ void tst_QComboBox::getSetCheck()
|
|||||||
QCOMPARE(4, obj1.currentIndex()); // Valid
|
QCOMPARE(4, obj1.currentIndex()); // Valid
|
||||||
obj1.setCurrentIndex(INT_MAX);
|
obj1.setCurrentIndex(INT_MAX);
|
||||||
QCOMPARE(-1, obj1.currentIndex()); // Invalid => -1
|
QCOMPARE(-1, obj1.currentIndex()); // Invalid => -1
|
||||||
|
|
||||||
|
obj1.setIconSize(QSize(64, 32));
|
||||||
|
QCOMPARE(obj1.iconSize(), QSize(64, 32));
|
||||||
|
obj1.setIconSize(QSize());
|
||||||
|
const int iconWidth = obj1.style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, &obj1);
|
||||||
|
QCOMPARE(obj1.iconSize(), QSize(iconWidth, iconWidth));
|
||||||
|
|
||||||
|
const QString placeholderText("Please select");
|
||||||
|
obj1.setCurrentIndex(1);
|
||||||
|
obj1.setPlaceholderText(placeholderText);
|
||||||
|
QCOMPARE(obj1.placeholderText(), placeholderText);
|
||||||
|
QCOMPARE(obj1.currentText(), "2");
|
||||||
|
QCOMPARE(obj1.currentIndex(), 1);
|
||||||
|
obj1.setPlaceholderText(QString()); // should not change anything
|
||||||
|
QCOMPARE(obj1.placeholderText(), QString());
|
||||||
|
QCOMPARE(obj1.currentText(), "2");
|
||||||
|
|
||||||
|
obj1.clear();
|
||||||
|
obj1.setPlaceholderText(placeholderText);
|
||||||
|
obj1.addItems({"1", "2", "3", "4", "5"});
|
||||||
|
QCOMPARE(obj1.currentText(), placeholderText);
|
||||||
|
QCOMPARE(obj1.currentIndex(), -1);
|
||||||
|
obj1.setPlaceholderText(QString()); // should not change anything
|
||||||
|
QCOMPARE(obj1.currentText(), "1");
|
||||||
|
QCOMPARE(obj1.currentIndex(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef QList<QVariant> VariantList;
|
typedef QList<QVariant> VariantList;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user