Style sheets: add placeholder text color property for edit widgets

The placeholder text was given its own QPalette color role in Qt 5.12,
but there has been no way to specify it from a Qt style sheet.

Fixes: QTBUG-93009
Change-Id: If58ca844c19c65b7eee14c6d5730a4ba27640c33
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Eirik Aavitsland 2022-09-16 15:29:10 +02:00
parent b6db79d82f
commit 72a3da3d4d
9 changed files with 53 additions and 10 deletions

View File

@ -12,6 +12,7 @@ MainWindow::MainWindow(QWidget *parent)
ui.setupUi(this); ui.setupUi(this);
ui.nameLabel->setProperty("class", "mandatory QLabel"); ui.nameLabel->setProperty("class", "mandatory QLabel");
ui.nameCombo->lineEdit()->setPlaceholderText(tr("Last, First"));
styleSheetEditor = new StyleSheetEditor(this); styleSheetEditor = new StyleSheetEditor(this);

View File

@ -59,6 +59,11 @@ QComboBox, QLineEdit, QSpinBox, QTextEdit, QListView {
selection-background-color: #C19A6B; selection-background-color: #C19A6B;
} }
/* Make placeholder text a matching semi-transparent color */
QComboBox, QLineEdit {
placeholder-text-color: #80C19A6B;
}
QListView { QListView {
show-decoration-selected: 1; show-decoration-selected: 1;
} }

View File

