diff --git a/examples/widgets/widgets/stylesheet/mainwindow.cpp b/examples/widgets/widgets/stylesheet/mainwindow.cpp index a2f477c83d7..a43613c757d 100644 --- a/examples/widgets/widgets/stylesheet/mainwindow.cpp +++ b/examples/widgets/widgets/stylesheet/mainwindow.cpp @@ -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); diff --git a/examples/widgets/widgets/stylesheet/qss/coffee.qss b/examples/widgets/widgets/stylesheet/qss/coffee.qss index 4571d42d7e2..8f72a15ee59 100644 --- a/examples/widgets/widgets/stylesheet/qss/coffee.qss +++ b/examples/widgets/widgets/stylesheet/qss/coffee.qss @@ -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; } diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index eff9ffbc8ca..48f388984be 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -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; diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h index cc50fb76b19..53399137d5f 100644 --- a/src/gui/text/qcssparser_p.h +++ b/src/gui/text/qcssparser_p.h @@ -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); diff --git a/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc b/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc index 6b4a472275d..d5050405907 100644 --- a/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc +++ b/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc @@ -1849,3 +1849,6 @@ QTableView::indicator:unchecked { * { widget-animation-duration: 100 } //! [162] +//! [163] +QLineEdit { placeholder-text-color: #800000ff } /* semi-transparent blue */ +//! [163] diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc index 46c28c5fc44..fc7193c7bd9 100644 --- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc @@ -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 diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index b64093ada53..7f22656fc8a 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -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 &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 diff --git a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp index 3b20068f175..31ca1ef4e7c 100644 --- a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp +++ b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp @@ -1543,9 +1543,9 @@ void tst_QCssParser::gradient() QList rules = testSelector.styleRulesForNode(n); QList 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(sbg.gradient()); diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index 62e253bd045..55918a11735 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -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()