当前位置:   article > 正文

FluentUI系列 - 1 - 介绍&第一个窗口_fluent ui

fluent ui

介绍一个QML的UI库,国人编写,作者也耍知乎。这个UI库确实好用,但是教程基本等于无,个人在使用中顺便记录一下学习内容。这玩意儿也有Pyside6的版本,有需要的可以查看PySide6-FluentUI-QML

FluentUI库地址​github.com/zhuzichu520/FluentUI

预览程序,可以在上面查看大部分组件

安装

浏览项目的Github页,注意有如下前置需求。

有缺少的可以在Qt目录下的MaintenanceTool.exe里进行安装。

  • Qt Core, Qt Quick, Qt QML, Qt ShaderTool, Qt 5 Compatibility Module. (必备)
  • Qt LinguistTool (optional,for translations)
    • Tips: 在 Qt安装目录\版本\编译环境类型\bin 里
    • 例如:F:\Qt\6.5.2\mingw_64\bin
  • Qt Svg (optional, however essential for Qt 5)

确认前置条件满足后,开始安装,具体步骤参考:

FluentUI:如何在新项目中使用?_哔哩哔哩_bilibili​www.bilibili.com/video/BV1ek4y1N7r8/​编辑

这里要注意git clone有些坑,作者的库里有引用别的库的,clone过程使用如下

  1. cd source
  2. git clone --recursive https://github.com/zhuzichu520/FluentUI.git
  3. cd FluentUI

完成后的FluentUI源码目录

注意检查完成后的framelesshelper与zxing-cpp可能是空的。我写这篇文章的时候,作者的引用的framelesshelper仍然处于NotFound状态, 可能需要直接去clone再放进此目录下。

删除framelesshelper与zxing-cpp文件夹,直接clone:

  1. git clone --recursive https://github.com/zhuzichu520/framelesshelper.git
  2. git clone https://github.com/zhuzichu520/zxing-cpp.git

完成安装后,Qt目录下会有QML模块生成的。路径类似F:\Qt\6.5.2\mingw_64\qml\FluentUI

路径中的版本和编译环境类型来源于图中

第一个程序

  1. 新建一个Qt Quick Application,为了方便可以命名为Tutorial1-FirstWindow

2. 选择前面用来编译FluentUI的Qt版本

3. 如果有选择项,构建方式选cmake而不是qmake或者qbs

新建项目完成后

4. 把之前的FluentUI文件夹丢到项目根目录下

5. 修改CMakeLists.txt, 改完之后类似上面的构建视频的cmakelist

  1. cmake_minimum_required(VERSION 3.16)
  2. # Tutorial1-FirstWindow是项目名, 修改为自己的项目名
  3. project(Tutorial1-FirstWindow VERSION 0.1 LANGUAGES CXX)
  4. set(CMAKE_AUTOMOC ON)
  5. set(CMAKE_AUTORCC ON)
  6. set(CMAKE_AUTOUIC ON)
  7. set(CMAKE_CXX_STANDARD_REQUIRED ON)
  8. set(FLUENTUI_BUILD_EXAMPLES OFF)
  9. set(FLUENTUI_BUILD_FRAMELESSHEPLER OFF)
  10. find_package(FluentUI)
  11. find_package(Qt6 6.4 REQUIRED COMPONENTS Quick)
  12. qt_standard_project_setup()
  13. qt_add_executable(appTutorial1-FirstWindow
  14. main.cpp
  15. )
  16. qt_add_qml_module(appTutorial1-FirstWindow
  17. URI Tutorial1-FirstWindow
  18. VERSION 1.0
  19. QML_FILES Main.qml
  20. )
  21. # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
  22. # If you are developing for iOS or macOS you should consider setting an
  23. # explicit, fixed bundle identifier manually though.
  24. set_target_properties(appTutorial1-FirstWindow PROPERTIES
  25. # MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appTutorial1-FirstWindow
  26. MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
  27. MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
  28. MACOSX_BUNDLE TRUE
  29. WIN32_EXECUTABLE TRUE
  30. )
  31. target_link_libraries(appTutorial1-FirstWindow
  32. PRIVATE Qt6::Quick
  33. )
  34. include(GNUInstallDirs)
  35. install(TARGETS appTutorial1-FirstWindow
  36. BUNDLE DESTINATION .
  37. LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  38. RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  39. )