@ -128,6 +128,7 @@ static const QCssKnownValue properties[NumProperties - 1] = {
{ "padding-top", PaddingTop }, { "padding-top", PaddingTop },
{ "page-break-after", PageBreakAfter }, { "page-break-after", PageBreakAfter },
{ "page-break-before", PageBreakBefore }, { "page-break-before", PageBreakBefore },
{ "placeholder-text-color", QtPlaceHolderTextColor },
{ "position", Position }, { "position", Position },
{ "right", Right }, { "right", Right },
{ "selection-background-color", QtSelectionBackground }, { "selection-background-color", QtSelectionBackground },
@ -1340,7 +1341,7 @@ bool ValueExtractor::extractFont(QFont *font, int *fontSizeAdjustment)
return hit; return hit;
} }
bool ValueExtractor::extractPalette(QBrush *fg, QBrush *sfg, QBrush *sbg, QBrush *abg) bool ValueExtractor::extractPalette(QBrush *fg, QBrush *sfg, QBrush *sbg, QBrush *abg, QBrush *pfg)
{ {
bool hit = false; bool hit = false;
for (int i = 0; i < declarations.count(); ++i) { for (int i = 0; i < declarations.count(); ++i) {
@ -1350,6 +1351,7 @@ bool ValueExtractor::extractPalette(QBrush *fg, QBrush *sfg, QBrush *sbg, QBrush
case QtSelectionForeground: *sfg = decl.brushValue(pal); break; case QtSelectionForeground: *sfg = decl.brushValue(pal); break;
case QtSelectionBackground: *sbg = decl.brushValue(pal); break; case QtSelectionBackground: *sbg = decl.brushValue(pal); break;
case QtAlternateBackground: *abg = decl.brushValue(pal); break; case QtAlternateBackground: *abg = decl.brushValue(pal); break;
case QtPlaceHolderTextColor: *pfg = decl.brushValue(pal); break;
default: continue; default: continue;
} }
hit = true; hit = true;

View File

@ -166,6 +166,7 @@ enum Property {
LetterSpacing, LetterSpacing,
WordSpacing, WordSpacing,
TextDecorationColor, TextDecorationColor,
QtPlaceHolderTextColor,
NumProperties NumProperties
}; };
@ -823,7 +824,7 @@ struct Q_GUI_EXPORT ValueExtractor
bool extractBox(int *margins, int *paddings, int *spacing = nullptr); bool extractBox(int *margins, int *paddings, int *spacing = nullptr);
bool extractBorder(int *borders, QBrush *colors, BorderStyle *Styles, QSize *radii); bool extractBorder(int *borders, QBrush *colors, BorderStyle *Styles, QSize *radii);
bool extractOutline(int *borders, QBrush *colors, BorderStyle *Styles, QSize *radii, int *offsets); bool extractOutline(int *borders, QBrush *colors, BorderStyle *Styles, QSize *radii, int *offsets);
bool extractPalette(QBrush *fg, QBrush *sfg, QBrush *sbg, QBrush *abg); bool extractPalette(QBrush *fg, QBrush *sfg, QBrush *sbg, QBrush *abg, QBrush *pfg);
int extractStyleFeatures(); int extractStyleFeatures();
bool extractImage(QIcon *icon, Qt::Alignment *a, QSize *size); bool extractImage(QIcon *icon, Qt::Alignment *a, QSize *size);
bool extractIcon(QIcon *icon, QSize *size); bool extractIcon(QIcon *icon, QSize *size);

View File

@ -1849,3 +1849,6 @@ QTableView::indicator:unchecked {
* { widget-animation-duration: 100 } * { widget-animation-duration: 100 }
//! [162] //! [162]
//! [163]
QLineEdit { placeholder-text-color: #800000ff } /* semi-transparent blue */
//! [163]

View File

@ -732,6 +732,9 @@
subcontrol. By default, the arrow is placed in the center of the subcontrol. By default, the arrow is placed in the center of the
contents rectangle of the drop-down subcontrol. contents rectangle of the drop-down subcontrol.
The color of the placeholder text can be set using the
\l{#placeholder-text-color-prop}{placeholder-text-color} property.
See \l{Qt Style Sheets Examples#Customizing QComboBox}{Customizing QComboBox} See \l{Qt Style Sheets Examples#Customizing QComboBox}{Customizing QComboBox}
for an example. for an example.
@ -841,13 +844,16 @@
\row \row
\li QLineEdit \target qlineedit-widget \li QLineEdit \target qlineedit-widget
\li Support the \l{box model}. \li Supports the \l{box model}.
The color and background of the selected item is styled using The color and background of the selected item is styled using
\l{#selection-color-prop}{selection-color} and \l{#selection-color-prop}{selection-color} and
\l{#selection-background-color-prop}{selection-background-color} \l{#selection-background-color-prop}{selection-background-color}
respectively. respectively.
The color of the placeholder text can be set using the
\l{#placeholder-text-color-prop}{placeholder-text-color} property.
The password character can be styled using the The password character can be styled using the
\l{#lineedit-password-character-prop}{lineedit-password-character} \l{#lineedit-password-character-prop}{lineedit-password-character}
property. property.
@ -1202,6 +1208,9 @@
\l{#selection-background-color-prop}{selection-background-color} \l{#selection-background-color-prop}{selection-background-color}
respectively. respectively.
The color of the placeholder text can be set using the
\l{#placeholder-text-color-prop}{placeholder-text-color} property.
See \l{qabstractscrollarea-widget}{QAbsractScrollArea} to See \l{qabstractscrollarea-widget}{QAbsractScrollArea} to
style scrollable backgrounds. style scrollable backgrounds.
@ -2298,6 +2307,21 @@
\li Whether the QTreeView paints alternating row colors for the empty \li Whether the QTreeView paints alternating row colors for the empty
area (i.e the area where there are no items) area (i.e the area where there are no items)
\row
\li \b{\c placeholder-text-color*} \target placeholder-text-color-prop
\li \l{#Brush}{Brush} \br
\li The color used for the placeholder text of text editing widgets.
If this property is not set, the default value is whatever
is set for the palette's \l{QPalette::}{PlaceholderText}
role.
Example:
\snippet code/doc_src_stylesheet.qdoc 163
Available since 6.5.
\row \row
\li \b{\c position} \target position-prop \li \b{\c position} \target position-prop
\li \c relative \br \li \c relative \br

View File

@ -437,14 +437,15 @@ struct QStyleSheetBoxData : public QSharedData
struct QStyleSheetPaletteData : public QSharedData struct QStyleSheetPaletteData : public QSharedData
{ {
QStyleSheetPaletteData(const QBrush &fg, const QBrush &sfg, const QBrush &sbg, QStyleSheetPaletteData(const QBrush &fg, const QBrush &sfg, const QBrush &sbg,
const QBrush &abg) const QBrush &abg, const QBrush &pfg)
: foreground(fg), selectionForeground(sfg), selectionBackground(sbg), : foreground(fg), selectionForeground(sfg), selectionBackground(sbg),
alternateBackground(abg) { } alternateBackground(abg), placeholderForeground(pfg) { }
QBrush foreground; QBrush foreground;
QBrush selectionForeground; QBrush selectionForeground;
QBrush selectionBackground; QBrush selectionBackground;
QBrush alternateBackground; QBrush alternateBackground;
QBrush placeholderForeground;
}; };
struct QStyleSheetGeometryData : public QSharedData struct QStyleSheetGeometryData : public QSharedData
@ -956,10 +957,10 @@ QRenderRule::QRenderRule(const QList<Declaration> &declarations, const QObject *
bg = new QStyleSheetBackgroundData(brush, pixmap, repeat, alignment, origin, attachment, clip); bg = new QStyleSheetBackgroundData(brush, pixmap, repeat, alignment, origin, attachment, clip);
} }
QBrush sfg, fg; QBrush sfg, fg, pfg;
QBrush sbg, abg; QBrush sbg, abg;
if (v.extractPalette(&fg, &sfg, &sbg, &abg)) if (v.extractPalette(&fg, &sfg, &sbg, &abg, &pfg))
pal = new QStyleSheetPaletteData(fg, sfg, sbg, abg); pal = new QStyleSheetPaletteData(fg, sfg, sbg, abg, pfg);
QIcon imgIcon; QIcon imgIcon;
alignment = Qt::AlignCenter; alignment = Qt::AlignCenter;
@ -1486,6 +1487,8 @@ void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const Q
p->setBrush(cg, QPalette::HighlightedText, pal->selectionForeground); p->setBrush(cg, QPalette::HighlightedText, pal->selectionForeground);
if (pal->alternateBackground.style() != Qt::NoBrush) if (pal->alternateBackground.style() != Qt::NoBrush)
p->setBrush(cg, QPalette::AlternateBase, pal->alternateBackground); p->setBrush(cg, QPalette::AlternateBase, pal->alternateBackground);
if (pal->placeholderForeground.style() != Qt::NoBrush)
p->setBrush(cg, QPalette::PlaceholderText, pal->placeholderForeground);
} }
bool QRenderRule::hasModification() const bool QRenderRule::hasModification() const

View File

@ -1543,9 +1543,9 @@ void tst_QCssParser::gradient()
QList<QCss::StyleRule> rules = testSelector.styleRulesForNode(n); QList<QCss::StyleRule> rules = testSelector.styleRulesForNode(n);
QList<QCss::Declaration> decls = rules.at(0).declarations; QList<QCss::Declaration> decls = rules.at(0).declarations;
QCss::ValueExtractor ve(decls); QCss::ValueExtractor ve(decls);
QBrush fg, sfg; QBrush fg, sfg, pfg;
QBrush sbg, abg; QBrush sbg, abg;
QVERIFY(ve.extractPalette(&fg, &sfg, &sbg, &abg)); QVERIFY(ve.extractPalette(&fg, &sfg, &sbg, &abg, &pfg));
if (type == "linear") { if (type == "linear") {
QCOMPARE(sbg.style(), Qt::LinearGradientPattern); QCOMPARE(sbg.style(), Qt::LinearGradientPattern);
const QLinearGradient *lg = static_cast<const QLinearGradient *>(sbg.gradient()); const QLinearGradient *lg = static_cast<const QLinearGradient *>(sbg.gradient());

View File

@ -2354,6 +2354,10 @@ void tst_QStyleSheetStyle::placeholderColor()
phColor = le2.palette().placeholderText().color(); phColor = le2.palette().placeholderText().color();
QCOMPARE(phColor.rgb(), red.rgb()); QCOMPARE(phColor.rgb(), red.rgb());
QVERIFY(phColor.alpha() < red.alpha()); QVERIFY(phColor.alpha() < red.alpha());
const char *phSpec = "#aabbccdd";
le1.setStyleSheet(QString("QLineEdit { placeholder-text-color: %1; }").arg(phSpec));
QCOMPARE(le1.palette().placeholderText().color(), QColor(phSpec));
} }
void tst_QStyleSheetStyle::enumPropertySelector_data() void tst_QStyleSheetStyle::enumPropertySelector_data()