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.nameLabel->setProperty("class", "mandatory QLabel");
ui.nameCombo->lineEdit()->setPlaceholderText(tr("Last, First"));
styleSheetEditor = new StyleSheetEditor(this);

View File

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

View File

@ -128,6 +128,7 @@ static const QCssKnownValue properties[NumProperties - 1] = {
{ "padding-top", PaddingTop },
{ "page-break-after", PageBreakAfter },
{ "page-break-before", PageBreakBefore },
{ "placeholder-text-color", QtPlaceHolderTextColor },
{ "position", Position },
{ "right", Right },
{ "selection-background-color", QtSelectionBackground },
@ -1340,7 +1341,7 @@ bool ValueExtractor::extractFont(QFont *font, int *fontSizeAdjustment)
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;
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 QtSelectionBackground: *sbg = decl.brushValue(pal); break;
case QtAlternateBackground: *abg = decl.brushValue(pal); break;
case QtPlaceHolderTextColor: *pfg = decl.brushValue(pal); break;
default: continue;
}
hit = true;

View File

@ -166,6 +166,7 @@ enum Property {
LetterSpacing,
WordSpacing,
TextDecorationColor,
QtPlaceHolderTextColor,
NumProperties
};
@ -823,7 +824,7 @@ struct Q_GUI_EXPORT ValueExtractor
bool extractBox(int *margins, int *paddings, int *spacing = nullptr);
bool extractBorder(int *borders, QBrush *colors, BorderStyle *Styles, QSize *radii);
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();
bool extractImage(QIcon *icon, Qt::Alignment *a, QSize *size);
bool extractIcon(QIcon *icon, QSize *size);

View File

@ -1849,3 +1849,6 @@ QTableView::indicator:unchecked {
* { widget-animation-duration: 100 }
//! [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
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}
for an example.
@ -841,13 +844,16 @@
\row
\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
\l{#selection-color-prop}{selection-color} and
\l{#selection-background-color-prop}{selection-background-color}
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
\l{#lineedit-password-character-prop}{lineedit-password-character}
property.
@ -1202,6 +1208,9 @@
\l{#selection-background-color-prop}{selection-background-color}
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
style scrollable backgrounds.
@ -2298,6 +2307,21 @@
\li Whether the QTreeView paints alternating row colors for the empty
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
\li \b{\c position} \target position-prop
\li \c relative \br

View File

@ -437,14 +437,15 @@ struct QStyleSheetBoxData : public QSharedData
struct QStyleSheetPaletteData : public QSharedData
{
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),
alternateBackground(abg) { }
alternateBackground(abg), placeholderForeground(pfg) { }
QBrush foreground;
QBrush selectionForeground;
QBrush selectionBackground;
QBrush alternateBackground;
QBrush placeholderForeground;
};
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);
}
QBrush sfg, fg;
QBrush sfg, fg, pfg;
QBrush sbg, abg;
if (v.extractPalette(&fg, &sfg, &sbg, &abg))
pal = new QStyleSheetPaletteData(fg, sfg, sbg, abg);
if (v.extractPalette(&fg, &sfg, &sbg, &abg, &pfg))
pal = new QStyleSheetPaletteData(fg, sfg, sbg, abg, pfg);
QIcon imgIcon;
alignment = Qt::AlignCenter;
@ -1486,6 +1487,8 @@ void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const Q
p->setBrush(cg, QPalette::HighlightedText, pal->selectionForeground);
if (pal->alternateBackground.style() != Qt::NoBrush)
p->setBrush(cg, QPalette::AlternateBase, pal->alternateBackground);
if (pal->placeholderForeground.style() != Qt::NoBrush)
p->setBrush(cg, QPalette::PlaceholderText, pal->placeholderForeground);
}
bool QRenderRule::hasModification() const

View File

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

View File

@ -2354,6 +2354,10 @@ void tst_QStyleSheetStyle::placeholderColor()
phColor = le2.palette().placeholderText().color();
QCOMPARE(phColor.rgb(), red.rgb());
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()