QFluentWidgets: 基于 C++ Qt 的 Fluent Design 组件库
简介
QFluentWidgets 是一个基于 Qt 的 Fluent Designer 组件库,内置超过 150 个开箱即用的 Fluent Designer 组件,支持亮暗主题无缝切换和自定义主题色。搭配所见即所得的 Fluent Designer 软件,只需拖拖拽拽,不用编写一行 QSS,就能快速搭建现代化软件界面。
官网地址:https://qfluentwidgets.com/
仓库地址:https://github.com/zhiyiYo/PyQt-Fluent-Widgets
演示视频:https://www.bilibili.com/video/BV1o94y1a7Yv

编译示例
以 Qt5 为例(Qt6 也支持),从 Qt5 分支下载示例代码,将 libQFluentWidgets.dll、libFramlessHelperCore.dll 和 libFramelessHelperWidgets.dll 放在 lib 文件夹中,QFluentWidgets 头文件放在 include 文件夹中,项目结构如下图所示

接着在终端输入指令进行编译,其中 -DCMAKE_PREFIX_PATH 用于设置本机 Qt5 SDK 的路径:
cmake -B ./build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="D:/Qt/5.15.2/mingw81_64" -G "MinGW Makefiles" .
cd build
cmake --build . --config Release --target all --parallel
编译完成后可以在 build/bin 目录下看到所有生成的 exe 示例文件:

搭配 Fluent Designer
项目结构如下图所示:

其中 LoginWindow.py.ui 是使用 Fluent Designer 拖拽 PyQt-Fluent-Widgets 组件生成的 ui 文件,预览效果如下:

ui 代码如下,从 <customwidgets> 可以看到导入的组件来自 PyQt-Fluent-Widgets :
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
省略代码
</widget>
<customwidgets>
<customwidget>
<class>LineEdit</class>
<extends>QLineEdit</extends>
<header>qfluentwidgets</header>
</customwidget>
<customwidget>
<class>CheckBox</class>
<extends>QCheckBox</extends>
<header>qfluentwidgets</header>
</customwidget>
<customwidget>
<class>PrimaryPushButton</class>
<extends>QPushButton</extends>
<header>qfluentwidgets</header>
</customwidget>
<customwidget>
<class>HyperlinkButton</class>
<extends>QPushButton</extends>
<header>qfluentwidgets</header>
</customwidget>
<customwidget>
<class>BodyLabel</class>
<extends>QLabel</extends>
<header>qfluentwidgets</header>
</customwidget>
</customwidgets>
<resources>
<include location="login.qrc"/>
</resources>
<connections/>
</ui>
将该 ui 文件拖拽到 Fluent Studio 软件的设计师界面中,点击转换按钮,即可得到 C++ 组件库使用的 ui 文件。

