QStyle *QWidget::style() const
{
Q_D(const QWidget);
if (d->extra && d->extra->style)
return d->extra->style;
return QApplication::style();
}
QStyle *QApplication::style()
{
if (!QApplicationPrivate::app_style) {
// Create default style
if (!qobject_cast<QApplication *>(QCoreApplication::instance())) {
Q_ASSERT(!"No style available without QApplication!");
return nullptr;
}
auto &defaultStyle = QApplicationPrivate::app_style;
defaultStyle = QStyleFactory::create(QApplicationPrivate::desktopStyleKey());
if (!defaultStyle) {
const QStringList styles = QStyleFactory::keys();
for (const auto &style : styles) {
if ((defaultStyle = QStyleFactory::create(style)))
break;
}
}
if (!defaultStyle) {
Q_ASSERT(!"No styles available!");
return nullptr;
}
// Take ownership of the style
defaultStyle->setParent(qApp);
QGuiApplicationPrivate::updatePalette();
#ifndef QT_NO_STYLE_STYLESHEET
if (!QApplicationPrivate::styleSheet.isEmpty()) {
qApp->setStyleSheet(QApplicationPrivate::styleSheet);
} else
#endif
{
defaultStyle->polish(qApp);
}
}
return QApplicationPrivate::app_style;
}
没有app_style时,会创建一个默认的style.
void QWidget::setStyle(QStyle *style)
{
Q_D(QWidget);
setAttribute(Qt::WA_SetStyle, style != nullptr);
d->createExtra();
#ifndef QT_NO_STYLE_STYLESHEET
if (QStyleSheetStyle *styleSheetStyle = qt_styleSheet(style)) {
//if for some reason someone try to set a QStyleSheetStyle, ref it
//(this may happen for exemple in QButtonDialogBox which propagates its style)
styleSheetStyle->ref();
d->setStyle_helper(style, false);
} else if (qt_styleSheet(d->extra->style) || !qApp->styleSheet().isEmpty()) {
// if we have an application stylesheet or have a proxy already, propagate
d->setStyle_helper(new QStyleSheetStyle(style), true);
} else
#endif
d->setStyle_helper(style, false);
}
void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate)
{
Q_Q(QWidget);
QStyle *oldStyle = q->style();
createExtra();
#ifndef QT_NO_STYLE_STYLESHEET
QPointer<QStyle> origStyle = extra->style;
#endif
extra->style = newStyle;
// repolish
if (polished && q->windowType() != Qt::Desktop) {
oldStyle->unpolish(q);
q->style()->polish(q);
}
if (propagate) {
// We copy the list because the order may be modified
const QObjectList childrenList = children;
for (int i = 0; i < childrenList.size(); ++i) {
QWidget *c = qobject_cast<QWidget*>(childrenList.at(i));
if (c)
c->d_func()->inheritStyle();
}
}
#ifndef QT_NO_STYLE_STYLESHEET
if (!qt_styleSheet(newStyle)) {
if (const QStyleSheetStyle* cssStyle = qt_styleSheet(origStyle)) {
cssStyle->clearWidgetFont(q);
}
}
#endif
QEvent e(QEvent::StyleChange);
QCoreApplication::sendEvent(q, &e);
#ifndef QT_NO_STYLE_STYLESHEET
// dereference the old stylesheet style
if (QStyleSheetStyle *proxy = qt_styleSheet(origStyle))
proxy->deref();
#endif
}
设置完style后, 发送StyleChange事件。
3.QPalette::ColorRole backgroundRole() const;
QPalette::ColorRole QWidget::backgroundRole() const
{
const QWidget *w = this;
do {
QPalette::ColorRole role = w->d_func()->bg_role;
if (role != QPalette::NoRole)
return role;
if (w->isWindow() || w->windowType() == Qt::SubWindow)
break;
w = w->parentWidget();
} while (w);
return QPalette::Window;
}
如果未设置显式背景角色,则QWidget继承其父QWidget背景角色。
4.void setBackgroundRole(QPalette::ColorRole);
void QWidget::setBackgroundRole(QPalette::ColorRole role)
{
Q_D(QWidget);
d->bg_role = role;
d->updateSystemBackground();
d->propagatePaletteChange();
d->updateIsOpaque();
}
void QWidgetPrivate::propagatePaletteChange()
{
Q_Q(QWidget);
// Propagate a new inherited mask to all children.
#if QT_CONFIG(graphicsview)
if (!q->parentWidget() && extra && extra->proxyWidget) {
QGraphicsProxyWidget *p = extra->proxyWidget;
inheritedPaletteResolveMask = p->d_func()->inheritedPaletteResolveMask | p->palette().resolveMask();
} else
#endif // QT_CONFIG(graphicsview)
if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) {
inheritedPaletteResolveMask = 0;
}
directPaletteResolveMask = data.pal.resolveMask();
auto mask = directPaletteResolveMask | inheritedPaletteResolveMask;
const bool useStyleSheetPropagationInWidgetStyles =
QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
QEvent pc(QEvent::PaletteChange);
QCoreApplication::sendEvent(q, &pc);
for (int i = 0; i < children.size(); ++i) {
QWidget *w = qobject_cast<QWidget*>(children.at(i));
if (w && (!w->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
&& (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
QWidgetPrivate *wd = w->d_func();
wd->inheritedPaletteResolveMask = mask;
wd->resolvePalette();
}
}
}
将此QWidget的调色板传播给所有子级控件。