Add attribute to enable font and palette propagation in QSS.
By default when using Qt Style Sheets, a widget does not inherit its font and palette from its parent widget. With the Qt::AA_UseStyleSheetPropagationInWidgetStyles application attribute set, propagation when using Qt Style Sheets behaves like it does with regular QWidget::setPalette() and QWidget::setFont() calls. [ChangeLog][QtWidgets] Added the Qt::AA_UseStyleSheetPropagationInWidgetStyles attribute which enables font and palette propagation for Qt Style Sheets. Task-number: QTBUG-37580 Change-Id: I3038c13d61e32625a1a05291c5394eaefd376a68 Reviewed-by: Samuel Nevala <samuel.nevala@intopalo.com> Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
This commit is contained in:
parent
aaab800e16
commit
7293200ace
@ -498,6 +498,7 @@ public:
|
|||||||
AA_ShareOpenGLContexts = 18,
|
AA_ShareOpenGLContexts = 18,
|
||||||
AA_SetPalette = 19,
|
AA_SetPalette = 19,
|
||||||
AA_NoHighDpiScaling = 20,
|
AA_NoHighDpiScaling = 20,
|
||||||
|
AA_UseStyleSheetPropagationInWidgetStyles = 21, // ### Qt 6: remove me
|
||||||
|
|
||||||
// Add new attributes before this line
|
// Add new attributes before this line
|
||||||
AA_AttributeCount
|
AA_AttributeCount
|
||||||
|
@ -213,6 +213,13 @@
|
|||||||
so this does not guarantee that QPaintDevice::devicePixelRatio() will
|
so this does not guarantee that QPaintDevice::devicePixelRatio() will
|
||||||
be equal to 1. This value has been added in Qt 5.6.
|
be equal to 1. This value has been added in Qt 5.6.
|
||||||
|
|
||||||
|
\value AA_UseStyleSheetPropagationInWidgetStyles By default, Qt Style Sheets
|
||||||
|
disable regular QWidget palette and font propagation. When this flag
|
||||||
|
is enabled, font and palette changes propagate as though the user had
|
||||||
|
manually called the corresponding QWidget methods. See
|
||||||
|
\l{The Style Sheet Syntax#Inheritance}{The Style Sheet Syntax - Inheritance}
|
||||||
|
for more details. This value has been added in Qt 5.7.
|
||||||
|
|
||||||
The following values are obsolete:
|
The following values are obsolete:
|
||||||
|
|
||||||
\value AA_ImmediateWidgetCreation This attribute is no longer fully
|
\value AA_ImmediateWidgetCreation This attribute is no longer fully
|
||||||
|
@ -138,3 +138,7 @@ emailEdit->setProperty("mandatoryField", true);
|
|||||||
QSpinBox *ageSpinBox = new QSpinBox(this);
|
QSpinBox *ageSpinBox = new QSpinBox(this);
|
||||||
ageSpinBox->setProperty("mandatoryField", true);
|
ageSpinBox->setProperty("mandatoryField", true);
|
||||||
//! [95]
|
//! [95]
|
||||||
|
|
||||||
|
//! [96]
|
||||||
|
qApp->setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, true);
|
||||||
|
//! [97]
|
||||||
|
@ -492,9 +492,9 @@
|
|||||||
\section1 Inheritance
|
\section1 Inheritance
|
||||||
|
|
||||||
In classic CSS, when font and color of an item is not explicitly set,
|
In classic CSS, when font and color of an item is not explicitly set,
|
||||||
it gets automatically inherited from the parent. When using Qt Style Sheets,
|
it gets automatically inherited from the parent. By default, when using
|
||||||
a widget does \b{not} automatically inherit its font and color setting
|
Qt Style Sheets, a widget does \b{not} automatically inherit its font
|
||||||
from its parent widget.
|
and color setting from its parent widget.
|
||||||
|
|
||||||
For example, consider a QPushButton inside a QGroupBox:
|
For example, consider a QPushButton inside a QGroupBox:
|
||||||
|
|
||||||
@ -507,9 +507,23 @@
|
|||||||
|
|
||||||
\snippet code/doc_src_stylesheet.cpp 25
|
\snippet code/doc_src_stylesheet.cpp 25
|
||||||
|
|
||||||
In contrast, setting a font and propagate using QWidget::setFont() and
|
In contrast, setting a font and palette using QWidget::setFont() and
|
||||||
QWidget::setPalette() propagates to child widgets.
|
QWidget::setPalette() propagates to child widgets.
|
||||||
|
|
||||||
|
If you would prefer that the font and palette propagate to child widgets,
|
||||||
|
you can set the Qt::AA_UseStyleSheetPropagationInWidgetStyles flag, like
|
||||||
|
this:
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
\snippet code/doc_src_stylesheet.cpp 96
|
||||||
|
|
||||||
|
When the widget-style font and palette propagation is enabled, font and
|
||||||
|
palette changes made through Qt Style Sheets will behave as though the
|
||||||
|
user had manually called the corresponding QWidget::setPalette() and
|
||||||
|
QWidget::setFont() methods on all of the QWidgets targeted by the style
|
||||||
|
sheet. If this would have caused propagation in C++, it will cause
|
||||||
|
propagation in style sheets and visa versa.
|
||||||
|
|
||||||
\section1 Widgets Inside C++ Namespaces
|
\section1 Widgets Inside C++ Namespaces
|
||||||
|
|
||||||
The Type Selector can be used to style widgets of a particular type. For
|
The Type Selector can be used to style widgets of a particular type. For
|
||||||
|
@ -1954,11 +1954,14 @@ void QWidgetPrivate::propagatePaletteChange()
|
|||||||
}
|
}
|
||||||
int mask = data.pal.resolve() | inheritedPaletteResolveMask;
|
int mask = data.pal.resolve() | inheritedPaletteResolveMask;
|
||||||
|
|
||||||
|
const bool useStyleSheetPropagationInWidgetStyles =
|
||||||
|
QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
|
||||||
|
|
||||||
QEvent pc(QEvent::PaletteChange);
|
QEvent pc(QEvent::PaletteChange);
|
||||||
QApplication::sendEvent(q, &pc);
|
QApplication::sendEvent(q, &pc);
|
||||||
for (int i = 0; i < children.size(); ++i) {
|
for (int i = 0; i < children.size(); ++i) {
|
||||||
QWidget *w = qobject_cast<QWidget*>(children.at(i));
|
QWidget *w = qobject_cast<QWidget*>(children.at(i));
|
||||||
if (w && !w->testAttribute(Qt::WA_StyleSheet)
|
if (w && (!w->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
|
||||||
&& (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
|
&& (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
|
||||||
QWidgetPrivate *wd = w->d_func();
|
QWidgetPrivate *wd = w->d_func();
|
||||||
wd->inheritedPaletteResolveMask = mask;
|
wd->inheritedPaletteResolveMask = mask;
|
||||||
@ -4543,15 +4546,19 @@ void QWidget::setPalette(const QPalette &palette)
|
|||||||
QPalette QWidgetPrivate::naturalWidgetPalette(uint inheritedMask) const
|
QPalette QWidgetPrivate::naturalWidgetPalette(uint inheritedMask) const
|
||||||
{
|
{
|
||||||
Q_Q(const QWidget);
|
Q_Q(const QWidget);
|
||||||
|
|
||||||
|
const bool useStyleSheetPropagationInWidgetStyles =
|
||||||
|
QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
|
||||||
|
|
||||||
QPalette naturalPalette = QApplication::palette(q);
|
QPalette naturalPalette = QApplication::palette(q);
|
||||||
if (!q->testAttribute(Qt::WA_StyleSheet)
|
if ((!q->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
|
||||||
&& (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
|
&& (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
|
||||||
#ifndef QT_NO_GRAPHICSVIEW
|
#ifndef QT_NO_GRAPHICSVIEW
|
||||||
|| (extra && extra->proxyWidget)
|
|| (extra && extra->proxyWidget)
|
||||||
#endif //QT_NO_GRAPHICSVIEW
|
#endif //QT_NO_GRAPHICSVIEW
|
||||||
)) {
|
)) {
|
||||||
if (QWidget *p = q->parentWidget()) {
|
if (QWidget *p = q->parentWidget()) {
|
||||||
if (!p->testAttribute(Qt::WA_StyleSheet)) {
|
if (!p->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles) {
|
||||||
if (!naturalPalette.isCopyOf(QApplication::palette())) {
|
if (!naturalPalette.isCopyOf(QApplication::palette())) {
|
||||||
QPalette inheritedPalette = p->palette();
|
QPalette inheritedPalette = p->palette();
|
||||||
inheritedPalette.resolve(inheritedMask);
|
inheritedPalette.resolve(inheritedMask);
|
||||||
@ -4687,15 +4694,19 @@ void QWidget::setFont(const QFont &font)
|
|||||||
QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const
|
QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const
|
||||||
{
|
{
|
||||||
Q_Q(const QWidget);
|
Q_Q(const QWidget);
|
||||||
|
|
||||||
|
const bool useStyleSheetPropagationInWidgetStyles =
|
||||||
|
QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
|
||||||
|
|
||||||
QFont naturalFont = QApplication::font(q);
|
QFont naturalFont = QApplication::font(q);
|
||||||
if (!q->testAttribute(Qt::WA_StyleSheet)
|
if ((!q->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
|
||||||
&& (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
|
&& (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
|
||||||
#ifndef QT_NO_GRAPHICSVIEW
|
#ifndef QT_NO_GRAPHICSVIEW
|
||||||
|| (extra && extra->proxyWidget)
|
|| (extra && extra->proxyWidget)
|
||||||
#endif //QT_NO_GRAPHICSVIEW
|
#endif //QT_NO_GRAPHICSVIEW
|
||||||
)) {
|
)) {
|
||||||
if (QWidget *p = q->parentWidget()) {
|
if (QWidget *p = q->parentWidget()) {
|
||||||
if (!p->testAttribute(Qt::WA_StyleSheet)) {
|
if (!p->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles) {
|
||||||
if (!naturalFont.isCopyOf(QApplication::font())) {
|
if (!naturalFont.isCopyOf(QApplication::font())) {
|
||||||
QFont inheritedFont = p->font();
|
QFont inheritedFont = p->font();
|
||||||
inheritedFont.resolve(inheritedMask);
|
inheritedFont.resolve(inheritedMask);
|
||||||
@ -4747,6 +4758,8 @@ void QWidgetPrivate::updateFont(const QFont &font)
|
|||||||
#ifndef QT_NO_STYLE_STYLESHEET
|
#ifndef QT_NO_STYLE_STYLESHEET
|
||||||
const QStyleSheetStyle* cssStyle;
|
const QStyleSheetStyle* cssStyle;
|
||||||
cssStyle = extra ? qobject_cast<const QStyleSheetStyle*>(extra->style) : 0;
|
cssStyle = extra ? qobject_cast<const QStyleSheetStyle*>(extra->style) : 0;
|
||||||
|
const bool useStyleSheetPropagationInWidgetStyles =
|
||||||
|
QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
data.fnt = QFont(font, q);
|
data.fnt = QFont(font, q);
|
||||||
@ -4771,7 +4784,7 @@ void QWidgetPrivate::updateFont(const QFont &font)
|
|||||||
if (w) {
|
if (w) {
|
||||||
if (0) {
|
if (0) {
|
||||||
#ifndef QT_NO_STYLE_STYLESHEET
|
#ifndef QT_NO_STYLE_STYLESHEET
|
||||||
} else if (w->testAttribute(Qt::WA_StyleSheet)) {
|
} else if (!useStyleSheetPropagationInWidgetStyles && w->testAttribute(Qt::WA_StyleSheet)) {
|
||||||
// Style sheets follow a different font propagation scheme.
|
// Style sheets follow a different font propagation scheme.
|
||||||
if (cssStyle)
|
if (cssStyle)
|
||||||
cssStyle->updateStyleSheetFont(w);
|
cssStyle->updateStyleSheetFont(w);
|
||||||
@ -4786,7 +4799,7 @@ void QWidgetPrivate::updateFont(const QFont &font)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_STYLE_STYLESHEET
|
#ifndef QT_NO_STYLE_STYLESHEET
|
||||||
if (cssStyle) {
|
if (!useStyleSheetPropagationInWidgetStyles && cssStyle) {
|
||||||
cssStyle->updateStyleSheetFont(q);
|
cssStyle->updateStyleSheetFont(q);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -10442,7 +10455,11 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
|
|||||||
|
|
||||||
d->reparentFocusWidgets(oldtlw);
|
d->reparentFocusWidgets(oldtlw);
|
||||||
setAttribute(Qt::WA_Resized, resized);
|
setAttribute(Qt::WA_Resized, resized);
|
||||||
if (!testAttribute(Qt::WA_StyleSheet)
|
|
||||||
|
const bool useStyleSheetPropagationInWidgetStyles =
|
||||||
|
QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
|
||||||
|
|
||||||
|
if (!useStyleSheetPropagationInWidgetStyles && !testAttribute(Qt::WA_StyleSheet)
|
||||||
&& (!parent || !parent->testAttribute(Qt::WA_StyleSheet))) {
|
&& (!parent || !parent->testAttribute(Qt::WA_StyleSheet))) {
|
||||||
d->resolveFont();
|
d->resolveFont();
|
||||||
d->resolvePalette();
|
d->resolvePalette();
|
||||||
|
@ -2556,7 +2556,13 @@ void QStyleSheetStyle::setPalette(QWidget *w)
|
|||||||
{ PseudoClass_Enabled, QPalette::Inactive }
|
{ PseudoClass_Enabled, QPalette::Inactive }
|
||||||
};
|
};
|
||||||
|
|
||||||
QPalette p = w->palette();
|
const bool useStyleSheetPropagationInWidgetStyles =
|
||||||
|
QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
|
||||||
|
|
||||||
|
QPalette p;
|
||||||
|
if (!useStyleSheetPropagationInWidgetStyles)
|
||||||
|
p = w->palette();
|
||||||
|
|
||||||
QWidget *ew = embeddedWidget(w);
|
QWidget *ew = embeddedWidget(w);
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
@ -2573,32 +2579,84 @@ void QStyleSheetStyle::setPalette(QWidget *w)
|
|||||||
rule.configurePalette(&p, map[i].group, ew, ew != w);
|
rule.configurePalette(&p, map[i].group, ew, ew != w);
|
||||||
}
|
}
|
||||||
|
|
||||||
styleSheetCaches->customPaletteWidgets.insert(w, w->palette());
|
if (!useStyleSheetPropagationInWidgetStyles || p.resolve() != 0) {
|
||||||
|
QPalette wp = w->palette();
|
||||||
|
styleSheetCaches->customPaletteWidgets.insert(w, qMakePair(wp, p.resolve()));
|
||||||
|
|
||||||
|
if (useStyleSheetPropagationInWidgetStyles) {
|
||||||
|
p = p.resolve(wp);
|
||||||
|
p.resolve(p.resolve() | wp.resolve());
|
||||||
|
}
|
||||||
|
|
||||||
w->setPalette(p);
|
w->setPalette(p);
|
||||||
if (ew != w)
|
if (ew != w)
|
||||||
ew->setPalette(p);
|
ew->setPalette(p);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QStyleSheetStyle::unsetPalette(QWidget *w)
|
void QStyleSheetStyle::unsetPalette(QWidget *w)
|
||||||
{
|
{
|
||||||
|
const bool useStyleSheetPropagationInWidgetStyles =
|
||||||
|
QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
|
||||||
|
|
||||||
if (styleSheetCaches->customPaletteWidgets.contains(w)) {
|
if (styleSheetCaches->customPaletteWidgets.contains(w)) {
|
||||||
QPalette p = styleSheetCaches->customPaletteWidgets.value(w);
|
QPair<QPalette, uint> p = styleSheetCaches->customPaletteWidgets.value(w);
|
||||||
w->setPalette(p);
|
styleSheetCaches->customPaletteWidgets.remove(w);
|
||||||
|
|
||||||
|
QPalette original = p.first;
|
||||||
|
|
||||||
|
if (useStyleSheetPropagationInWidgetStyles) {
|
||||||
|
original.resolve(original.resolve() & p.second);
|
||||||
|
|
||||||
|
QPalette wp = w->palette();
|
||||||
|
wp.resolve(wp.resolve() & ~p.second);
|
||||||
|
wp.resolve(original);
|
||||||
|
wp.resolve(wp.resolve() | original.resolve());
|
||||||
|
original = wp;
|
||||||
|
}
|
||||||
|
|
||||||
|
w->setPalette(original);
|
||||||
QWidget *ew = embeddedWidget(w);
|
QWidget *ew = embeddedWidget(w);
|
||||||
if (ew != w)
|
if (ew != w)
|
||||||
ew->setPalette(p);
|
ew->setPalette(original);
|
||||||
styleSheetCaches->customPaletteWidgets.remove(w);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (useStyleSheetPropagationInWidgetStyles) {
|
||||||
|
unsetStyleSheetFont(w);
|
||||||
|
QWidget *ew = embeddedWidget(w);
|
||||||
|
if (ew != w)
|
||||||
|
unsetStyleSheetFont(ew);
|
||||||
|
} else {
|
||||||
QVariant oldFont = w->property("_q_styleSheetWidgetFont");
|
QVariant oldFont = w->property("_q_styleSheetWidgetFont");
|
||||||
if (oldFont.isValid()) {
|
if (oldFont.isValid()) {
|
||||||
w->setFont(qvariant_cast<QFont>(oldFont));
|
w->setFont(qvariant_cast<QFont>(oldFont));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (styleSheetCaches->autoFillDisabledWidgets.contains(w)) {
|
if (styleSheetCaches->autoFillDisabledWidgets.contains(w)) {
|
||||||
embeddedWidget(w)->setAutoFillBackground(true);
|
embeddedWidget(w)->setAutoFillBackground(true);
|
||||||
styleSheetCaches->autoFillDisabledWidgets.remove(w);
|
styleSheetCaches->autoFillDisabledWidgets.remove(w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QStyleSheetStyle::unsetStyleSheetFont(QWidget *w) const
|
||||||
|
{
|
||||||
|
if (styleSheetCaches->customFontWidgets.contains(w)) {
|
||||||
|
QPair<QFont, uint> f = styleSheetCaches->customFontWidgets.value(w);
|
||||||
|
styleSheetCaches->customFontWidgets.remove(w);
|
||||||
|
|
||||||
|
QFont original = f.first;
|
||||||
|
original.resolve(original.resolve() & f.second);
|
||||||
|
|
||||||
|
QFont font = w->font();
|
||||||
|
font.resolve(font.resolve() & ~f.second);
|
||||||
|
font.resolve(original);
|
||||||
|
font.resolve(font.resolve() | original.resolve());
|
||||||
|
|
||||||
|
w->setFont(font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void updateObjects(const QList<const QObject *>& objects)
|
static void updateObjects(const QList<const QObject *>& objects)
|
||||||
{
|
{
|
||||||
if (!styleSheetCaches->styleRulesCache.isEmpty() || !styleSheetCaches->hasStyleRuleCache.isEmpty() || !styleSheetCaches->renderRulesCache.isEmpty()) {
|
if (!styleSheetCaches->styleRulesCache.isEmpty() || !styleSheetCaches->hasStyleRuleCache.isEmpty() || !styleSheetCaches->renderRulesCache.isEmpty()) {
|
||||||
@ -2658,6 +2716,7 @@ void QStyleSheetStyleCaches::objectDestroyed(QObject *o)
|
|||||||
hasStyleRuleCache.remove(o);
|
hasStyleRuleCache.remove(o);
|
||||||
renderRulesCache.remove(o);
|
renderRulesCache.remove(o);
|
||||||
customPaletteWidgets.remove((const QWidget *)o);
|
customPaletteWidgets.remove((const QWidget *)o);
|
||||||
|
customFontWidgets.remove(static_cast<QWidget *>(o));
|
||||||
styleSheetCache.remove(o);
|
styleSheetCache.remove(o);
|
||||||
autoFillDisabledWidgets.remove((const QWidget *)o);
|
autoFillDisabledWidgets.remove((const QWidget *)o);
|
||||||
}
|
}
|
||||||
@ -5846,9 +5905,26 @@ void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const
|
|||||||
// we should never override it.
|
// we should never override it.
|
||||||
if (w->objectName() == QLatin1String("qt_fontDialog_sampleEdit"))
|
if (w->objectName() == QLatin1String("qt_fontDialog_sampleEdit"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QWidget *container = containerWidget(w);
|
QWidget *container = containerWidget(w);
|
||||||
QRenderRule rule = renderRule(container, PseudoElement_None,
|
QRenderRule rule = renderRule(container, PseudoElement_None,
|
||||||
PseudoClass_Active | PseudoClass_Enabled | extendedPseudoClass(container));
|
PseudoClass_Active | PseudoClass_Enabled | extendedPseudoClass(container));
|
||||||
|
|
||||||
|
const bool useStyleSheetPropagationInWidgetStyles =
|
||||||
|
QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
|
||||||
|
|
||||||
|
if (useStyleSheetPropagationInWidgetStyles) {
|
||||||
|
unsetStyleSheetFont(w);
|
||||||
|
|
||||||
|
if (rule.font.resolve()) {
|
||||||
|
QFont wf = w->font();
|
||||||
|
styleSheetCaches->customFontWidgets.insert(w, qMakePair(wf, rule.font.resolve()));
|
||||||
|
|
||||||
|
QFont font = rule.font.resolve(wf);
|
||||||
|
font.resolve(wf.resolve() | rule.font.resolve());
|
||||||
|
w->setFont(font);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
QFont font = rule.font.resolve(w->font());
|
QFont font = rule.font.resolve(w->font());
|
||||||
|
|
||||||
if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
|
if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
|
||||||
@ -5865,6 +5941,7 @@ void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const
|
|||||||
QEvent e(QEvent::FontChange);
|
QEvent e(QEvent::FontChange);
|
||||||
QApplication::sendEvent(w, &e);
|
QApplication::sendEvent(w, &e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QStyleSheetStyle::saveWidgetFont(QWidget* w, const QFont& font) const
|
void QStyleSheetStyle::saveWidgetFont(QWidget* w, const QFont& font) const
|
||||||
{
|
{
|
||||||
|
@ -149,6 +149,7 @@ private:
|
|||||||
void unsetPalette(QWidget *);
|
void unsetPalette(QWidget *);
|
||||||
void setProperties(QWidget *);
|
void setProperties(QWidget *);
|
||||||
void setGeometry(QWidget *);
|
void setGeometry(QWidget *);
|
||||||
|
void unsetStyleSheetFont(QWidget *) const;
|
||||||
QVector<QCss::StyleRule> styleRules(const QObject *obj) const;
|
QVector<QCss::StyleRule> styleRules(const QObject *obj) const;
|
||||||
bool hasStyleRule(const QObject *obj, int part) const;
|
bool hasStyleRule(const QObject *obj, int part) const;
|
||||||
|
|
||||||
@ -178,9 +179,12 @@ public:
|
|||||||
QHash<const QObject *, QHash<int, bool> > hasStyleRuleCache;
|
QHash<const QObject *, QHash<int, bool> > hasStyleRuleCache;
|
||||||
typedef QHash<int, QHash<quint64, QRenderRule> > QRenderRules;
|
typedef QHash<int, QHash<quint64, QRenderRule> > QRenderRules;
|
||||||
QHash<const QObject *, QRenderRules> renderRulesCache;
|
QHash<const QObject *, QRenderRules> renderRulesCache;
|
||||||
QHash<const QWidget *, QPalette> customPaletteWidgets; // widgets whose palette we tampered
|
|
||||||
QHash<const void *, QCss::StyleSheet> styleSheetCache; // parsed style sheets
|
QHash<const void *, QCss::StyleSheet> styleSheetCache; // parsed style sheets
|
||||||
QSet<const QWidget *> autoFillDisabledWidgets;
|
QSet<const QWidget *> autoFillDisabledWidgets;
|
||||||
|
// widgets whose palettes and fonts we have tampered. stored value pair is
|
||||||
|
// QPair<old widget value, resolve mask of stylesheet value>
|
||||||
|
QHash<const QWidget *, QPair<QPalette, uint> > customPaletteWidgets;
|
||||||
|
QHash<const QWidget *, QPair<QFont, uint> > customFontWidgets;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ public:
|
|||||||
~tst_QStyleSheetStyle();
|
~tst_QStyleSheetStyle();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void init();
|
||||||
void repolish();
|
void repolish();
|
||||||
void numinstances();
|
void numinstances();
|
||||||
void widgetsBeforeAppStyleSheet();
|
void widgetsBeforeAppStyleSheet();
|
||||||
@ -71,8 +72,12 @@ private slots:
|
|||||||
void layoutSpacing();
|
void layoutSpacing();
|
||||||
#endif
|
#endif
|
||||||
void qproperty();
|
void qproperty();
|
||||||
|
void palettePropagation_data();
|
||||||
void palettePropagation();
|
void palettePropagation();
|
||||||
|
void fontPropagation_data();
|
||||||
void fontPropagation();
|
void fontPropagation();
|
||||||
|
void widgetStylePropagation_data();
|
||||||
|
void widgetStylePropagation();
|
||||||
void onWidgetDestroyed();
|
void onWidgetDestroyed();
|
||||||
void fontPrecedence();
|
void fontPrecedence();
|
||||||
void focusColors();
|
void focusColors();
|
||||||
@ -137,6 +142,12 @@ tst_QStyleSheetStyle::~tst_QStyleSheetStyle()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QStyleSheetStyle::init()
|
||||||
|
{
|
||||||
|
qApp->setStyleSheet(QString());
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, false);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QStyleSheetStyle::numinstances()
|
void tst_QStyleSheetStyle::numinstances()
|
||||||
{
|
{
|
||||||
QWidget w;
|
QWidget w;
|
||||||
@ -627,31 +638,80 @@ void tst_QStyleSheetStyle::namespaces()
|
|||||||
QCOMPARE(BACKGROUND(pb2), red);
|
QCOMPARE(BACKGROUND(pb2), red);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QStyleSheetStyle::palettePropagation_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("applicationStyleSheet");
|
||||||
|
QTest::addColumn<bool>("widgetStylePropagation");
|
||||||
|
QTest::newRow("Widget style propagation") << " " << true;
|
||||||
|
QTest::newRow("Widget style propagation, no application style sheet") << QString() << true;
|
||||||
|
QTest::newRow("Default propagation") << " " << false;
|
||||||
|
QTest::newRow("Default propagation, no application style sheet") << QString() << false;
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QStyleSheetStyle::palettePropagation()
|
void tst_QStyleSheetStyle::palettePropagation()
|
||||||
{
|
{
|
||||||
qApp->setStyleSheet("");
|
QFETCH(QString, applicationStyleSheet);
|
||||||
|
QFETCH(bool, widgetStylePropagation);
|
||||||
|
|
||||||
|
qApp->setStyleSheet(applicationStyleSheet);
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, widgetStylePropagation);
|
||||||
|
|
||||||
QGroupBox gb;
|
QGroupBox gb;
|
||||||
QPushButton *push = new QPushButton(&gb);
|
QLabel *label = new QLabel(&gb);
|
||||||
QPushButton &pb = *push;
|
QLabel &lb = *label;
|
||||||
push->setText("AsdF");
|
label->setText("AsdF");
|
||||||
|
|
||||||
gb.setStyleSheet("QGroupBox { color: red }");
|
gb.setStyleSheet("QGroupBox { color: red }");
|
||||||
QVERIFY(COLOR(gb) == Qt::red);
|
QCOMPARE(COLOR(gb), QColor(Qt::red));
|
||||||
QVERIFY(COLOR(pb) == APPCOLOR(pb)); // palette shouldn't propagate
|
|
||||||
gb.setStyleSheet("QGroupBox * { color: red }");
|
|
||||||
|
|
||||||
QVERIFY(COLOR(pb) == Qt::red);
|
if (widgetStylePropagation) {
|
||||||
QVERIFY(COLOR(gb) == APPCOLOR(gb));
|
QCOMPARE(COLOR(lb), QColor(Qt::red)); // palette should propagate in standard mode
|
||||||
|
} else {
|
||||||
|
QCOMPARE(COLOR(lb), APPCOLOR(lb)); // palette shouldn't propagate
|
||||||
|
}
|
||||||
|
|
||||||
QWidget window;
|
QWidget window;
|
||||||
|
lb.setParent(&window);
|
||||||
|
if (widgetStylePropagation) {
|
||||||
|
// In standard propagation mode, widgets that are not explicitly
|
||||||
|
// targeted do not have their propagated palette unset when they are
|
||||||
|
// unpolished by changing parents. This is consistent with regular Qt
|
||||||
|
// widgets, who also maintain their propagated palette when changing
|
||||||
|
// parents
|
||||||
|
QCOMPARE(COLOR(lb), QColor(Qt::red));
|
||||||
|
} else {
|
||||||
|
QCOMPARE(COLOR(lb), APPCOLOR(lb));
|
||||||
|
}
|
||||||
|
lb.setParent(&gb);
|
||||||
|
|
||||||
|
gb.setStyleSheet("QGroupBox * { color: red }");
|
||||||
|
|
||||||
|
QCOMPARE(COLOR(lb), QColor(Qt::red));
|
||||||
|
QCOMPARE(COLOR(gb), APPCOLOR(gb));
|
||||||
|
|
||||||
window.setStyleSheet("* { color: white; }");
|
window.setStyleSheet("* { color: white; }");
|
||||||
pb.setParent(&window);
|
lb.setParent(&window);
|
||||||
QVERIFY(COLOR(pb) == Qt::white);
|
QCOMPARE(COLOR(lb), QColor(Qt::white));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QStyleSheetStyle::fontPropagation_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("applicationStyleSheet");
|
||||||
|
QTest::addColumn<bool>("widgetStylePropagation");
|
||||||
|
QTest::newRow("Widget style propagation") << " " << true;
|
||||||
|
QTest::newRow("Widget style propagation, no application style sheet") << QString() << true;
|
||||||
|
QTest::newRow("Default propagation") << " " << false;
|
||||||
|
QTest::newRow("Default propagation, no application style sheet") << QString() << false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QStyleSheetStyle::fontPropagation()
|
void tst_QStyleSheetStyle::fontPropagation()
|
||||||
{
|
{
|
||||||
qApp->setStyleSheet("");
|
QFETCH(QString, applicationStyleSheet);
|
||||||
|
QFETCH(bool, widgetStylePropagation);
|
||||||
|
|
||||||
|
qApp->setStyleSheet(applicationStyleSheet);
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, widgetStylePropagation);
|
||||||
|
|
||||||
QComboBox cb;
|
QComboBox cb;
|
||||||
cb.addItem("item1");
|
cb.addItem("item1");
|
||||||
cb.addItem("item2");
|
cb.addItem("item2");
|
||||||
@ -661,7 +721,11 @@ void tst_QStyleSheetStyle::fontPropagation()
|
|||||||
|
|
||||||
cb.setStyleSheet("QComboBox { font-size: 20pt; }");
|
cb.setStyleSheet("QComboBox { font-size: 20pt; }");
|
||||||
QCOMPARE(FONTSIZE(cb), 20);
|
QCOMPARE(FONTSIZE(cb), 20);
|
||||||
|
if (widgetStylePropagation) {
|
||||||
|
QCOMPARE(FONTSIZE(*popup), 20);
|
||||||
|
} else {
|
||||||
QCOMPARE(FONTSIZE(*popup), viewFontSize);
|
QCOMPARE(FONTSIZE(*popup), viewFontSize);
|
||||||
|
}
|
||||||
QGroupBox gb;
|
QGroupBox gb;
|
||||||
QPushButton *push = new QPushButton(&gb);
|
QPushButton *push = new QPushButton(&gb);
|
||||||
QPushButton &pb = *push;
|
QPushButton &pb = *push;
|
||||||
@ -670,7 +734,11 @@ void tst_QStyleSheetStyle::fontPropagation()
|
|||||||
|
|
||||||
gb.setStyleSheet("QGroupBox { font-size: 20pt }");
|
gb.setStyleSheet("QGroupBox { font-size: 20pt }");
|
||||||
QCOMPARE(FONTSIZE(gb), 20);
|
QCOMPARE(FONTSIZE(gb), 20);
|
||||||
QVERIFY(FONTSIZE(pb) == buttonFontSize); // font does not propagate
|
if (widgetStylePropagation) {
|
||||||
|
QCOMPARE(FONTSIZE(pb), 20);
|
||||||
|
} else {
|
||||||
|
QCOMPARE(FONTSIZE(pb), buttonFontSize); // font does not propagate
|
||||||
|
}
|
||||||
gb.setStyleSheet("QGroupBox * { font-size: 20pt; }");
|
gb.setStyleSheet("QGroupBox * { font-size: 20pt; }");
|
||||||
QCOMPARE(FONTSIZE(gb), gbFontSize);
|
QCOMPARE(FONTSIZE(gb), gbFontSize);
|
||||||
QCOMPARE(FONTSIZE(pb), 20);
|
QCOMPARE(FONTSIZE(pb), 20);
|
||||||
@ -1796,6 +1864,138 @@ void tst_QStyleSheetStyle::styleSheetChangeBeforePolish()
|
|||||||
QVERIFY(testForColors(image2, QColor(0x00, 0xFF, 0x00)));
|
QVERIFY(testForColors(image2, QColor(0x00, 0xFF, 0x00)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QStyleSheetStyle::widgetStylePropagation_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("applicationStyleSheet");
|
||||||
|
QTest::addColumn<QString>("parentStyleSheet");
|
||||||
|
QTest::addColumn<QString>("childStyleSheet");
|
||||||
|
QTest::addColumn<QFont>("parentFont");
|
||||||
|
QTest::addColumn<QFont>("childFont");
|
||||||
|
QTest::addColumn<QPalette>("parentPalette");
|
||||||
|
QTest::addColumn<QPalette>("childPalette");
|
||||||
|
QTest::addColumn<int>("parentExpectedSize");
|
||||||
|
QTest::addColumn<int>("childExpectedSize");
|
||||||
|
QTest::addColumn<QColor>("parentExpectedColor");
|
||||||
|
QTest::addColumn<QColor>("childExpectedColor");
|
||||||
|
|
||||||
|
QFont noFont;
|
||||||
|
QFont font45; font45.setPointSize(45);
|
||||||
|
QFont font32; font32.setPointSize(32);
|
||||||
|
|
||||||
|
QPalette noPalette;
|
||||||
|
QPalette redPalette; redPalette.setColor(QPalette::WindowText, QColor("red"));
|
||||||
|
QPalette greenPalette; greenPalette.setColor(QPalette::WindowText, QColor("green"));
|
||||||
|
|
||||||
|
QLabel defaultLabel;
|
||||||
|
|
||||||
|
int defaultSize = defaultLabel.font().pointSize();
|
||||||
|
QColor defaultColor = defaultLabel.palette().color(defaultLabel.foregroundRole());
|
||||||
|
QColor redColor("red");
|
||||||
|
QColor greenColor("green");
|
||||||
|
|
||||||
|
// Check regular Qt propagation works as expected, with and without a
|
||||||
|
// non-interfering application stylesheet
|
||||||
|
QTest::newRow("defaults")
|
||||||
|
<< QString() << QString() << QString()
|
||||||
|
<< noFont << noFont << noPalette << noPalette
|
||||||
|
<< defaultSize << defaultSize << defaultColor << defaultColor;
|
||||||
|
QTest::newRow("parent font propagation, no application style sheet")
|
||||||
|
<< QString() << QString() << QString()
|
||||||
|
<< font45 << noFont << noPalette << noPalette
|
||||||
|
<< 45 << 45 << defaultColor << defaultColor;
|
||||||
|
QTest::newRow("parent font propagation, dummy application style sheet")
|
||||||
|
<< "QGroupBox { font-size: 64pt }" << QString() << QString()
|
||||||
|
<< font45 << noFont << noPalette << noPalette
|
||||||
|
<< 45 << 45 << defaultColor << defaultColor;
|
||||||
|
QTest::newRow("parent color propagation, no application style sheet")
|
||||||
|
<< QString() << QString() << QString()
|
||||||
|
<< noFont << noFont << redPalette << noPalette
|
||||||
|
<< defaultSize << defaultSize << redColor << redColor;
|
||||||
|
QTest::newRow("parent color propagation, dummy application style sheet")
|
||||||
|
<< "QGroupBox { color: blue }" << QString() << QString()
|
||||||
|
<< noFont << noFont << redPalette << noPalette
|
||||||
|
<< defaultSize << defaultSize << redColor << redColor;
|
||||||
|
|
||||||
|
// Parent style sheet propagates to child if child has not explicitly
|
||||||
|
// set a value
|
||||||
|
QTest::newRow("parent style sheet color propagation")
|
||||||
|
<< "#parentLabel { color: red }" << QString() << QString()
|
||||||
|
<< noFont << noFont << noPalette << noPalette
|
||||||
|
<< defaultSize << defaultSize << redColor << redColor;
|
||||||
|
QTest::newRow("parent style sheet font propagation")
|
||||||
|
<< "#parentLabel { font-size: 45pt }" << QString() << QString()
|
||||||
|
<< noFont << noFont << noPalette << noPalette
|
||||||
|
<< 45 << 45 << defaultColor << defaultColor;
|
||||||
|
|
||||||
|
// Parent style sheet does not propagate to child if child has explicitly
|
||||||
|
// set a value
|
||||||
|
QTest::newRow("parent style sheet color propagation, child explicitly set")
|
||||||
|
<< "#parentLabel { color: red }" << QString() << QString()
|
||||||
|
<< noFont << noFont << noPalette << greenPalette
|
||||||
|
<< defaultSize << defaultSize << redColor << greenColor;
|
||||||
|
QTest::newRow("parent style sheet font propagation, child explicitly set")
|
||||||
|
<< "#parentLabel { font-size: 45pt }" << QString() << QString()
|
||||||
|
<< noFont << font32 << noPalette << noPalette
|
||||||
|
<< 45 << 32 << defaultColor << defaultColor;
|
||||||
|
|
||||||
|
// Parent does not propagate to child when child is target of style sheet
|
||||||
|
QTest::newRow("parent style sheet font propagation, child application style sheet")
|
||||||
|
<< "#childLabel { font-size: 32pt }" << QString() << QString()
|
||||||
|
<< font45 << noFont << noPalette << noPalette
|
||||||
|
<< 45 << 32 << defaultColor << defaultColor;
|
||||||
|
QTest::newRow("parent style sheet color propagation, child application style sheet")
|
||||||
|
<< "#childLabel { color: green }" << QString() << QString()
|
||||||
|
<< noFont << noFont << redPalette << noPalette
|
||||||
|
<< defaultSize << defaultSize << redColor << greenColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QStyleSheetStyle::widgetStylePropagation()
|
||||||
|
{
|
||||||
|
QFETCH(QString, applicationStyleSheet);
|
||||||
|
QFETCH(QString, parentStyleSheet);
|
||||||
|
QFETCH(QString, childStyleSheet);
|
||||||
|
|
||||||
|
QFETCH(QFont, parentFont);
|
||||||
|
QFETCH(QFont, childFont);
|
||||||
|
QFETCH(QPalette, parentPalette);
|
||||||
|
QFETCH(QPalette, childPalette);
|
||||||
|
|
||||||
|
QFETCH(int, parentExpectedSize);
|
||||||
|
QFETCH(int, childExpectedSize);
|
||||||
|
QFETCH(QColor, parentExpectedColor);
|
||||||
|
QFETCH(QColor, childExpectedColor);
|
||||||
|
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, true);
|
||||||
|
|
||||||
|
qApp->setStyleSheet(applicationStyleSheet);
|
||||||
|
|
||||||
|
QLabel parentLabel;
|
||||||
|
parentLabel.setObjectName("parentLabel");
|
||||||
|
QLabel childLabel(&parentLabel);
|
||||||
|
childLabel.setObjectName("childLabel");
|
||||||
|
|
||||||
|
if (parentFont.resolve())
|
||||||
|
parentLabel.setFont(parentFont);
|
||||||
|
if (childFont.resolve())
|
||||||
|
childLabel.setFont(childFont);
|
||||||
|
if (parentPalette.resolve())
|
||||||
|
parentLabel.setPalette(parentPalette);
|
||||||
|
if (childPalette.resolve())
|
||||||
|
childLabel.setPalette(childPalette);
|
||||||
|
if (!parentStyleSheet.isEmpty())
|
||||||
|
parentLabel.setStyleSheet(parentStyleSheet);
|
||||||
|
if (!childStyleSheet.isEmpty())
|
||||||
|
childLabel.setStyleSheet(childStyleSheet);
|
||||||
|
|
||||||
|
parentLabel.ensurePolished();
|
||||||
|
childLabel.ensurePolished();
|
||||||
|
|
||||||
|
QCOMPARE(FONTSIZE(parentLabel), parentExpectedSize);
|
||||||
|
QCOMPARE(FONTSIZE(childLabel), childExpectedSize);
|
||||||
|
QCOMPARE(COLOR(parentLabel), parentExpectedColor);
|
||||||
|
QCOMPARE(COLOR(childLabel), childExpectedColor);
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QStyleSheetStyle)
|
QTEST_MAIN(tst_QStyleSheetStyle)
|
||||||
#include "tst_qstylesheetstyle.moc"
|
#include "tst_qstylesheetstyle.moc"
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user