当前位置: 代码网 > it编程>编程语言>C/C++ > 基于Qt实现系统主题感知功能

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

2024年12月30日 C/C++ 我要评论
【正文开始】一、使用效果二、系统主题感知助手类(systemthemehelper)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是两个不可用于绑定的方法,它们立即返回当前的主题颜色和颜色方案,但不会触发任何更新通知。这两个方法主要用于快速获取当前设置,而不关心后续的变化。

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
}

更新主题颜色和颜色方案

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

  • 构造函数与成员变量

    systemthemehelperprivate的构造函数接收一个指向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_colorschemesettings{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() << helper->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系统主题感知的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com