Qt源码分析--QWidget(6)--Look and feel

59 篇文章 1 订阅
37 篇文章 1 订阅

1.QStyle *style() const;

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.

2.void setStyle(QStyle *);

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的调色板传播给所有子级控件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天天进步2015

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值