基于Qt实现系统主题感知功能

2024-12-30 03:50

本文主要是介绍基于Qt实现系统主题感知功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《基于Qt实现系统主题感知功能》在现代桌面应用程序开发中,系统主题感知是一项重要的功能,它使得应用程序能够根据用户的系统主题设置(如深色模式或浅色模式)自动调整其外观,Qt作为一个跨平台的C++图形用...

【正文开始】

一、使用效果

基于Qt实现系统主题感知功能

二、系统主题感知助手类(SystemThemeHelper)

SystemThemeHelper类是一个封装了系统主题感知功能的Qt对象。它主要通过读取系统设置和监听系统主题变化来更新应用程序的主题颜色和颜色方案。

  • 类定义与属性

    systemthemehelper.h中,SystemThemeHelper类继承自QObject,并定义了两个属性:themeColorcolorScheme。这两个属性分别表示当前的主题颜色和颜色方案(深色、浅色或无)。

class SystemThemeHelper : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QColor themeColor READ themeColor NOTIFY themeColorChanged)
    Q_PROPERTY(SystemThemeHelper::ColorScheme colorScheme READ colorScheme NOTIFY colorSchemeChanged)
    // ...
};
  • ColorScheme是一个枚举类,定义了三种颜色方案:NoneDarkLight

  • 构造函数与析构函数

    SystemThemeHelper的构造函数初始化了一些私有成员变量,并启动了一个定时器,用于定期更新主题颜色和颜色方案。析构函数则负责清理资源。

SystemThemeHelper::SystemThemeHelper(QObject *parent)
    : QObject{parent}, d_ptr(new SystemThemeHelperPrivate(this))
{
    Q_D(SystemThemeHelper);
    d->m_themeColor = getThemeColor();
    d->m_colorScheme = getColorScheme();
    d->m_timer.start(200, this);
    #ifdef Q_OS_WIN
    initializeFunctionPointers();
    #endif
}

SystemThemeHelper::~SystemThemeHelper()
{
    // 清理资源
}

获取主题颜色和颜色方案

getThemeColorgetColorScheme是两个不可用于绑定的方法,它们立即返回当前的主题颜色和颜色方案,但不会触发任何更新通知。这两个方法主要用于快速获http://www.chinasem.cn取当前设置,而不关心后续的变化。

QColor SystemThemeHelper::getThemeColor() const
{
    Q_D(const SystemThemeHelper);
    #ifdef Q_OS_WIN
    return QColor::fromRgb(d->m_themeColorSettings.value("ColorizationColor").toUInt());
    #endif
}

SystemThemeHelper::ColorScheme SystemThemeHelper::getColorScheme() const
{
    Q_D(const SystemThemeHelper);
    #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
    const auto scheme = QGuiApplication::styleHints()->colorScheme();
    return scheme == Qt::ColorScheme::Dark ? ColorScheme::Dark : ColorScheme::Light;
    #else
    #ifdef Q_OS_WIN
    return !d->m_colorSchemeSettings.value("AppsUseLightTheme").toBool() ? ColorScheme::Dark : ColorScheme::Light;
    #else //linux
    const QPalette defaultPalette;
    const auto text = defaultPalette.color(QPalette::WindowText);
    const auto window = defaultPalette.color(QPalette::Window);
    return text.lightness() > window.lightness() ? ColorScheme::Dark : ColorScheme::Light;
    #endif // Q_OS_WIN
    #endif // QT_VERSION
}

更新主题www.chinasem.cn颜色和颜色方案

themeColorcolorScheme是两个可用于绑定的方法,它们返回当前的主题颜色和颜色方案,并在值发生变化时发出通知。这两个方法内部调用了私有成员函数的更新逻辑。

QColor SystemThemeHelper::themeColor()
{
    Q_D(SystemThemeHelper);
    d->_updateThemeColor();
    return d->m_themeColor;
}

SystemThemeHelper::ColorScheme SystemThemeHelper::colorScheme()
{
    Q_D(SystemThemeHelper);
    d->_updateColorScheme();
    return d->m_colorScheme;
}

