English: README_EN.md
FluentUI3Style基于QProxyStyle实现,完整实现了FluentUI3 UI风格,使用到项目中超简单。通过编译成Qt样式插件,可直接在项目中使用app.setStyle("FluentUI3")来应用样式,无需手动加载库或链接源码。
本项目定位为样式库,目标是将 Qt 现有控件呈现为 FluentUI(WinUI3)风格。 由于 Qt 组件边界限制,部分 FluentUI 控件无法完全复刻;但会尽量基于现有控件,通过 Style 中的定制逻辑实现接近 FluentUI 的交互与视觉效果,例如:
- SwitchButton
- TabBar实现"Pivot"和"Segmented"控件
为了让 "Gallery" 展示更完整,会在 ExWidgets 下实现一些组件;这些组件的样式仍由 Style 统一绘制。 后续可能会增加其他控件,但都会保证这些组件能独立于Style之外运行。
ExWidgets 各控件的使用说明(接入方式、API 示例、数据格式约定)见:ExWidgets/README.md(English)
若想修改控件样式,只能通过以往使用QSS的方式,那样会使控件的QStyle样式消失。
如需深度定制,建议像本项目一样重写对应的 QStyle 逻辑,不过深度定制是【ElaWidgetTools】组件库的功能了,对于本项目不是很合适,本项目只是样式库。
所以如果需要统一样式,或者在统一样式下做一些小改动,推荐本项目。
最后,本项目是为了在现有项目中,或者希望简单集成FluentUI样式时使用而实现。
PS:关于本项目自定义控件的问题,如果不改源码的话,本项目没有提供自定义组件的功能,因为本项目写的样式Style与Qt自带的"windowsvista", "Windows", "Fusion"使用方式完全一致, 所以要自定义的话,就跟我们平常对Qt组件改样式的方法一样,qss或者定制qstyle。后续会使用对控件 setProperty的方式,放开一些属性可设。
祝各位Qter能做出完美的Qt程序。
- 自动部署:CMake 编译时可将样式插件拷贝到对应的 Qt 目录(见下方 CMake 选项
FLUENTUI3STYLE_COPY_TO_QT_DIR) - 即插即用:项目中使用时直接调用
app.setStyle("FluentUI3") - 无需依赖:不需要在项目中链接源码或手动加载库文件
| 方式 | 状态 | 说明 |
|---|---|---|
| CMake | ✅ 推荐、持续维护 | 与 examples/Gallery/CMakeLists.txt 等功能同步更新,日常开发请使用 CMake |
| qmake | 根目录 fluentw3uistyle.pro 仍保留,但不再与 CMake 同步维护,不保证与最新 Gallery / QWindowKit 行为一致 |
- 版本兼容性:样式库在 Qt 5.14.2、Qt 5.15.2、Qt 6.5.3、Qt 6.6.3(MSVC 环境)下测试正常
- 可选无边框组件:Qt ≥ 5.15.2 时默认构建
ExWidgets::Frameless(需 CMake ≥ 3.19);旧版 Qt 自动关闭。可显式设置EXWIDGETS_BUILD_FRAMELESS=OFF使基础ExWidgets不引入 QWindowKit。 - Qt 6.8+ 已知问题:
QMenu、QComboBox下拉等 Popup 弹窗的外阴影 在 Qt 6.8 及以上 可能显示异常(缺失、裁切、发脏或位置不对)。原因是:本样式对菜单/下拉弹层关闭了系统阴影(Qt::NoDropShadowWindowHint),并配合WA_TranslucentBackground在QStyle里 自绘多层阴影;而 Qt 6.8 起 Windows 平台对 半透明 Popup 窗口的合成与绘制区域 做了调整,弹窗实际可绘制区域、Alpha 混合与层叠顺序与旧版不一致,导致 Style 里手工绘制的阴影层无法像 Qt 6.6 及以前那样正确显示。该问题来自 Qt 平台层 + 自绘阴影方案 的叠加,并非单一控件逻辑错误;后续会在新版本 Qt 上继续适配。 - MinGW注意:在MinGW环境下,菜单弹出可能需要特殊处理
- 版本差异:不同Qt版本间的差异主要体现在右键菜单的显示效果上,可能存在渲染或布局的细微差别
- 兼容性建议:由于Qt版本众多且自身兼容性差异,建议在使用时针对具体版本进行适当调整。完全兼容所有Qt版本不现实,但会确保对Qt最新稳定版的支持
| Qt版本 | 样式库 | Gallery(CMake) | 窗口边框 |
|---|---|---|---|
| Qt5.14.2 | ✅ 支持 | ✅ 支持 | 系统边框(无 QWindowKit 无边框) |
| Qt5.15.2 | ✅ 支持 | ✅ 支持 | 可选 QWindowKit 无边框 + DWM 背景 |
| Qt6.6.3 | ✅ 支持 | ✅ 支持 | 可选 QWindowKit 无边框 + DWM 背景 |
| Qt6.8+ | Popup 菜单/下拉 外阴影 可能有 Bug(见上文说明) | ||
| Qt6.10 | 同上;样式代码基于 Qt 6.10 Win11 样式移植 |
ExWidgets::Frameless 的无边框窗口与 DWM 背景依赖 QWindowKit,子模块位于 3rd/qwindowkit/。
Qt ≥ 5.15.2 时该组件默认开启;设置 EXWIDGETS_BUILD_FRAMELESS=OFF 可跳过 QWindowKit 子模块。
若要启用无边框组件,git clone 后须初始化子模块,否则 CMake 会尝试查找系统安装的 QWindowKit package。
git clone --recursive https://github.com/XHY-ChuJian/FluentUIStyle.git
cd FluentUIStylegit pull
git submodule update --init --recursive注意: 日常
git pull不会自动更新子模块。仅在EXWIDGETS_BUILD_FRAMELESS=ON时需要 QWindowKit;找不到3rd/qwindowkit时请执行git submodule update --init --recursive。
其他第三方依赖(如 3rd/kissfft)已直接提交在仓库中,无需额外步骤。
- 操作系统:建议 Windows 10/11
- 编译器:MSVC(与 Qt 套件保持一致)
- Qt:建议使用已测试版本(如 Qt 6.6.3)
- CMake:基础组件建议 3.16+;无边框组件需 3.19+
说明:请确保
cmake、ninja(如使用)和 Qt 对应工具链在同一套环境中,避免出现“头文件版本与 moc 版本不一致”问题。
项目以 CMake 为准:CMakeLists.txt 与各子目录 CMakeLists.txt 会随功能更新;qmake 工程不再同步维护。
cd D:/workspace/Code/Github/Window11StyleQt 5.15.2 示例(须 64 位 MSVC Kit,Kit 名称含 64bit):
cmake -S . -B build -G Ninja -DCMAKE_PREFIX_PATH="D:/Qt/5.15.2/msvc2019_64" -DCMAKE_BUILD_TYPE=DebugQt 6 示例:
cmake -S . -B build -G "Visual Studio 17 2022" -A x64 -DCMAKE_PREFIX_PATH="D:/app/Qt/Qt6.6.3/6.6.3/msvc2019_64"如果你希望更明确地指定 Qt 包目录,也可以加上:
-DQt6_DIR="D:/app/Qt/Qt6.6.3/6.6.3/msvc2019_64/lib/cmake/Qt6"cmake --build build多配置生成器(Visual Studio)可使用:
cmake --build build --config Debug./build/bin/Galleryd.exe # Debug
./build/bin/Gallery.exe # ReleaseBUILD_LIBRARY:编译样式库(默认 ON)BUILD_PLUGIN:编译 Qt Style 插件(默认 ON)BUILD_GALLERY:编译 Gallery(默认 ON)EXWIDGETS_BUILD_FRAMELESS:编译ExWidgets::Frameless并引入 QWindowKit(Qt ≥ 5.15.2 默认 ON,旧版 Qt 默认 OFF)FLUENTUI3STYLE_COPY_TO_QT_DIR:构建后将插件复制到 Qt 的plugins/styles(默认 OFF,避免无权限写入 Qt 安装目录)
例如只编译库和插件、不编译示例:
cmake -S . -B build -DBUILD_GALLERY=OFF- 样式库 / 插件 / Gallery 均可通过 CMake 正常构建
- Gallery 不使用 QWindowKit,窗口为 系统边框 + 系统标题栏
- 无需初始化
3rd/qwindowkit子模块(若不编译依赖 QWindowKit 的目标)
根目录仍保留 fluentw3uistyle.pro,便于旧工程参考,但 不再与 CMake 同步更新,不保证包含最新 Gallery 功能(如 QWindowKit 无边框、AudiomaticMini 等)。
若仍需尝试:
cd D:/workspace/Code/Github/Window11Style
qmake fluentw3uistyle.pro
nmake新接入与日常开发请使用 CMake。
当启用插件构建时,构建脚本会自动把样式插件拷贝到 Qt 的 plugins/styles 目录。
如果你在自定义环境中使用,也可以手动将生成的插件复制到目标 Qt 环境的 plugins/styles 下。
下面是把 FluentUI3Style 接入到你自己的 Qt 项目的常见流程。
先按上面的 CMake 步骤完成构建。若开启 FLUENTUI3STYLE_COPY_TO_QT_DIR=ON,插件会复制到 Qt 的样式插件目录:
QT_INSTALL_PLUGINS/styles
同时会自动复制属性头文件到:
QT_INSTALL_HEADERS/FluentUI3Style/fluentui3styleproperties.h
如果 Qt 安装目录在受保护路径(例如
Program Files),复制阶段可能需要管理员权限。
应用启动后直接使用插件名启用:
QApplication app(argc, argv);
app.setStyle("FluentUI3");#include <FluentUI3Style/fluentui3styleproperties.h>
// 或者 include "fluentui3styleproperties.h"然后通过 setProperty 设置控件样式,不建议再写数字魔法值。
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
add_executable(MyApp main.cpp mainwindow.cpp)
target_link_libraries(MyApp PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets)只要运行环境能找到 FluentUI3 插件(plugins/styles 下),业务工程无需显式链接 FluentUI3Style 库即可使用 app.setStyle("FluentUI3")。
#include "fluentui3style.h"
QApplication app(argc, argv);
app.setStyle(new FluentUI3Style);适用场景:
- 你以源码或库形式集成样式
- 不依赖 Qt 插件机制
QApplication app(argc, argv);
app.setStyle("FluentUI3");适用场景:
- 已构建并部署
FluentUI3样式插件 - 希望主工程最少改动接入
#include "fluentuiappearance.h"
FluentUIAppearance::instance()->initialize();
QApplication app(argc, argv);适用场景:
- 需要更完整的外观初始化流程
- 需要统一主题/配色相关行为
FluentUI3Style通过属性设置的方式支持以下控件的FluentUI3风格:
| 控件类型 | 控件名称 | 说明 | 属性设置 |
|---|---|---|---|
| 按钮 | QPushButton | 普通按钮 | |
| 按钮 | QCheckBox | 复选框 | switchButton=true:启用开关按钮样式 |
| 按钮 | QRadioButton | 单选按钮 | |
| 输入控件 | QLineEdit | 文本框 | 支持底边线动画 |
| 输入控件 | QTextEdit | 文本编辑框 | |
| 输入控件 | QPlainTextEdit | 纯文本编辑框 | |
| 输入控件 | QSpinBox | 数字输入框 | spinBoxButtonLayout属性: 0:垂直箭头(默认) 1:水平两侧箭头 2:水平右侧箭头 3:水平两侧加减号 |
| 输入控件 | QDoubleSpinBox | 浮点数输入框 | spinBoxButtonLayout属性: 0:垂直箭头(默认) 1:水平两侧箭头 2:水平右侧箭头 3:水平两侧加减号 |
| 选择控件 | QComboBox | 下拉组合框 | 支持下拉动画和阴影效果 |
| 选择控件 | QListWidget | 列表框 | 支持选中指示器动画 |
| 选择控件 | QListView | 列表视图 | 支持选中指示器动画 |
| 滑块 | QSlider | 滑块 | 支持水平和垂直方向 |
| 进度条 | QProgressBar | 进度条 | progressBarStyle属性: 0:细条样式(默认) 1:粗条样式 2:环形样式 |
| 标签页 | QTabBar | 标签栏 | tabBarStyle属性: 1:Capsule 2:Pivot_Grow 3:Pivot_Slide 4:Pivot_Stretch 5:PillTabs 6:Segmented_Slide 7:Segmented_Fade 8:Navigation 9:Segmented_WinUI3 |
| 标签页 | QTabWidget | 标签页组件 | 继承QTabBar的样式设置 |
| 滚动条 | QScrollBar | 滚动条 | 支持水平和垂直方向 |
| 滚动条 | QScrollArea | 滚动区域 | |
| 菜单 | QMenu | 上下文菜单 | 支持阴影效果 |
| 菜单 | QMenuBar | 菜单栏 | |
| 对话框 | QMessageBox | 消息框 | |
| 对话框 | QFileDialog | 文件对话框 | |
| 工具栏 | QToolButton | 工具按钮 | 支持菜单箭头动画 |
| 工具栏 | QToolBar | 工具栏 | |
| 树形控件 | QTreeView | 树型视图 | 支持FluentUI导航控件样式 |
| 表格控件 | QTableView | 表格视图 | |
| 表格控件 | QTableWidget | 表格组件 |
建议优先使用 fluentui3styleproperties.h 里的属性名常量和枚举值,而不是直接写数字。
#include <FluentUI3Style/fluentui3styleproperties.h>
// ProgressBar:粗条样式
ui->progressBar->setProperty(ProgressBarStyleProperty, ProgressBarThick);
// TabBar:WinUI3 Segmented 样式
ui->tabBar->setProperty(TabBarStyleProperty, Segmented_WinUI3);
// TabBar:其他样式
pillBar->setProperty(TabBarStyleProperty, PillTabs);
capTabBar->setProperty(TabBarStyleProperty, Capsule);
navTabBar->setProperty(TabBarStyleProperty, Navigation);
// SpinBox 按钮布局(当前属性名仍是字符串)
ui->spinBox->setProperty("spinBoxButtonLayout", ArrowsVertical);
ui->spinBox->setProperty("spinBoxButtonLayout", ArrowsHorizontalSides);
ui->spinBox->setProperty("spinBoxButtonLayout", ArrowsHorizontalRight);
ui->spinBox->setProperty("spinBoxButtonLayout", PlusMinusHorizontalSides);
// CheckBox 开关样式
checkBox->setProperty(SwitchStyleProperty, true);常用属性速查:
TabBarStyleProperty:QTabBar风格(Capsule / Pivot / Segmented / Navigation)ProgressBarStyleProperty:QProgressBar风格(Thin / Thick / Ring)SwitchStyleProperty:QCheckBox切换开关样式ButtonAccentStyleProperty:按钮 Accent 色风格NavigationViewStyleProperty:导航指示器样式NoRoundedCorners:关闭圆角样式
#include "fluentui3style.h"
QApplication app(argc, argv);
app.setStyle(new FluentUI3Style);QApplication app(argc, argv);
app.setStyle("FluentUI3");#include "fluentuiappearance.h"
// 初始化FluentUI外观
FluentUIAppearance::instance()->initialize();
QApplication app(argc, argv);FluentUI3Style是基于Qt 6.10自带的Windows 11样式代码移植而来,在此基础上进行了大量的修复和优化:
- 修复了多个控件的显示问题
- 调整了控件大小和布局,使其更符合FluentUI3的设计规范
- 优化了动画效果和性能
- 增强了跨版本兼容性
- 其他问题
定义了完整的FluentUI3颜色体系,包括:
- Light主题颜色方案
- Dark主题颜色方案
- 各种状态下的控件颜色(默认、悬停、按下、禁用)
- 文本颜色
- 边框颜色
- 支持Fluent和Teams两种配色方案
使用Segoe Fluent Icons字体作为图标源,实现了FluentUI3风格的图标显示。
自动检测系统主题设置,在Windows 11上使用系统API获取当前主题,在其他系统上使用默认Light主题。
- BUILD_LIBRARY:编译为静态库(默认ON)
- BUILD_PLUGIN:编译为Qt插件(默认OFF)
- BUILD_GALLERY:编译 Gallery(默认ON)
- 支持更多FluentUI3控件
- 增强自定义主题能力
- 优化性能和动画效果
- 提供更多配色方案
本项目在界面布局与交互设计方面参考了以下优秀项目:
FluentUI3Style 采用 MIT 许可证开源,允许所有类型项目使用,但要求所有分发的软件中必须保留本项目的MIT授权许可;所有未保留授权分发的商业行为均将被视为侵权行为。