diff --git a/Software/Development/Environment/Qt/QML/QML_应用程序开发技术总结.md b/Software/Development/Environment/Qt/QML/QML_应用程序开发技术总结.md index 0f830b7..994360d 100644 --- a/Software/Development/Environment/Qt/QML/QML_应用程序开发技术总结.md +++ b/Software/Development/Environment/Qt/QML/QML_应用程序开发技术总结.md @@ -19,24 +19,28 @@ - [6.2. 添加图标到应用](#62-添加图标到应用) - [7. 绘制圆形](#7-绘制圆形) - [8. Dialog 对象](#8-dialog-对象) - - [8.1. FileDialog](#81-filedialog) - - [8.2. MessageDialog](#82-messagedialog) + - [8.1. QtQuick.Controls 中的 Dialog](#81-qtquickcontrols-中的-dialog) + - [8.2. QtQuick.Dialogs](#82-qtquickdialogs) + - [8.2.1. FileDialog](#821-filedialog) + - [8.2.2. MessageDialog](#822-messagedialog) - [9. ComboBox](#9-combobox) - - [10. ScrollView](#10-scrollview) - - [11. GridView](#11-gridview) - - [12. BusyIndicator](#12-busyindicator) - - [13. VirtualKeyboard](#13-virtualkeyboard) - - [14. 多文档开发](#14-多文档开发) - - [14.1. 多 QML 文件的管理](#141-多-qml-文件的管理) - - [14.2. 如何引用自定义 QML 文件](#142-如何引用自定义-qml-文件) - - [14.3. 示例](#143-示例) - - [15. QML 与 C++ 交互](#15-qml-与-c-交互) - - [15.1. QML 访问 C++ 中声明的类型](#151-qml-访问-c-中声明的类型) - - [15.2. C++ 访问 QML 对象](#152-c-访问-qml-对象) - - [15.3. 通过信号槽传递自建类型](#153-通过信号槽传递自建类型) - - [15.4. QML 与 C++ 交互综合示例](#154-qml-与-c-交互综合示例) - - [16. Windows 下 QML 程序的打包发布](#16-windows-下-qml-程序的打包发布) - - [17. 外部参考资料](#17-外部参考资料) + - [10. Grid](#10-grid) + - [11. ScrollView](#11-scrollview) + - [12. GridView](#12-gridview) + - [13. BusyIndicator](#13-busyindicator) + - [14. VirtualKeyboard](#14-virtualkeyboard) + - [15. 多文档开发](#15-多文档开发) + - [15.1. 多 QML 文件的管理](#151-多-qml-文件的管理) + - [15.2. 如何引用自定义 QML 文件](#152-如何引用自定义-qml-文件) + - [15.3. 使用另一 QML 文件中的元件或属性](#153-使用另一-qml-文件中的元件或属性) + - [15.4. 示例](#154-示例) + - [16. QML 与 C++ 交互](#16-qml-与-c-交互) + - [16.1. QML 访问 C++ 中声明的类型](#161-qml-访问-c-中声明的类型) + - [16.2. C++ 访问 QML 对象](#162-c-访问-qml-对象) + - [16.3. 通过信号槽传递自建类型](#163-通过信号槽传递自建类型) + - [16.4. QML 与 C++ 交互综合示例](#164-qml-与-c-交互综合示例) + - [17. Windows 下 QML 程序的打包发布](#17-windows-下-qml-程序的打包发布) + - [18. 外部参考资料](#18-外部参考资料) ## 1. 基础部分 @@ -291,7 +295,53 @@ If you do not use qmake, the necessary steps are: first, create an .rc file and ## 8. Dialog 对象 -在使用 QML 的 Dialog 对象时,如果使用 QGuiApplication 来执行则会导致无法加载主题风格,并且对话框无法正确显示图标。如果最初使用 QGuiApplication 创建了 app,则需要进行如下修改: +QML 中有三大类 Dialog 对象,这里主要介绍 QtQuick.Controls 中的 Dialog 和 QtQuick.Dialogs。 + +### 8.1. QtQuick.Controls 中的 Dialog + +QtQuick.Controls 中的 Dialog 比较原始,需要属性需要自行定义和实现,所以它的自由度也比较高。该 Dialog 包含了页眉(Header)、页脚(Footer)和内容(Content)三部分,每个部分都可以单独设定。 + +- footer:Item + + 对话框页脚项。页脚项目位于底部,并调整为对话框的宽度。 默认值为空。 + + 注意:将 DialogButtonBox 指定为对话框页脚会自动将其 accepted() 和 rejected() 信号连接到 Dialog 中的相应信号。 + + 注意:将 DialogButtonBox、ToolBar 或 TabBar 指定为对话框页脚会自动将相应的 DialogButtonBox::position、ToolBar::position 或 TabBar::position 属性设置为 Footer。 + +- header:Item + + 对话框标题项。标题项位于顶部,并调整为对话框的宽度。默认值为空。 + + 注意:将 DialogButtonBox 指定为对话框标题会自动将其 accepted() 和 rejected() 信号连接到 Dialog 中的相应信号。 + + 注意:将 DialogButtonBox、ToolBar 或 TabBar 指定为对话框标题会自动将相应的 DialogButtonBox::position、ToolBar::position 或 TabBar::position 属性设置为 Header。 + +该 Dialog 不会阻塞父窗口,并且在点击 Dialog 之外的区域会自动关闭,如果需要阻塞父窗口并且不自动关闭,则需要设定如下属性: + +```js +Dialog { + modal : true + closePolicy: Popup.NoAutoClose +} +``` + +上面的对话框没有提供任何按钮,可以通过 standardButtons 设定标准按钮: + +```js +Dialog { + title: qsTr("Demo") + standardButtons: Dialog.Ok | Dialog.Cancel + modal : true + closePolicy: Popup.NoAutoClose +} +``` + +除 Ok Button 和 Cancel Button 外,还有许多系统预定义的 Standard Button 可自行翻阅 QML 帮助获得相关帮助信息。 + +### 8.2. QtQuick.Dialogs + +在使用 QtQuick.Dialogs 的 Dialog 对象时,如果使用 QGuiApplication 来执行则会导致无法加载主题风格,并且对话框无法正确显示图标。如果最初使用 QGuiApplication 创建了 app,则需要进行如下修改: ```cpp /** @@ -310,7 +360,7 @@ QApplication app(argc, argv); Dialog 对象默认不显示,当调用 Dialog 的 open() 方法后弹出窗口并阻塞父窗体的执行。 -### 8.1. FileDialog +#### 8.2.1. FileDialog FileDialog 为标准文件对话框。 @@ -349,7 +399,7 @@ Window { } ``` -### 8.2. MessageDialog +#### 8.2.2. MessageDialog MessageDialog 为标准消息对话框。 @@ -417,11 +467,48 @@ Window { } ``` -## 10. ScrollView +## 10. Grid + +布局组件,可以布局多个行和列,每个子成员必须是相同类型,一般使用 Item 来组织多个不同类型。每个子成员必须设置高度和宽度,否则不被显示。 + +```js +import QtQuick +import QtQuick.Controls 6.3 + +Grid { + spacing: 8 + rows: 2 + columns: 2 + + Item { + height: 20; width: 68 + Text { + anchors.fill: parent + text: qsTr("DemoItem0") + } + } + Item { + height: 20; width: 68 + TextField { + anchors.fill: parent + text: qsTr("DemoItem1") + } + } + Item { + height: 20; width: 68 + Button { + anchors.fill: parent + text: qsTr("DemoItem2") + } + } +} +``` + +## 11. ScrollView ScrollView 会为其所容纳的对象创建滚动条。 -## 11. GridView +## 12. GridView GridView 可以以网格的形式显示模型内容。可以使用 ListModel 或 XmlListModel 作为模型。 @@ -529,7 +616,7 @@ Window { } ``` -## 12. BusyIndicator +## 13. BusyIndicator 用于指示工作状态,设置 BusyIndicator 的 running 属性为 true 将默认显示一个旋转的圆圈;设置 running 属性为 false 则 BusyIndicator 将不显示。 @@ -554,7 +641,7 @@ Window { 可以对 BusyIndicator 进行自定义。 -## 13. VirtualKeyboard +## 14. VirtualKeyboard 一些涉及触屏的应用会涉及到虚拟键盘/软键盘的应用,不同系统平台上往往会提供不同的软键盘工具,但相比之下,Qt 内嵌的 VirtualKeyboard 更加易用,并具有很好的跨平台能力,中文(拼音)、英文以及其他主要语言的支持能力也比较好。 @@ -603,9 +690,9 @@ CONFIG+="lang-en_GB lang-zh_CN" 更多关于 VirtualKeyboard 的应用可以参考官方自带示例。 -## 14. 多文档开发 +## 15. 多文档开发 -### 14.1. 多 QML 文件的管理 +### 15.1. 多 QML 文件的管理 在创建基于 Qt6 的 QML 项目时,不会包含 qml.qrc 文件,系统编译时自动创建该文件,创建的依据是 .pro 文件中的 resources.xxx 字段: @@ -630,7 +717,7 @@ failed to load component ... is not a type 错误,此时需要手动添加 Demo.qml 到 resources.files 字段中。 -### 14.2. 如何引用自定义 QML 文件 +### 15.2. 如何引用自定义 QML 文件 引用同级目录下的 QML 文件时不需要 import,在引用其他文件夹下的 QML 文件时需要: @@ -640,33 +727,39 @@ import "./DemoQml" QML 文件必须以大写字母开头,以表明这是一个 QML 类型。 -### 14.3. 示例 +### 15.3. 使用另一 QML 文件中的元件或属性 + +可以使用: + +```js +property alias <别名>:<属性名称/ID> +``` + +将一个 QML 文件中的某属性,某子组件的属性或某个子组件变为外部可见。 + +### 15.4. 示例 假设存在 DemoQml/Demo.qml 文件,该文件内容如下: ```js import QtQuick +import QtQuick.Controls 6.3 -Grid { - spacing: 8 - rows: 2 - columns: 2 +Item { + property alias dia: diaDemo - Rectangle { - height: 20; width: 68 - color: "red" - } - Rectangle { - height: 20; width: 68 - color: "blue" - } - Rectangle { - height: 20; width: 68 - color: "green" + Dialog { + id: diaDemo + title: qsTr("DemoDialog") + standardButtons: Dialog.Ok | Dialog.Cancel + + onRejected: console.log("Cancel clicked") } } ``` +注意这里使用的是 QtQuick.Controls 中的 Dialog,需要保持 main.cpp 中的 app 为 QGuiApplication 类型。 + .pro 文件的相关字段如下: ```js @@ -690,12 +783,23 @@ Window { title: qsTr("Hello World") Demo { + id: compDemo + dia.onAccepted: { + console.log("clicked Ok button.") + } + } + + Button { anchors.fill: parent + text: qsTr("显示 Dialog") + onClicked: { + compDemo.dia.open() + } } } ``` -## 15. QML 与 C++ 交互 +## 16. QML 与 C++ 交互 QML 与 C++ 交互的主要实现方式是: @@ -707,7 +811,7 @@ QML 与 C++ 交互的主要实现方式是: QML 与 C++ 之间主要通过信号槽机制来传递消息。 -### 15.1. QML 访问 C++ 中声明的类型 +### 16.1. QML 访问 C++ 中声明的类型 QML 使用 C++ 中声明的类型可以为类、结构体或枚举等。若需要将 C++ 类导出给 QML,则需要使用 qmlRegisterType() 方法进行注册: @@ -732,7 +836,7 @@ engine.rootContext()->setContextProperty("qmlObj", cObj); 将 C++ 对象注册到 QML 上下文环境中。 -### 15.2. C++ 访问 QML 对象 +### 16.2. C++ 访问 QML 对象 在 QML 中为对象添加 objectName 属性后,在 C++ 中可使用: @@ -745,7 +849,7 @@ auto qmlObj = root.first()->findChild("object name"); 大部分情况下在 QML 中访问 C++ 即可实现较完善的功能,QML 传递信息给 C++ 完全可以通过信号槽机制实现。除非需要在 C++ 中动态创建对象并连接到 QML 中的信号槽,否则没必要这样设计。 -### 15.3. 通过信号槽传递自建类型 +### 16.3. 通过信号槽传递自建类型 当使用信号槽机制时,需要注意一点:如果需要通过信号槽传递自建类型数据,需要使用 qRegisterMetaType() 方法进行注册。 @@ -753,7 +857,7 @@ auto qmlObj = root.first()->findChild("object name"); qRegisterMetaType("Myclass"); ``` -### 15.4. QML 与 C++ 交互综合示例 +### 16.4. QML 与 C++ 交互综合示例 该示例包含以下文件: @@ -1104,7 +1208,7 @@ Window { } ``` -## 16. Windows 下 QML 程序的打包发布 +## 17. Windows 下 QML 程序的打包发布 Qt 提供了导出 Qt 环境变量的命令行脚本,比如“Qt 5.15.2 (MinGW 8.1.0 64-bit)”,运行该脚本可进入带有 Qt 环境变量的命令行界面,之后可通过如下命令打包程序(编译生成的可执行程序需要拷贝到\): @@ -1115,7 +1219,7 @@ windeployqt [--qmldir ] Qt 自带的打包程序会添加额外的库,如果想进一步减小体积,可手动筛减。 -## 17. 外部参考资料 +## 18. 外部参考资料 1. [深入了解JS中的整数](https://www.jianshu.com/p/1ba45c3894ab) 2. [QML 中的信号与槽](https://blog.csdn.net/Love_XiaoQinEr/article/details/123746983) @@ -1132,3 +1236,4 @@ Qt 自带的打包程序会添加额外的库,如果想进一步减小体积 13. [Qt-虚拟键盘](https://blog.csdn.net/qq_39175540/article/details/87972667) 14. [Qt5软键盘实现中文拼音输入法](https://blog.csdn.net/onlyshi/article/details/78408000) 15. [Qt6中加载自定义qml遇到的问题](https://blog.csdn.net/youyicc/article/details/124367513) +16. [QML控件类型:Dialog(Qt Quick Controls 模块)](https://blog.csdn.net/kenfan1647/article/details/123109241)