实现Windows系统标题栏颜色跟随主题动态切换

前言

使用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 转换
  • 弹窗窗口: 如果弹窗也需要跟随主题,需要对每个独立窗口调用
相关推荐
AI袋鼠帝7 小时前
Claude4.5+Gemini3 接管电脑桌面,这回是真无敌了..
人工智能·windows·aigc
獨枭7 小时前
Windows 下安装与使用 Miniconda 完整指南
windows
命里有定数9 小时前
保姆级教程:在 Windows (WSL2) 下本地部署 Qwen3-ASR
windows
lucky670712 小时前
Windows 上彻底卸载 Node.js
windows·node.js
编程小白202612 小时前
从 C++ 基础到效率翻倍:Qt 开发环境搭建与Windows 神级快捷键指南
开发语言·c++·windows·qt·学习
凯子坚持 c14 小时前
CANN 性能剖析实战:从原始事件到交互式火焰图
windows·microsoft
开开心心就好15 小时前
发票合并打印工具,多页布局设置实时预览
linux·运维·服务器·windows·pdf·harmonyos·1024程序员节
獨枭15 小时前
PyCharm 跑通 SAM 全流程实战
windows
仙剑魔尊重楼16 小时前
音乐制作电子软件FL Studio2025.2.4.5242中文版新功能介绍
windows·音频·录屏·音乐·fl studio
PHP小志16 小时前
Windows 服务器怎么修改密码和用户名?账户被系统锁定如何解锁
windows