项目使用的 CMakeLists.txt 代码如下:
set(DEMO_NAME LoginDemo)
cmake_minimum_required(VERSION 3.5)
project(${DEMO_NAME} VERSION 1.0)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
find_package(Qt5 COMPONENTS Widgets Multimedia REQUIRED)
# -----------------------------------------------------------------------------
file(GLOB inc_files ${CMAKE_SOURCE_DIR}/*.h)
file(GLOB src_files ${CMAKE_SOURCE_DIR}/*.cpp)
qt5_wrap_ui(UI_FILES ${CMAKE_SOURCE_DIR}/ui/LoginWindow.ui)
# add resource
SET(RCC_FILES ${CMAKE_SOURCE_DIR}/login.qrc)
qt5_add_resources(RCC_SOURCES ${RCC_FILES})
# 设置 dll 文件夹
link_directories(${CMAKE_SOURCE_DIR}/lib)
add_executable(${DEMO_NAME} ${src_files} ${inc_files} ${UI_FILES} ${RCC_SOURCES})
target_link_libraries(${PROJECT_NAME} PRIVATE Qt::Widgets QFluentWidgets FramelessHelperCore FramelessHelperWidgets)
# 设置头文件搜索路径
target_include_directories(${PROJECT_NAME}
PRIVATE
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/include/framelesshelper/include
${CMAKE_SOURCE_DIR}/include/framelesshelper/src/core
${CMAKE_SOURCE_DIR}/include/framelesshelper/src/widgets
${CMAKE_SOURCE_DIR}/include/framelesshelper/qmake/inc/core
)
# 拷贝 dll 到 bin 目录
configure_file(${CMAKE_SOURCE_DIR}/lib/libFramelessHelperCore.dll ${CMAKE_SOURCE_DIR}/build/bin/libFramelessHelperCore.dll COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/lib/libFramelessHelperWidgets.dll ${CMAKE_SOURCE_DIR}/build/bin/libFramelessHelperWidgets.dll COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/lib/libQFluentWidgets.dll ${CMAKE_SOURCE_DIR}/build/bin/libQFluentWidgets.dll COPYONLY)
main.cpp 代码如下,可以看到这里通过 #include "ui_LoginWindow.h" 和 ui->setupUi(this) 来使用 Fluent 组件初始化界面:
#include "ui_LoginWindow.h"
#include <FramelessHelper/Core/FramelessManager>
#include <FramelessHelper/Widgets/FramelessWidgetsHelper>
#include <FramelessHelper/Widgets/StandardSystemButton>
#include <framelessconfig_p.h>
#include <QApplication>
#include <QFluentWidgets/Common/FluentApp.h>
#include <QFluentWidgets/Common/Translator.h>
#include <QFluentWidgets/Window/FluentWindow.h>
using namespace qfluentwidgets;
FRAMELESSHELPER_USE_NAMESPACE
using namespace Global;
class Demo : public QWidget
{
Q_OBJECT
public:
Demo(QWidget *parent = nullptr) : QWidget(parent), ui(new Ui::Form), titleBar(new SplitTitleBar(this))
{
// 启用无边框
FramelessWidgetsHelper::get(this)->extendsContentIntoTitleBar();
// 设置主题色
setThemeColor("#28afe9");
// 初始化 UI
ui->setupUi(this);
setWindowIcon(QIcon(":/qfluentwidgets/images/logo.png"));
setWindowTitle("QFluentWidgets");
resize(1000, 650);
setStyleSheet("Demo{background: transparent}");
titleBar->titleLabel()->setStyleSheet(
"QLabel{ background: transparent; font: 13px 'Segoe UI'; padding: 0 4px; color: white}");
// 隐藏系统标题栏的最大化和最小化按钮
setWindowFlags(windowFlags() & ~Qt::WindowMinMaxButtonsHint & ~Qt::WindowCloseButtonHint);
// 设置标题栏
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
helper->setTitleBarWidget(titleBar);
helper->setSystemButton(titleBar->minButton(), SystemButtonType::Minimize);
helper->setSystemButton(titleBar->maxButton(), SystemButtonType::Maximize);
helper->setSystemButton(titleBar->closeButton(), SystemButtonType::Close);
titleBar->raise();
}
protected:
void resizeEvent(QResizeEvent *e)
{
QWidget::resizeEvent(e);
titleBar->resize(width(), titleBar->height());
}
private:
Ui::Form *ui;
SplitTitleBar *titleBar;
};
int main(int argc, char *argv[])
{
// enable dpi scale
#if (QT_VERSION > QT_VERSION_CHECK(5, 14, 0))
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication app(argc, argv);
// 启用云母效果
FramelessConfig::instance()->set(Option::EnableBlurBehindWindow);
FramelessConfig::instance()->set(Option::DisableLazyInitializationForMicaMaterial);
// 国际化
ftranslator.load(QLocale());
Demo w;
w.show();
return app.exec();
}
#include "main.moc"
编译指令不变,双击 build/bin/LoginWindow.exe 就能看到效果:

写在最后
C++ 组件库需要许可证才能拿到头文件和动态链接库使用,如果想体验运行效果,可以安装 Python 组件库并运行各个 demo.py,或者下载编译好的 PyQt-Fluent-Widgets-Gallery,最终效果和 C++ 是一样的。
经常有小伙伴留言为什么不将 C++ 组件库一起开源,其实原因很简单:白嫖的话有 Python 组件库就够了,一个人的精力是有限的,无法为爱发电维持这么多个组件库分支的开发,以上~~
QFluentWidgets: 基于 C++ Qt 的 Fluent Design 组件库的更多相关文章
- 如何用 Blazor 实现 Ant Design 组件库
本文主要分享我创建 Ant Design of Blazor 项目的心路历程,已经文末有一个 Blazor 线上分享预告. Blazor WebAssembly 来了! Blazor 这个新推出的前端 ...
- 基于Svelte3.x桌面端UI组件库Svelte UI
Svelte-UI,一套基于svelte.js开发的桌面pc端ui组件库 最近一直忙于写svelte-ui,一套svelte3开发的桌面端ui组件库.在设计及功能上借鉴了element-ui组件库.所 ...
- ve-plus:基于 vue3.x 桌面端UI组件库|vue3组件库
VE-Plus 自研轻量级 vue3.js 桌面pc端UI组件库 经过一个多月的筹划及开发,今天给大家带来一款全新的Vue3桌面端UI组件库VEPlus.新增了35+常用的组件,采用vue3 setu ...
- 【xingorg1-ui】基于vue3.0从0-1搭建组件库(一)环境配置与目录规划
npm地址 github源码 开篇-环境配置 环境配置: 使用vue-cli搭建项目框架,需要用vue3的话,得先把vue-cli的版本升级到vue-cli@5以上 npm install -g @v ...
- 基于 Vue.js 的移动端组件库mint-ui实现无限滚动加载更多
通过多次爬坑,发现了这些监听滚动来加载更多的组件的共同点, 因为这些加载更多的方法是绑定在需要加载更多的内容的元素上的, 所以是进入页面则直接触发一次,当监听到滚动事件之后,继续加载更多, 所以对于无 ...
- RSuite 一个基于 React.js 的 Web 组件库
RSuite http://rsuite.github.io RSuite 是一个基于 React.js 开发的 Web 组件库,参考 Bootstrap 设计,提供其中常用组件,支持响应式布局. 我 ...
- 基于Vue的npm组件库
前言(*❦ω❦) 思维导图可能有点高糊,有点太大了,项目和导图文件放到github或giteee上,这个思维导图也是我文章的架构,思维导图是用FeHelper插件生成的,这个是一款开源chrome插件 ...
- 16款优秀的Vue UI组件库推荐
16款优秀的Vue UI组件库推荐 Vue 是一个轻巧.高性能.可组件化的MVVM库,API简洁明了,上手快.从Vue推出以来,得到众多Web开发者的认可.在公司的Web前端项目开发中,多个项目采用基 ...
- Vue2.0+组件库总结
转自:https://blog.csdn.net/lishanleilixin/article/details/84025459 UI组件 element - 饿了么出品的Vue2的web UI工具套 ...
- 转:Vue2.0+组件库总结
UI组件 element - 饿了么出品的Vue2的web UI工具套件 Vux - 基于Vue和WeUI的组件库 mint-ui - Vue 2的移动UI元素 iview - 基于 Vuejs 的开 ...
随机推荐
- 在Istio中,到底怎么获取 Envoy 访问日志?
Envoy 访问日志记录了通过 Envoy 进行请求 / 响应交互的相关记录,可以方便地了解具体通信过程和调试定位问题. 环境准备 部署 httpbin 服务: kubectl apply -f sa ...
- 通用密钥,无需密码,在无密码元年实现Passkeys通用密钥登录(基于Django4.2/Python3.10)
毋庸讳言,密码是极其伟大的发明,但拜病毒和黑客所赐,一旦密码泄露,我们就得绞尽脑汁再想另外一个密码,但记忆力并不是一个靠谱的东西,一旦遗忘密码,也会造成严重的后果,2023年业界巨头Google已经率 ...
- docker-compose多服务器部署ELK
多服务器构建ELK es使用1主2从,logstash转发,kibana展现,本文ELK版本使用7.16.1 如果单机测试,请查看docker-compose单服务器部署ELK es-master:1 ...
- harbor 搭建和部署
Docker官方的Docker Registry镜像,可以用来储存和分发Docker镜像.不过实在不昨的,仅仅能储存和分发镜像,也不提供UI,你还得自己找一个过时的UI搭建,受限制于Docker Re ...
- Spring 的依赖注入(DI)
前言 欢迎来到本篇文章,书接上回,本篇说说 Spring 中的依赖注入,包括注入的方式,写法,该选择哪个注入方式以及可能出现的循环依赖问题等内容. 如果正在阅读的朋友还不清楚什么是「依赖」,建议先看看 ...
- 【WALT】WALT入口 update_task_ravg() 代码详解
目录 [WALT]WALT入口 update_task_ravg() 代码详解 代码展示 代码逻辑 ⑴ 判断是否进入 WALT 算法 ⑵ 获取 WALT 算法中上一个窗口的开始时间 ⑶ 如果任务刚初始 ...
- Python +selenium 自动化之元素定位
selenium之八大元素定位: 1.通过ID的方式定位 id是页面的唯一标识 例如:找到百度的搜索输入框 driver.findElement(By.id("kw")) 2.通 ...
- 2023年陕西彬州第八届半程马拉松赛153pb完赛
1.赛事背景 2023年6月3日,我参加了2023陕西彬州第八届半程马拉松赛,最终153完赛,PB了5分钟.起跑时间早上7点30分,毕竟6月天气也开始热了.天气预报显示当天还是小到中雨,上次铜川宜君半 ...
- hdfs小文件合并
HDFS small file merge 1.hive Settings There are 3 settings that should be configured before archivin ...
- LeetCode 周赛上分之旅 #35 两题坐牢,菜鸡现出原形
️ 本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 [BaguTree Pro] 知识星球提问. 学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思 ...