当前位置: 首页 > article >正文

QT全局所有QSS样式实时切换

方法如下:

void loadQss(int qssType)
{
    QString name;
    if (qssType == 1)
        name = ":/qss/day.qss";
    else
        name = ":/qss/night.qss";
    QFile file(name);
    file.open(QFile::ReadOnly);
    QString qss;
    qss = file.readAll();
    qApp->setStyleSheet(qss);
    file.close();
}

为什么qApp->setStyleSheet(qss);可以做到全局所有样式实时切换,我来看下setStyleSheet的源码。

void QApplication::setStyleSheet(const QString& styleSheet)
{
    //将样式内容保存到内存,以备候用
    QApplicationPrivate::styleSheet = styleSheet;
    //获取当前应用程序的样式
    QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle*>(QApplicationPrivate::app_style);
    //第一个判断条件:如果传入样式为空,则保持当前应该用程序样式
    if (styleSheet.isEmpty()) { // application style sheet removed
        if (!proxy)
            return; // there was no stylesheet before
        setStyle(proxy->base);
    //如果应用程序已经设置了样式,则只是刷新样式,而不会使用函数传入的样式。
    //这也就告诉我们,为qApp设置样式前,需要卸载当前样式,之后安装样式才能生效
    } else if (proxy) { // style sheet update, just repolish
        proxy->repolish(qApp);
   //当前qApp没有样式,设置我们传进来的样式
    } else { // stylesheet set the first time
        QStyleSheetStyle *newProxy = new QStyleSheetStyle(QApplicationPrivate::app_style);
        QApplicationPrivate::app_style->setParent(newProxy);
        setStyle(newProxy);
    }
}
void QApplication::setStyle(QStyle *style)
{
    if (!style || style == QApplicationPrivate::app_style)
        return;

	//拿到所有控件,设置它们的样式。		
    QWidgetList all = allWidgets();

    // clean up the old style
    if (QApplicationPrivate::app_style) {
        if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
            for (QWidgetList::ConstIterator it = all.constBegin(), cend = all.constEnd(); it != cend; ++it) {
                QWidget *w = *it;
                if (!(w->windowType() == Qt::Desktop) &&        // except desktop
                     w->testAttribute(Qt::WA_WState_Polished)) { // has been polished
                     //清除所有老样式
                    QApplicationPrivate::app_style->unpolish(w);
                }
            }
        }
        QApplicationPrivate::app_style->unpolish(qApp);
    }

    QStyle *old = QApplicationPrivate::app_style; // save

    QApplicationPrivate::overrides_native_style =
        nativeStyleClassName() == QByteArray(style->metaObject()->className());

#ifndef QT_NO_STYLE_STYLESHEET
    if (!QApplicationPrivate::styleSheet.isEmpty() && !qobject_cast<QStyleSheetStyle *>(style)) {
        // we have a stylesheet already and a new style is being set
        QStyleSheetStyle *newProxy = new QStyleSheetStyle(style);
        style->setParent(newProxy);
        QApplicationPrivate::app_style = newProxy;
    } else
#endif // QT_NO_STYLE_STYLESHEET
        QApplicationPrivate::app_style = style;
    QApplicationPrivate::app_style->setParent(qApp); // take ownership

    // take care of possible palette requirements of certain gui
    // styles. Do it before polishing the application since the style
    // might call QApplication::setPalette() itself
    if (QApplicationPrivate::set_pal) {
        QApplication::setPalette(*QApplicationPrivate::set_pal);
    } else if (QApplicationPrivate::sys_pal) {
        clearSystemPalette();
        initSystemPalette();
        QApplicationPrivate::initializeWidgetPaletteHash();
        QApplicationPrivate::initializeWidgetFontHash();
        QApplicationPrivate::setPalette_helper(*QApplicationPrivate::sys_pal, /*className=*/0, /*clearWidgetPaletteHash=*/false);
    } else if (!QApplicationPrivate::sys_pal) {
        // Initialize the sys_pal if it hasn't happened yet...
        QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
    }

    // initialize the application with the new style
    //加载样式
    QApplicationPrivate::app_style->polish(qApp);

    // re-polish existing widgets if necessary
    if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
        for (QWidgetList::ConstIterator it = all.constBegin(), cend = all.constEnd(); it != cend; ++it) {
            QWidget *w = *it;
            if (w->windowType() != Qt::Desktop && w->testAttribute(Qt::WA_WState_Polished)) {
                if (w->style() == QApplicationPrivate::app_style)
                    QApplicationPrivate::app_style->polish(w);                // repolish
#ifndef QT_NO_STYLE_STYLESHEET
                else
                    w->setStyleSheet(w->styleSheet()); // touch
#endif
            }
        }

        for (QWidgetList::ConstIterator it = all.constBegin(), cend = all.constEnd(); it != cend; ++it) {
            QWidget *w = *it;
            if (w->windowType() != Qt::Desktop && !w->testAttribute(Qt::WA_SetStyle)) {
                    QEvent e(QEvent::StyleChange);
                    //将新样式应用到所有子控件中
                    QApplication::sendEvent(w, &e);
                    w->update();
            }
        }
    }

#ifndef QT_NO_STYLE_STYLESHEET
    if (QStyleSheetStyle *oldProxy = qobject_cast<QStyleSheetStyle *>(old)) {
        oldProxy->deref();
    } else
#endif
    if (old && old->parent() == qApp) {
        delete old;
    }

    if (QApplicationPrivate::focus_widget) {
        QFocusEvent in(QEvent::FocusIn, Qt::OtherFocusReason);
        QApplication::sendEvent(QApplicationPrivate::focus_widget->style(), &in);
        QApplicationPrivate::focus_widget->update();
    }
}

通过以上源码我们能看出在qApp的setStyleSheet中会拿到所有控件,清除旧的样式,然后加载新的样式,做到全局所有控件样式的动态切换。


http://www.kler.cn/a/537023.html

相关文章:

  • 搭建集成开发环境PyCharm
  • 【大数据技术】搭建完全分布式高可用大数据集群(Kafka)
  • 树莓派5添加摄像头 在C++下调用opencv
  • 【Linux】25.进程信号(1)
  • STM32的HAL库开发---高级定时器---输出比较模式实验
  • Baklib赋能数字内容体验个性化推荐提升用户体验的未来之路
  • 《机器学习数学基础》补充资料:秩-零化度定理
  • 【AI应用】免费的文本转语音工具:微软 Edge TTS 和 开源版 ChatTTS 对比
  • FPGA实现SDI视频缩放转UltraScale GTH光口传输,基于GS2971+Aurora 8b/10b编解码架构,提供2套工程源码和技术支持
  • flutter安卓打包签名
  • 客户端脚本安全设置:如何保障您的Web应用免受攻击?
  • DeepSeek与人工智能的结合:探索搜索技术的未来
  • 理解 Linux 文件结构:一份简单易懂的入门教程
  • 为什么要设计DTO类/什么时候设置DTO类?
  • 网络安全 纵向是什么意思 网络安全维度
  • qt部分核心机制
  • C#中的Dump:解锁程序调试新姿势
  • DeepSeek vs. ChatGPT:不同的诞生时间,对人工智能发展的不同影响
  • LabVIEW铅酸蓄电池测试系统
  • docker多个容器的相互通信
  • php7.3安装php7.3-gmp扩展踩坑总结
  • 2021 年 9 月青少年软编等考 C 语言五级真题解析
  • 自动生成ppt
  • C++ 编译 g++ -> make -> cmake
  • idea 找不到或者无法加载主类
  • 线性代数于工程应用中的实践:以代码实例拆解图像平滑问题的求解逻辑