设置窗口标题栏模式

setWindowTitleBarMode方法允许设置窗口标题栏的模式(深色或浅色)。这个方法在Windows平台上通过调用 dwM API 实现,而在其他平台上则不支持。

bool SystemThemeHelper::setWindowTitleBarMode(QWindow *window, bool isDark)
{
    #ifdef Q_OS_WIN
    return bool(pDwmSetWindowAttribute ? !pDwmSetWindowAttribute(HWND(window->winId()), 20, &isDark, sizeof(BOOL)) : false);
    #else
    return false;
    #endif //Q_OS_WIN
}

定时器事件处理

timerEvent方法是一个虚函数,用于处理定时器事件。它定期调用更新函数来检查主题颜色和颜色方案是否发生变化,并在变化时发出通知。

void SystemThemeHelper::timerEvent(QTimerEvent *)
{
    Q_D(SystemThemeHelper);
    d->_updateThemeColor();
    d->_updateColorScheme();
}

三、实现细节

SystemThemeHelperPrivateSystemThemeHelper的私有实现类,它封装了所有的实现细节和状态变量。这个类主要负责读取系统设置、更新主题颜色和颜色方案,并发出通知。

  • 构造函数与成员变量

    SystemThemeHelperPrpythonivate的构造函数接收一个指向SystemThemeHelper的指针,并初始化成员变量。成员变量包括主题颜色、颜色方案、定时器和一些平台特定的设置对象。

SystemThemeHelperPrivate::SystemThemeHelperPrivate(SystemThemeHelper *q)
    : q_ptr(q)
{
    // 初始化成员变量
}

更新函数

_updateThemeColor_updateColorScheme是两个更新函数,它们检查当前的主题颜色和颜色方案是否发生变化,并在变化时更新成员变量并发出通知。

void SystemThemeHelperPrivate::_updateThemeColor()
{
    Q_Q(SystemThemeHelper);
    auto nowThemeColor = q->getThemeColor();
    if (nowThemeColor != m_themeColor) {
        m_themeColor = nowThemeColor;
        emit q->themeColorChanged();
    }
}

void SystemThemeHelperPrivate::_updateColorScheme()
{
    Q_Q(SystemThemeHelper);
    auto nowColorScheme = q->getColorScheme();
    if (nowColorScheme != m_colorScheme) {
        m_colorScheme = nowColorScheme;
        emit q->colorSchemeChanged();
    }
}

平台特定的实现

在Windows平台上,SystemThemeHelperPrivate使用QSettings来读取系统主题设置,并使用DWM API来设置窗口标题栏的模式。这些实现细节被封装在条件编译块中,以确保跨平台的兼容性。

#ifdef Q_OS_WIN
QSettings m_themeColorSettings{QSettings::UserScope, "Microsoft", "Windows\\DWM"};
QSettings m_colorSchemeandroidSettings{QSettings::UserScope, "Microsoft", "Windows\\CurrentVersion\\Themes\\Personalize"};
static DwmSetWindowAttributeFunc pDwmSetWindowAttribute = nullptr;
// ...
static inline bool initializeFunctionPointers()
{
    // 初始化DWM API函数指针
}
#endif //Q_OS_WIN

四、如何使用

C++:

	SystemThemeHelper *helper = new SystemThemeHelper;
    QObject::connect(helper, &SystemThemeHelper::themeColorChanged, [helper]{
        qDebug() << helper->getThemeColor();
    });
    QObject::connect(helper, &SystemThemeHelper::colorSchemeChanged, [helper]{
        qDebug() << heljsper->getColorScheme();
    });

Qml:

import QtQuick 2.15
import QtQuick.Window 2.15

import DelegateUI.Utils 1.0

