前言
使用Qt实现Windows桌面程序,如果使用了系统默认的标题栏,标题栏的颜色可能和软件UI的主题色不太搭配,如果还有不同主题的切换,那么修改系统标题栏颜色就是个必要的需求了,本文使用Windows接口实现系统标题栏颜色的自定义,然后配合在Qt中使用。

技术方案
推荐方案:使用 Windows DWM API
Windows 10 1809+ 和 Windows 11 支持通过 DwmSetWindowAttribute 函数设置标题栏颜色:
DWMWA_CAPTION_COLOR (35): 设置标题栏背景颜色DWMWA_TEXT_COLOR (36): 设置标题栏文字颜色DWMWA_USE_IMMERSIVE_DARK_MODE (20): 启用深色模式
代码实现
1. 创建 TitleBarHelper 工具类
// TitleBarHelper.h
#pragma once
#include <QObject>
#include <QWindow>
#include <QColor>
class TitleBarHelper : public QObject
{
Q_OBJECT
public:
explicit TitleBarHelper(QObject *parent = nullptr);
// 设置标题栏颜色
Q_INVOKABLE void setTitleBarColor(QWindow *window, const QColor &color);
// 设置标题栏文字颜色
Q_INVOKABLE void setTitleBarTextColor(QWindow *window, const QColor &color);
// 设置深色/浅色模式(影响系统按钮图标颜色)
Q_INVOKABLE void setDarkMode(QWindow *window, bool dark);
// 一键应用主题
Q_INVOKABLE void applyTheme(QWindow *window, int themeMode);
private:
bool setWindowAttribute(HWND hwnd, DWORD attribute, LPCVOID pvAttribute, DWORD cbAttribute);
};
2. 实现 TitleBarHelper.cpp
#include "TitleBarHelper.h"
#ifdef Q_OS_WIN
#include <windows.h>
#include <dwmapi.h>
#pragma comment(lib, "dwmapi.lib")
// Windows 11/10 1809+ DWM 属性
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
#endif
#ifndef DWMWA_CAPTION_COLOR
#define DWMWA_CAPTION_COLOR 35
#endif
#ifndef DWMWA_TEXT_COLOR
#define DWMWA_TEXT_COLOR 36
#endif
#endif
void TitleBarHelper::applyTheme(QWindow *window, int themeMode)
{
if (!window) return;
#ifdef Q_OS_WIN
HWND hwnd = (HWND)window->winId();
if (themeMode == 0) {
// 深色主题
setDarkMode(window, true);
setTitleBarColor(window, QColor("#2E2F33")); // titleBgClr for dark
setTitleBarTextColor(window, QColor("#FFFFFF"));
} else {
// 浅色主题
setDarkMode(window, false);
setTitleBarColor(window, QColor("#E4E3E3")); // titleBgClr for light
setTitleBarTextColor(window, QColor("#131A29"));
}
#endif
}
3. 注册到 QML
qmlRegisterType<TitleBarHelper>("Utils", 1, 0, "TitleBarHelper");
4. 在 QML 中使用
在 MainWindow.qml 中:
import VoiceAI.Utils 1.0
ApplicationWindow{
id: mainWindow
TitleBarHelper {
id: titleBarHelper
}
Component.onCompleted: {
// 初始化标题栏颜色
titleBarHelper.applyTheme(mainWindow, customizeSetting.getTheme())
}
onSigAppThemeChange: {
// 主题切换时更新标题栏颜色
titleBarHelper.applyTheme(mainWindow, themeMode)
}
}
5. 修改 .pro 文件
确保链接 dwmapi 库:
win32:{
LIBS += -ldwmapi
}
注意事项
- Windows版本兼容性: DWMWA_CAPTION_COLOR 需要 Windows 10 1809+,建议添加版本检测
- 颜色格式: DWM API 使用 COLORREF (0x00BBGGRR),需要从 QColor 转换
- 弹窗窗口: 如果弹窗也需要跟随主题,需要对每个独立窗口调用