首页 > 编程语言 >QFluentWidgets: 基于 C++ Qt 的 Fluent Design 组件库

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

时间:2023-10-04 13:55:20浏览次数:45  
标签:CMAKE Qt QFluentWidgets C++ Fluent SOURCE ui include DIR

简介

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

image

编译示例

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

image

接着在终端输入指令进行编译,其中 -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 示例文件:

image

搭配 Fluent Designer

项目结构如下图所示:

image

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

image

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 文件。

image

项目使用的 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 就能看到效果:

image

写在最后

C++ 组件库需要许可证才能拿到头文件和动态链接库使用,如果想体验运行效果,可以安装 Python 组件库并运行各个 demo.py,或者下载编译好的 PyQt-Fluent-Widgets-Gallery,最终效果和 C++ 是一样的。

经常有小伙伴留言为什么不将 C++ 组件库一起开源,其实原因很简单:白嫖的话有 Python 组件库就够了,一个人的精力是有限的,无法为爱发电维持这么多个组件库分支的开发,以上~~

标签:CMAKE,Qt,QFluentWidgets,C++,Fluent,SOURCE,ui,include,DIR
From: https://www.cnblogs.com/zhiyiYo/p/17742194.html

相关文章

  • C++ bitset 用法和应用
    C++的bitset在bitset头文件中,它是一种类似数组的结构,它的每一个元素只能是0或1,每个元素仅用1bit空间。下面是具体用法构造函数bitset常用构造函数有四种,如下bitset<4>bitset1;//无参构造,长度为4,默认每一位为0bitset<8>bitset2(12);//长度为8,二进制保存,前......
  • C++ typedef用法详解
    typedef的语法描述 在现实生活中,信息的概念可能是长度,数量和面积等。在C语言中,信息被抽象为int、float和double等基本数据类型。从基本数据类型名称上,不能够看出其所代表的物理属性,并且int、float和double为系统关键字,不可以修改。为了解决用户自定义数据类型名称的需求,C语言......
  • C++ 初始化列表
    何谓初始化列表与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段。在C++中,struct和class的唯一区别是默认的访问性不同,而这里我们不考虑访问性的问题,所以下面的代码都以struct来演示。structfoo......
  • C++ thread 互斥操作
    ThreadMutexstd::mutex是C++11最基本的互斥量,该类的实例化对象提供了资源独占所有权的特性,用于保护共享数据免受多个线程同时访问的同步原语。Mutex用法头文件#include<mutex>类型std::mutex最基础的Mutex类std::recursive_mutex递归的Mutex类std......
  • 关于Actor Component的思考--学习斯坦佛UE+C++
    跟着B站的视频学习,感觉自己的头很混乱。所以浅浅总结一下创建ActorComponent之后其的作用和相关操作。ActorComponent首先Component为一个组件,源码就是一个类的声明和类的实现。所以对其的操作就是对类的操作。可以在其源码内部定义一些物体属性,比如一个角色的Component。我们......
  • 十四天学会C++之第二天(函数和库)
    1.函数的定义和调用在C++中,函数是组织和结构化代码的关键工具之一。它们允许您将一段代码封装成一个可重复使用的模块,这有助于提高代码的可读性和维护性。为什么使用函数?函数在编程中的作用不可小觑。它们有以下几个重要用途:模块化编程:函数允许将代码划分为小的、独立的单元,使得......
  • C++ Thread 基础使用
    C++11Thread使用基础用法头文件#include<thread>函数初始化threadthread(<function_name>);线程分离thread.detach();线程阻塞thread.join()线程取消this_thread::yield();线程休眠this_thread::sleep_for(chrono::seconds(3));代码#in......
  • C++特种成员函数生成机制及相关原则
    C++特种成员函数生成机制及相关原则注:默认C++标准是C++11及以后的标准,因为C++11之前的标准定义的默认成员函数不包含移动构造函数和移动赋值运算符1.C++默认成员函数默认成员函数的定义:类中没有显示声明,在需要时由编译器自动生成的函数,包括默认构造函数、默认析构函数、......
  • 基于hash_table对STL unordered系列容器的封装 #C++
    概述本文对hash_table进行封装,以模仿SGISTL对unordered系列容器进行简单实现,旨在加深对C++封装与泛型技法的体会与理解。阅读本文之前,建议先对哈希表进行学习。unordered_map与map一样,unordered_map的所有元素类型都是pair,pair的第一个成员为Key,第二个成员为Value。因为Key在任何......
  • deepin DTK(Development ToolKit)已正式适配 Qt6!
    导读近日,深度deepin宣布 deepinDTK(Development ToolKit)已正式适配Qt6(6.4.2),实现全面升级。DTK作为deepin基于Qt开发的一整套简单且实用的通用开发框架,处于deepin操作系统中的核心位置,此次成功适配意味着deepin操作系统后续将充分利用Qt6版本的新特性......