Window {
    id: window
    width: 640
    height: 480
    visible: true
    title: qsTr("SystemThemeHelper Test - ") + (themeHelper.colorScheme == SystemThemeHelper.Dark ? "Dark" : "Light")
    color: themeHelper.colorScheme == SystemThemeHelper.Dark ? "black" : "white"

    Behavior on color { ColorAnimation { } }

    SystemThemeHelper {
        id: themeHelper
        onThemeColorChanged: {
            console.log("onThemeColorChanged:", themeColor);
        }
        onColorSchemeChanged: {
            setWindowTitleBarMode(window, themeHelper.colorScheme == SystemThemeHelper.Dark)
            console.log("onColorSchemeChanged:", colorScheme);
        }
        Component.onCompleted: {
            console.log("onColorSchemeChanged:", colorScheme);
            setWindowTitleBarMode(window, themeHelper.colorScheme == SystemThemeHelper.Dark)
        }
    }

    Text {
        anchors.centerIn: parent
        text: qsTr("主题颜色")
        font.family: "微软雅黑"
        font.pointSize: 32
        color: themeHelper.themeColor
    }
}

【结语】

通过SystemThemeHelper类,我们可以在 Qt 应用程序中实现系统主题感知功能。

这个类封装了读取系统设置、更新主题颜色和颜色方案以及发出通知的逻辑,使得我们可以轻松地根据系统主题变化来调整应用程序的外观。

此外,通过条件编译和平台特定的实现,还确保了跨平台的兼容性。

以上就是基于Qt实现系统主题感知功能的详细内容,更多关于Qt系统主题感知的资料请关注China编程(www.chinasem.cn)其它相关文章!

这篇关于基于Qt实现系统主题感知功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1152838

相关文章

QT Creator配置Kit的实现示例

《QTCreator配置Kit的实现示例》本文主要介绍了使用Qt5.12.12与VS2022时,因MSVC编译器版本不匹配及WindowsSDK缺失导致配置错误的问题解决,感兴趣的可以了解一下... 目录0、背景:qt5.12.12+vs2022一、症状:二、原因:(可以跳过,直奔后面的解决方法)三、解决方

Debian 13升级后网络转发等功能异常怎么办? 并非错误而是管理机制变更

《Debian13升级后网络转发等功能异常怎么办?并非错误而是管理机制变更》很多朋友反馈,更新到Debian13后网络转发等功能异常,这并非BUG而是Debian13Trixie调整... 日前 Debian 13 Trixie 发布后已经有众多网友升级到新版本,只不过升级后发现某些功能存在异常,例如网络转

MySQL中On duplicate key update的实现示例

《MySQL中Onduplicatekeyupdate的实现示例》ONDUPLICATEKEYUPDATE是一种MySQL的语法,它在插入新数据时,如果遇到唯一键冲突,则会执行更新操作,而不是抛... 目录1/ ON DUPLICATE KEY UPDATE的简介2/ ON DUPLICATE KEY UP

Python中Json和其他类型相互转换的实现示例

《Python中Json和其他类型相互转换的实现示例》本文介绍了在Python中使用json模块实现json数据与dict、object之间的高效转换,包括loads(),load(),dumps()... 项目中经常会用到json格式转为object对象、dict字典格式等。在此做个记录,方便后续用到该方

JWT + 拦截器实现无状态登录系统

《JWT+拦截器实现无状态登录系统》JWT(JSONWebToken)提供了一种无状态的解决方案:用户登录后,服务器返回一个Token,后续请求携带该Token即可完成身份验证,无需服务器存储会话... 目录✅ 引言 一、JWT 是什么? 二、技术选型 三、项目结构 四、核心代码实现4.1 添加依赖(pom

SpringBoot路径映射配置的实现步骤

《SpringBoot路径映射配置的实现步骤》本文介绍了如何在SpringBoot项目中配置路径映射,使得除static目录外的资源可被访问,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一... 目录SpringBoot路径映射补:springboot 配置虚拟路径映射 @RequestMapp

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

Java Kafka消费者实现过程

《JavaKafka消费者实现过程》Kafka消费者通过KafkaConsumer类实现,核心机制包括偏移量管理、消费者组协调、批量拉取消息及多线程处理,手动提交offset确保数据可靠性,自动提交... 目录基础KafkaConsumer类分析关键代码与核心算法2.1 订阅与分区分配2.2 拉取消息2.3