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

介绍一个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过程使用如下

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

完成后的FluentUI源码目录

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

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

git clone --recursive https://github.com/zhuzichu520/framelesshelper.git
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

cmake_minimum_required(VERSION 3.16)

# Tutorial1-FirstWindow是项目名, 修改为自己的项目名
project(Tutorial1-FirstWindow VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(FLUENTUI_BUILD_EXAMPLES OFF)
set(FLUENTUI_BUILD_FRAMELESSHEPLER OFF)
find_package(FluentUI)
find_package(Qt6 6.4 REQUIRED COMPONENTS Quick)

qt_standard_project_setup()

qt_add_executable(appTutorial1-FirstWindow
    main.cpp
)

qt_add_qml_module(appTutorial1-FirstWindow
    URI Tutorial1-FirstWindow
    VERSION 1.0
    QML_FILES Main.qml
)

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
set_target_properties(appTutorial1-FirstWindow PROPERTIES
#    MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appTutorial1-FirstWindow
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

target_link_libraries(appTutorial1-FirstWindow
    PRIVATE Qt6::Quick
)

include(GNUInstallDirs)
install(TARGETS appTutorial1-FirstWindow
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

6. 修改Main.qml代码:

import QtQuick
import QtQuick.Window
// 注意这里,如果报错的话可能是前面构建FluentUI失败。检查这种路径F:\Qt\6.5.2\mingw_64\qml\FluentUI
import FluentUI

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    FluFilledButton {
        width: 100
        height: 50
        anchors.centerIn: parent
        text: "HelloWorld"
    }

}

FluFilledButton

使用FluApp与FluWindow

  1. QtCreator右键项目选择添加新文件->Qt Resource File->命名resource
  2. 在项目根目录下新建文件夹qml
  3. qml文件夹内新建文件AppMainWindow.qml
  4. 修改AppMainWindow.qml
import QtQuick 2.15
import FluentUI

FluWindow {

    id: mainWindow

    // 避免双屏情景下的宽度溢出
    minimumWidth: Screen.width * 0.8
    minimumHeight: Screen.desktopAvailableHeight * 0.8
    visible: true
    title: "Helloworld"
    //appBar: undefined

}
  1. 右键resource.qrc->添加现有文件->AppMainWindow.qml

创建完成后的项目

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

6. 修改Main.qml

import QtQuick
import QtQuick.Window
import FluentUI

Window {

    id: app
    flags: Qt.SplashScreen
    // 一定要是false
    visible: false

    Component.onCompleted: {
        // 初始化FluApp,实质是记录了app这个根组件实例用以获取QQmlEngine
        // 然后从engine中以initialRoute文本找到用户定义的组件.qml(在这里是AppMainWindow.qml)
        // 实例化AppMainWindow,在窗口实例表中对照是否已有相同窗口存在,若存在则会判断launchMode
        // 所以AppMainWindow要继承自FluWindow, 否则必须自行添加Property: _pageRegister 、 argument、 _route、 launchMode
        FluApp.init(app)
        // 相关枚举大部分都在Def.h里
        FluTheme.darkMode = FluThemeType.Light
        // 开启动画
        FluTheme.enableAnimation = true
        // 开启文本本地渲染
        FluTheme.nativeText = true
        // 切换主题色
        // FluTheme.primaryColor = FluColors.Orange
        // 路由表
        FluApp.routes = {
            "/": "qrc:/qml/AppMainWindow.qml"
        }
        // 初始化路径
        FluApp.initialRoute = "/"
        FluApp.run()
    }
}

Ctrl+R运行

FluWindow

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

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

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

appBar: undefined

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

import QtQuick 2.15
import FluentUI

FluWindow {

    id: mainWindow

    // 避免双屏情景下的宽度溢出
    minimumWidth: Screen.width * 0.8
    minimumHeight: Screen.desktopAvailableHeight * 0.8
    visible: true
    title: "Tutorial1-FirstWindow"
    appBar: undefined

    // 窗口标题栏
    FluAppBar {
        id: title_bar
        title: mainWindow.title
        // 可以在resource.qrc中添加ico,把url复制过来,程序左上角就有图标了
        // icon:"qrc:/example/res/image/favicon.ico"
        anchors {
            top: parent.top
            left: parent.left
            right: parent.right
        }
        showDark: true
        darkText: "Dark Mode"
    }
}

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

关闭窗口提示

在AppMainWindow.qml中添加代码

    // 退出软件确认提示框
    FluContentDialog {
        id: dialog_close
        title: "退出"
        message: "确定要退出程序吗?"
        negativeText: "最小化"
        buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.NeutralButton
                     | FluContentDialogType.PositiveButton
        onNegativeClicked: {
            mainWindow.hide()
        }
        positiveText: "退出"
        neutralText: "取消"
        onPositiveClicked: {
            FluApp.exit()
        }
    }

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

            mainWindow.deleteWindow()
            FluApp.closeApp()

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

我们查看FluWindow的代码里有:

    Connections{
        target: window
        function onClosing(event){closeListener(event)}
    }
    property var closeListener: function(event){
        if(closeDestory){
            destoryOnClose()
        }else{
            visible = false
            event.accepted = false
        }
    }

我们查看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就行。

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

完整代码

import QtQuick 2.15
import FluentUI

FluWindow {

    id: mainWindow

    // 避免双屏情景下的宽度溢出
    minimumWidth: Screen.width * 0.8
    minimumHeight: Screen.desktopAvailableHeight * 0.8
    visible: true
    title: "Tutorial1-FirstWindow"
    appBar: undefined

    closeListener: function (event) {
        dialog_close.open()
        // 取消窗口关闭
        event.accepted = false
    }

    // 窗口标题栏
    FluAppBar {
        id: title_bar
        title: mainWindow.title
        // icon:"qrc:/example/res/image/favicon.ico"
        anchors {
            top: parent.top
            left: parent.left
            right: parent.right
        }
        showDark: true
        darkText: "Dark Mode"
    }

    // 退出软件确认提示框
    FluContentDialog {
        id: dialog_close
        title: "退出"
        message: "确定要退出程序吗?"
        negativeText: "最小化"
        buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.NeutralButton
                     | FluContentDialogType.PositiveButton
        onNegativeClicked: {
            mainWindow.hide()
        }
        positiveText: "退出"
        neutralText: "取消"
        onPositiveClicked: {
            FluApp.exit()
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/539884.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringMVC--02--上下文工具类(RequestContextHolder)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 RequestContextHolder背景1.RequestContextHolder的使用2.request和response怎么和当前请求挂钩?3.request和response等是什么时候设置进去的? 案例应用---用户信…

softmax回归:多分类问题的解码器

随着人工智能技术的不断发展,分类问题在机器学习领域中的地位日益凸显。在众多分类算法中,softmax回归以其独特的优势和广泛的应用场景,成为了处理多分类问题的有力工具。本文将深入探讨softmax回归的原理、应用及其优缺点,以期为…

【好用】推荐10套后端管理系统前端模板

后台管理系统前端模板是开发者在构建后台管理系统时使用的一种工具,它提供了预先设计好的界面和组件,以帮助开发者快速搭建出功能完善、用户体验良好的管理系统。以下是V哥整理的10款流行的后台管理系统前端模板,它们基于不同的技术栈和设计理…

找出mongodb的jumbo块并进行分裂

https://www.cnblogs.com/abclife/p/15968628.html 根据这篇文档中的脚本,在我们自己的环境中跑了下,第一次跑的结果如下: 运行完上面跑出的split脚本后,还是存在jumbo块,第二次跑出的结果: 从上面结果可以…

【Vue3进阶】- 第2学堂小商城项目后端准备和接口文档

简介 在大多数前端项目开发中,都需要与后端进行接口交互,后端通常会以文档的形式提供接口信息,前端开发者通过阅读这些文档,了解后端接口的功能和使用方法,从而实现数据的获取和提交等功能。 第二学堂小商城教程后端…

古月·ROS2入门21讲——学习笔记

第一讲:ROS/ROS2是什么 1. ROS的诞生 对于越来越复杂的智能机器人系统,已经不是一个人或者一个团队可以独立完成的,如何高效开发机器人,是技术层面上非常重要的一个问题,针对这个问题,一群斯坦福大学的有…

CentOS7 boa服务器的搭建和配置

环境是CentOS7,但方法不局限于此版系统,应该是通用的。 具体步骤如下: 1. 下载boa源码 下载地址: Boa Webserver 下载后,进入压缩包所在目录,进行解压: tar xzf boa-0.94.13.tar.gz 2. 安装需要的工具b…

要申请开通融资融券账户,有那些条件?

1、什么是融资融券交易? 融资融券交易,又称信用交易,是指投资者向具有融资融券业务资格的证券公司提供担 保物,借入资金买入交易所上市证券(融资交易)或借入交易所上市证券并卖出(融券交易) 的…

如何在ADS中实现数据的导入和导出

1 MDIF接口 ADS提供了一种通用的MDIF格式文件,允许用户使用一个通用的数据接口实现导入和导出的功能,其Help文件中的简介如下: 2 数据的导入 实现数据导入功能之前,数据必须遵从一定的标准格式,如下图所示,…

联储降息预期落空打了谁的脸

美国 3 月消费者价格指数(CPI)于本周发布,最新数据全线高于预期。具体而言,美国劳工部周三公布的数据显示,美国 3 月消费者物价指数(CPI)同比上涨 3.5%,为 2023 年 9 月以来最高水平…

汇编基础-----通过x64dbg了解什么是堆栈

汇编基础-----通过x64dbg了解什么是堆栈 什么是堆栈 在汇编语言中,堆栈(stack)是一种用于存储临时数据和执行函数调用的内存结构。堆栈是一种后进先出(Last-In-First-Out, LIFO)的数据结构,通常用于保存函…

算法修炼之路之双指针含多道leetcode 经典题目

目录 前言 一:普通双指针 1.经典题目一 283移动0问题 分析 代码实现 2.经典题目二 1089复写0 分析 代码实现 二:解决成环类问题-快慢指针 经典例题一 202快乐数 分析 代码实现 三:左右相遇指针 经典例题一 11 盛最多水的容…

阿里云9元服务器租用收费价格表_免费云服务器领取

2024年最新阿里云服务器租用费用优惠价格表,轻量2核2G3M带宽轻量服务器一年61元,折合5元1个月,新老用户同享99元一年服务器,2核4G5M服务器ECS优惠价199元一年,2核4G4M轻量服务器165元一年,2核4G服务器30元3…

「代码之舞:选择成为程序员的兴趣与职业发展」

文章目录 每日一句正能量前言当初为什么会选择成为一名程序员?你觉得程序员是一个怎样的职业?你会如何看待「35 岁危机」这个话题?从事这个职业以来,分享一下你印象最深的一件事?对于即将入行的职场后辈们,…

Centos7 搭建Mongodb 分片集群4.0/ PSA(三成员副本集)

MongoDB 简介:1、优点和缺点:2、MongoDB适用的业务场景:Centos7 搭建Mongodb 分片集群一、安装MongoDB社区版4.01、配置程序包管理系统(`yum`)2、安装对应版本的MongoDB软件包。3、创建运行mongodb的目录并禁用SELinux4、修改文件打开数5、初始化系统5.1、创建config配置…

CentOS 8服务器搭建L2TP服务器(over IPsec)操作指南

正文共:1234 字 14 图,预估阅读时间:2 分钟 之前发过把我自己的服务器搬上公网的文章(我用100块钱把物理服务器放到了公网,省了几万块!),当时L2TP拨号用的是网络上的解决方案&#x…

Java 集合Collection

集合的体系 Collection的结构体系 List系列集合:添加的元素是有序的、可重复、有索引。Set系列集合:无序、不重复、无索引 HashSet:无序、不重复、无索引LinkedHashSet:有序、不重复、无索引TreeSet:按照大小默认升序排序、不重复…

最新PDD批发Anti-Content参数逆向分析与算法还原

文章目录 1. 写在前面2. 接口分析3. 分析与扣代码 【🏠作者主页】:吴秋霖 【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Py…

Day:007(1) | Python爬虫:高效数据抓取的编程技术(scrapy框架使用)

Scrapy的介绍 Scrapy 是一个用于抓取网站和提取结构化数据的应用程序框架,可用于各种有用的应用程序,如数据挖掘、信息处理或历史存档。 尽管 Scrapy 最初是为网络抓取而设计的,但它也可用于使用API提取数据或用作通用网络爬虫。 Scrapy的优势…

海外媒体发稿:4种旅游业媒体套餐助你宣发推广-华媒舍

在现代社会中,旅游业发展迅速,竞争也变得日益激烈。为了让自己的旅游产品或服务脱颖而出,宣传和推广变得至关重要。有着强大传播力的媒体平台成为了旅游行业的一项重要资源。为了更好地推广旅游业,提高其影响力,有许多…