6. 修改Main.qml代码:

  1. import QtQuick
  2. import QtQuick.Window
  3. // 注意这里,如果报错的话可能是前面构建FluentUI失败。检查这种路径F:\Qt\6.5.2\mingw_64\qml\FluentUI
  4. import FluentUI
  5. Window {
  6. width: 640
  7. height: 480
  8. visible: true
  9. title: qsTr("Hello World")
  10. FluFilledButton {
  11. width: 100
  12. height: 50
  13. anchors.centerIn: parent
  14. text: "HelloWorld"
  15. }
  16. }

FluFilledButton

使用FluApp与FluWindow

  1. QtCreator右键项目选择添加新文件->Qt Resource File->命名resource
  2. 在项目根目录下新建文件夹qml
  3. qml文件夹内新建文件AppMainWindow.qml
  4. 修改AppMainWindow.qml
  1. import QtQuick 2.15
  2. import FluentUI
  3. FluWindow {
  4. id: mainWindow
  5. // 避免双屏情景下的宽度溢出
  6. minimumWidth: Screen.width * 0.8
  7. minimumHeight: Screen.desktopAvailableHeight * 0.8
  8. visible: true
  9. title: "Helloworld"
  10. //appBar: undefined
  11. }
  1. 右键resource.qrc->添加现有文件->AppMainWindow.qml

创建完成后的项目

5. 右键resource.qrc下的AppMainWindow-> Copy URL "qrc:/qml/AppMainWindow.qml"

6. 修改Main.qml

  1. import QtQuick
  2. import QtQuick.Window
  3. import FluentUI
  4. Window {
  5. id: app
  6. flags: Qt.SplashScreen
  7. // 一定要是false
  8. visible: false
  9. Component.onCompleted: {
  10. // 初始化FluApp,实质是记录了app这个根组件实例用以获取QQmlEngine
  11. // 然后从engine中以initialRoute文本找到用户定义的组件.qml(在这里是AppMainWindow.qml)
  12. // 实例化AppMainWindow,在窗口实例表中对照是否已有相同窗口存在,若存在则会判断launchMode
  13. // 所以AppMainWindow要继承自FluWindow, 否则必须自行添加Property: _pageRegister 、 argument、 _route、 launchMode
  14. FluApp.init(app)
  15. // 相关枚举大部分都在Def.h里
  16. FluTheme.darkMode = FluThemeType.Light
  17. // 开启动画
  18. FluTheme.enableAnimation = true
  19. // 开启文本本地渲染
  20. FluTheme.nativeText = true
  21. // 切换主题色
  22. // FluTheme.primaryColor = FluColors.Orange
  23. // 路由表
  24. FluApp.routes = {
  25. "/": "qrc:/qml/AppMainWindow.qml"
  26. }
  27. // 初始化路径
  28. FluApp.initialRoute = "/"
  29. FluApp.run()
  30. }
  31. }

Ctrl+R运行

FluWindow

图中的FluWindow拥有一个默认的FluAppBar,这个玩意儿是使用Loader动态载入的Component。我遇到过一个bug就是因为window的appbar还没有载入完成,我的canvas组件就依据appBar进行paint导致页面错误。所以可以自定义一个appBar。

这个appBar其实是有与FramelessHelper联动的,我的工作机上FramelessHelper时好时坏,就不无人子弟了。

刚刚AppMainWindow.qml里,取消这一行的注释:

appBar: undefined

