基于 C++ Qt 的 Fluent Design 组件库 QFluentWidgets

devtools/2025/2/27 17:32:03/

简介
QFluentWidgets 是一个基于 Qt 的 Fluent Designer 组件库,内置超过 150 个开箱即用的 Fluent Designer 组件,支持亮暗主题无缝切换和自定义主题色。
在这里插入图片描述

编译示例
以 Qt5 为例(Qt6 也支持),将 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 代码如下,从 可以看到导入的组件来自 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 C M A K E S O U R C E D I R / b u i l d / b i n / l i b F r a m e l e s s H e l p e r C o r e . d l l C O P Y O N L Y ) c o n f i g u r e f i l e ( {CMAKE_SOURCE_DIR}/build/bin/libFramelessHelperCore.dll COPYONLY) configure_file( CMAKESOURCEDIR/build/bin/libFramelessHelperCore.dllCOPYONLY)configurefile({CMAKE_SOURCE_DIR}/lib/libFramelessHelperWidgets.dll C M A K E S O U R C E D I R / b u i l d / b i n / l i b F r a m e l e s s H e l p e r W i d g e t s . d l l C O P Y O N L Y ) c o n f i g u r e f i l e ( {CMAKE_SOURCE_DIR}/build/bin/libFramelessHelperWidgets.dll COPYONLY) configure_file( CMAKESOURCEDIR/build/bin/libFramelessHelperWidgets.dllCOPYONLY)configurefile({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");// 初始化 UIui->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);
#endifQApplication::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++ 是一样的。


http://www.ppmy.cn/devtools/163120.html

相关文章

34.Java 阻塞队列(阻塞队列架构、阻塞队列分类、阻塞队列核心方法)

一、阻塞队列概述 java.util.concurrent 包下的 BlockingQueue 接口很好的解决了多线程中如何高效安全传输数据的问题&#xff0c;可以使用这些高效并且线程安全的队列类快速搭建高质量的多线程程序 阻塞队列通过一个共享的队列&#xff0c;使得数据由队列的一端输入&#xff…

保护密码等敏感信息的几个常用方法

概述 在生产环境&#xff0c;保护数据库账号密码等敏感信息是至关重要的&#xff0c;这些信息不能被所有研发工程师看见&#xff0c;本文介绍几种避免明文存储的常用方法。 方法1&#xff1a; 使用配置中心加密 适用场景&#xff1a;已采用配置中心&#xff08;如Spring Clou…

前端多个项目放在一个域名下如何配置打包文件

一、原因 当前端有三个项目&#xff0c;比如&#xff0c;大学生后台管理系统、大学生手机端网页、大学生电脑端网页&#xff0c;这三个项目想放在同一个域名下&#xff0c;此时就需要对项目打包配置进行更改&#xff0c;才能实现。 注&#xff1a;如果前端三个项目请求同一个后…

Redis面试宝典【刷题系列】

文章目录 一、什么是Redis&#xff1f;二、Redis相比Memcached有哪些优势&#xff1f;三、Redis支持的数据类型有哪些&#xff1f;四、Redis的主要消耗的物理资源是什么&#xff1f;五、Redis的全称是什么&#xff1f;六、Redis有哪些数据淘汰策略&#xff1f;七、为什么Redis需…

python爬虫学习第十一篇爬取指定类型数据

最近在学习Python爬虫的过程中&#xff0c;尝试用爬虫获取指定类型的数据。今天&#xff0c;我想和大家分享一下我的实践过程和遇到的问题。 一、实现目标 目标是从一个网站的API接口获取不同类型的食品数据。 比如&#xff0c;第一步我想获取汉堡、小食、甜品等不同类型的数…

计算机毕设-基于springboot的人工智能领域复合型人才校企协同培养管理系统的设计与实现(附源码+lw+ppt+开题报告)

博主介绍&#xff1a;✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围&#xff1a;Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…

大白话css第二章深入学习

CSS学习第二阶段主要是深入掌握一些更复杂、更实用的知识和技能&#xff0c;以下用大白话为你详细介绍并给出代码示例&#xff1a; 盒模型与布局 盒模型深入理解 解释&#xff1a;前面说过每个HTML元素像个盒子&#xff0c;现在要更深入了解。内容区域就是盒子里真正放东西的…

怎么合并主从分支,要注意什么

在 Git 中合并主从分支&#xff08;例如将 feature 分支合并到 main 分支&#xff09;是一个常见操作。以下是具体步骤和注意事项&#xff1a; 合并分支的步骤 切换到主分支 git checkout main确保当前在 main 分支。 拉取最新代码 git pull origin main确保 main 分支是最…