簡介
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 元件庫就夠了,一個人的精力是有限的,無法為愛發電維持這麼多個元件庫分支的開發,以上~~