后面再加上新的AppBar,整个文件内容:

  1. import QtQuick 2.15
  2. import FluentUI
  3. FluWindow {
  4. id: mainWindow
  5. // 避免双屏情景下的宽度溢出
  6. minimumWidth: Screen.width * 0.8
  7. minimumHeight: Screen.desktopAvailableHeight * 0.8
  8. visible: true
  9. title: "Tutorial1-FirstWindow"
  10. appBar: undefined
  11. // 窗口标题栏
  12. FluAppBar {
  13. id: title_bar
  14. title: mainWindow.title
  15. // 可以在resource.qrc中添加ico,把url复制过来,程序左上角就有图标了
  16. // icon:"qrc:/example/res/image/favicon.ico"
  17. anchors {
  18. top: parent.top
  19. left: parent.left
  20. right: parent.right
  21. }
  22. showDark: true
  23. darkText: "Dark Mode"
  24. }
  25. }

这里点了右上角的dark mode会切换黑/白模式

关闭窗口提示

在AppMainWindow.qml中添加代码

  1. // 退出软件确认提示框
  2. FluContentDialog {
  3. id: dialog_close
  4. title: "退出"
  5. message: "确定要退出程序吗?"
  6. negativeText: "最小化"
  7. buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.NeutralButton
  8. | FluContentDialogType.PositiveButton
  9. onNegativeClicked: {
  10. mainWindow.hide()
  11. }
  12. positiveText: "退出"
  13. neutralText: "取消"
  14. onPositiveClicked: {
  15. FluApp.exit()
  16. }
  17. }

onPositiveClicked这里,如果是1.6.0版本之前的FluentUI,需要写成

  1. mainWindow.deleteWindow()
  2. FluApp.closeApp()

现在Ctrl+R运行程序,点击右上角关闭窗口,发现并没有什么不一样

我们查看FluWindow的代码里有:

  1. Connections{
  2. target: window
  3. function onClosing(event){closeListener(event)}
  4. }
  5. property var closeListener: function(event){
  6. if(closeDestory){
  7. destoryOnClose()
  8. }else{
  9. visible = false
  10. event.accepted = false
  11. }
  12. }

我们查看QML的Window 文档会发现

closing(CloseEvent close)

This signal is emitted when the user tries to close the window.
This signal includes a close parameter. The close.accepted property is true by default so that the window is allowed to close; but you can implement an onClosing handler and set close.accepted = false if you need to do something else before the window can be closed.

所以FluWindow的onClosing已经被监听了,会调用closeListener, 我们直接用closeListener就行。

  1. closeListener:function(event){
  2. // 打开关闭确认 弹窗
  3. dialog_close.open()
  4. // 取消关闭先
  5. event.accepted = false
  6. }

完整代码

  1. import QtQuick 2.15
  2. import FluentUI
  3. FluWindow {
  4. id: mainWindow
  5. // 避免双屏情景下的宽度溢出
  6. minimumWidth: Screen.width * 0.8
  7. minimumHeight: Screen.desktopAvailableHeight * 0.8
  8. visible: true
  9. title: "Tutorial1-FirstWindow"
  10. appBar: undefined
  11. closeListener: function (event) {
  12. dialog_close.open()
  13. // 取消窗口关闭
  14. event.accepted = false
  15. }
  16. // 窗口标题栏
  17. FluAppBar {
  18. id: title_bar
  19. title: mainWindow.title
  20. // icon:"qrc:/example/res/image/favicon.ico"
  21. anchors {
  22. top: parent.top
  23. left: parent.left
  24. right: parent.right
  25. }
  26. showDark: true
  27. darkText: "Dark Mode"
  28. }
  29. // 退出软件确认提示框
  30. FluContentDialog {
  31. id: dialog_close
  32. title: "退出"
  33. message: "确定要退出程序吗?"
  34. negativeText: "最小化"
  35. buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.NeutralButton
  36. | FluContentDialogType.PositiveButton
  37. onNegativeClicked: {
  38. mainWindow.hide()
  39. }
  40. positiveText: "退出"
  41. neutralText: "取消"
  42. onPositiveClicked: {
  43. FluApp.exit()
  44. }
  45. }
  46. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/743217
推荐阅读
相关标签
  

闽ICP备14008679号