开发者

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

目录
  • 【正文开始】
    • 一、使用效果
    • 二、系统主题感知助手类(SystemThemeHelper)
    • 三、实现细节
    • 四、如何使用
  • 【结语】

    【正文开始】

    一、使用效果

    基于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.devze.com取当前设置,而不关心后续的变化。

    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.devze.com颜色和颜色方案

    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系统主题感知的资料请关注编程客栈(www.devze.com)其它相关文章!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