基于Qt實(shí)現(xiàn)系統(tǒng)主題感知功能
【正文開始】
一、使用效果

二、系統(tǒng)主題感知助手類(SystemThemeHelper)
SystemThemeHelper類是一個(gè)封裝了系統(tǒng)主題感知功能的Qt對象。它主要通過讀取系統(tǒng)設(shè)置和監(jiān)聽系統(tǒng)主題變化來更新應(yīng)用程序的主題顏色和顏色方案。
類定義與屬性
在
systemthemehelper.h中,SystemThemeHelper類繼承自QObject,并定義了兩個(gè)屬性:themeColor和colorScheme。這兩個(gè)屬性分別表示當(dāng)前的主題顏色和顏色方案(深色、淺色或無)。
class SystemThemeHelper : public QObject
{
Q_OBJECT
Q_PROPERTY(QColor themeColor READ themeColor NOTIFY themeColorChanged)
Q_PROPERTY(SystemThemeHelper::ColorScheme colorScheme READ colorScheme NOTIFY colorSchemeChanged)
// ...
};
ColorScheme是一個(gè)枚舉類,定義了三種顏色方案:None、Dark和Light。構(gòu)造函數(shù)與析構(gòu)函數(shù)
SystemThemeHelper的構(gòu)造函數(shù)初始化了一些私有成員變量,并啟動(dòng)了一個(gè)定時(shí)器,用于定期更新主題顏色和顏色方案。析構(gòu)函數(shù)則負(fù)責(zé)清理資源。
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()
{
// 清理資源
}
獲取主題顏色和顏色方案
getThemeColor和getColorScheme是兩個(gè)不可用于綁定的方法,它們立即返回當(dāng)前的主題顏色和顏色方案,但不會(huì)觸發(fā)任何更新通知。這兩個(gè)方法主要用于快速獲取當(dāng)前設(shè)置,而不關(guān)心后續(xù)的變化。
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
}
更新主題顏色和顏色方案
themeColor和colorScheme是兩個(gè)可用于綁定的方法,它們返回當(dāng)前的主題顏色和顏色方案,并在值發(fā)生變化時(shí)發(fā)出通知。這兩個(gè)方法內(nèi)部調(diào)用了私有成員函數(shù)的更新邏輯。
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;
}
設(shè)置窗口標(biāo)題欄模式
setWindowTitleBarMode方法允許設(shè)置窗口標(biāo)題欄的模式(深色或淺色)。這個(gè)方法在Windows平臺(tái)上通過調(diào)用 DWM API 實(shí)現(xiàn),而在其他平臺(tái)上則不支持。
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
}
定時(shí)器事件處理
timerEvent方法是一個(gè)虛函數(shù),用于處理定時(shí)器事件。它定期調(diào)用更新函數(shù)來檢查主題顏色和顏色方案是否發(fā)生變化,并在變化時(shí)發(fā)出通知。
void SystemThemeHelper::timerEvent(QTimerEvent *)
{
Q_D(SystemThemeHelper);
d->_updateThemeColor();
d->_updateColorScheme();
}
三、實(shí)現(xiàn)細(xì)節(jié)
SystemThemeHelperPrivate是SystemThemeHelper的私有實(shí)現(xiàn)類,它封裝了所有的實(shí)現(xiàn)細(xì)節(jié)和狀態(tài)變量。這個(gè)類主要負(fù)責(zé)讀取系統(tǒng)設(shè)置、更新主題顏色和顏色方案,并發(fā)出通知。
構(gòu)造函數(shù)與成員變量
SystemThemeHelperPrivate的構(gòu)造函數(shù)接收一個(gè)指向SystemThemeHelper的指針,并初始化成員變量。成員變量包括主題顏色、顏色方案、定時(shí)器和一些平臺(tái)特定的設(shè)置對象。
SystemThemeHelperPrivate::SystemThemeHelperPrivate(SystemThemeHelper *q)
: q_ptr(q)
{
// 初始化成員變量
}
更新函數(shù)
_updateThemeColor和_updateColorScheme是兩個(gè)更新函數(shù),它們檢查當(dāng)前的主題顏色和顏色方案是否發(fā)生變化,并在變化時(shí)更新成員變量并發(fā)出通知。
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();
}
}
平臺(tái)特定的實(shí)現(xiàn)
在Windows平臺(tái)上,SystemThemeHelperPrivate使用QSettings來讀取系統(tǒng)主題設(shè)置,并使用DWM API來設(shè)置窗口標(biāo)題欄的模式。這些實(shí)現(xiàn)細(xì)節(jié)被封裝在條件編譯塊中,以確??缙脚_(tái)的兼容性。
#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函數(shù)指針
}
#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
}
}
【結(jié)語】
通過SystemThemeHelper類,我們可以在 Qt 應(yīng)用程序中實(shí)現(xiàn)系統(tǒng)主題感知功能。
這個(gè)類封裝了讀取系統(tǒng)設(shè)置、更新主題顏色和顏色方案以及發(fā)出通知的邏輯,使得我們可以輕松地根據(jù)系統(tǒng)主題變化來調(diào)整應(yīng)用程序的外觀。
此外,通過條件編譯和平臺(tái)特定的實(shí)現(xiàn),還確保了跨平臺(tái)的兼容性。
以上就是基于Qt實(shí)現(xiàn)系統(tǒng)主題感知功能的詳細(xì)內(nèi)容,更多關(guān)于Qt系統(tǒng)主題感知的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++中運(yùn)算符 &和&&、|和|| 的詳解及區(qū)別
這篇文章主要介紹了C++中運(yùn)算符 &和&&、|和|| 的詳解及區(qū)別的相關(guān)資料,這里舉例說明該如何區(qū)別他們的不同,需要的朋友可以參考下2016-11-11
Qt實(shí)現(xiàn)生成指定范圍內(nèi)隨機(jī)數(shù)與隨機(jī)字符串
這篇文章主要為大家詳細(xì)介紹了如何利用Qt實(shí)現(xiàn)生成指定范圍內(nèi)隨機(jī)數(shù)與隨機(jī)字符串,文中的示例代碼簡潔易懂,感興趣的小伙伴可以自己動(dòng)手嘗試一下2023-07-07
C語言實(shí)現(xiàn)選擇題標(biāo)準(zhǔn)化考試系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)選擇題標(biāo)準(zhǔn)化考試系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
C++ 基于BFS算法的走迷宮自動(dòng)尋路的實(shí)現(xiàn)
這篇文章主要為大家介紹了C++ 基于BFS算法實(shí)現(xiàn)走迷宮自動(dòng)尋路,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11

