完成 QML 应用程序开发技术总结.
Signed-off-by: Rick.Chan <cy@haoan119.com>
This commit is contained in:
parent
b12ebf2549
commit
7b32475d7b
|
@ -1,12 +1,42 @@
|
|||
# QML 应用程序开发技术总结
|
||||
|
||||
- [QML 应用程序开发技术总结](#qml-应用程序开发技术总结)
|
||||
- [1. 方法/属性名称大小写](#1-方法属性名称大小写)
|
||||
- [2. 全局属性](#2-全局属性)
|
||||
- [3. 信号与槽](#3-信号与槽)
|
||||
- [3.1. 信号与信号处理器](#31-信号与信号处理器)
|
||||
- [3.2. 属性变化信号与属性变化信号处理器](#32-属性变化信号与属性变化信号处理器)
|
||||
- [3.3. 附加属性与附加信号处理器](#33-附加属性与附加信号处理器)
|
||||
- [3.4. Connections 建立信号与槽的连接](#34-connections-建立信号与槽的连接)
|
||||
- [3.5. connect()方法](#35-connect方法)
|
||||
- [3.6. 自定义信号](#36-自定义信号)
|
||||
- [4. 界面加载完成信号](#4-界面加载完成信号)
|
||||
- [5. 包别名](#5-包别名)
|
||||
- [6. 添加图标](#6-添加图标)
|
||||
- [6.1. 制作图标](#61-制作图标)
|
||||
- [6.2. 添加图标到应用](#62-添加图标到应用)
|
||||
- [7. 绘制圆形](#7-绘制圆形)
|
||||
- [8. Dialog 对象](#8-dialog-对象)
|
||||
- [8.1. FileDialog](#81-filedialog)
|
||||
- [8.2. MessageDialog](#82-messagedialog)
|
||||
- [9. ComboBox](#9-combobox)
|
||||
- [10. ScrollView](#10-scrollview)
|
||||
- [11. GridView](#11-gridview)
|
||||
- [12. QML 与 C++ 交互](#12-qml-与-c-交互)
|
||||
- [12.1. QML 访问 C++ 中声明的类型](#121-qml-访问-c-中声明的类型)
|
||||
- [12.2. C++ 访问 QML 对象](#122-c-访问-qml-对象)
|
||||
- [12.3. 通过信号槽传递自建类型](#123-通过信号槽传递自建类型)
|
||||
- [12.4. QML 与 C++ 交互综合示例](#124-qml-与-c-交互综合示例)
|
||||
- [13. Windows 下 QML 程序的打包发布](#13-windows-下-qml-程序的打包发布)
|
||||
- [14. 外部参考资料](#14-外部参考资料)
|
||||
|
||||
## 1. 方法/属性名称大小写
|
||||
|
||||
QML 语法与 JS 相同,具体请参考相关教程,此处只对一些需要特殊注意的地方进行说明。
|
||||
|
||||
QML 的属性、变量、函数等一般为小写字母开头,大写字母开头通常具有特殊意义,比如使用 QML 连接名为 demo() 的信号时,系统将自动连接 onDemo() 作为其槽函数。以下以连接 Button 的 clicked 信号为例进行演示:
|
||||
|
||||
```qml
|
||||
```js
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Window 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
@ -26,7 +56,7 @@ Window {
|
|||
|
||||
## 2. 全局属性
|
||||
|
||||
```qml
|
||||
```js
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Window 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
@ -41,54 +71,128 @@ Window {
|
|||
}
|
||||
```
|
||||
|
||||
## 3. 连接信号槽
|
||||
## 3. 信号与槽
|
||||
|
||||
TODO: 细化
|
||||
在 QML 中连接信号槽主要有以下 5 种方法。
|
||||
|
||||
信号与信号处理器
|
||||
### 3.1. 信号与信号处理器
|
||||
|
||||
```qml
|
||||
```js
|
||||
signal()
|
||||
|
||||
on<Signal>: {}
|
||||
```
|
||||
|
||||
属性变化信号与属性变化信号处理器
|
||||
这是最常见的方法,比如 onClicked: {} 槽。
|
||||
|
||||
```qml
|
||||
### 3.2. 属性变化信号与属性变化信号处理器
|
||||
|
||||
```js
|
||||
property
|
||||
|
||||
on<Property>Changed: {}
|
||||
```
|
||||
|
||||
附加属性与附加信号处理器
|
||||
QML 规范,当属性变化后会发送一个 \<Property\>Changed 信号。从 C 环境创建属性时需要注册 NOTIFY 信号,其命名格式也需要遵循该规范。
|
||||
|
||||
```qml
|
||||
### 3.3. 附加属性与附加信号处理器
|
||||
|
||||
```js
|
||||
Attached Signal(附加属性)
|
||||
|
||||
XX元素.on<附加属性>: {}
|
||||
```
|
||||
|
||||
Connections 建立信号与槽的连接
|
||||
最常见的是 Component.onCompleted:{} 槽。
|
||||
|
||||
```qml
|
||||
### 3.4. Connections 建立信号与槽的连接
|
||||
|
||||
```js
|
||||
Connections {
|
||||
target: 发送者
|
||||
发送者信号处理器:{}
|
||||
}
|
||||
```
|
||||
|
||||
connect()方法 信号连接信号
|
||||
前面的信号连接都嵌入在某个对象中,当信号与槽的连接不依赖具体对象时,需要将其嵌入到 Connections 对象中。Connections 的 target 指向信号的发送者,一个 Connections 可以绑定同一个 target 的多个信号处理机。
|
||||
|
||||
```qml
|
||||
元素对象.信号.connect(信号)
|
||||
```js
|
||||
Connections {
|
||||
target: whomSentTheSignal
|
||||
|
||||
function onSignal0(arg) {
|
||||
console.log(arg)
|
||||
}
|
||||
|
||||
function onSignal1(arg) {
|
||||
console.log(arg)
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 3.5. connect()方法
|
||||
|
||||
使用 connect() 方法,可以为信号指定非 on\<Signal\> 格式命名的响应方法,也可以指令信号触发下一个信号形成信号的连锁反应。
|
||||
|
||||
```js
|
||||
[元素对象.]信号.connect(信号/方法)
|
||||
```
|
||||
|
||||
示例如下:
|
||||
|
||||
```js
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
signal mySignal()
|
||||
// 信号响应处理
|
||||
onMySignal: console.log("clicked connect mySignal")
|
||||
|
||||
// 普通方法
|
||||
function slt_clicked() {
|
||||
console.log("clicked connect slt_clicked");
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
mousearea.clicked.connect(slt_clicked);
|
||||
mousearea.clicked.connect(mySignal);
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mousearea
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.6. 自定义信号
|
||||
|
||||
用以下形式声明自定义的信号:
|
||||
|
||||
```js
|
||||
signal <name>[([<type> <parameter name>[, ...]])]
|
||||
```
|
||||
|
||||
示例如下:
|
||||
|
||||
```js
|
||||
Rectangle {
|
||||
id: root
|
||||
signal mysignal(int x, int y)
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressed: root.mysignal(mouse.x, mouse.y)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 界面加载完成信号
|
||||
|
||||
许多时候需要在 QML 程序界面完成加载后做一些事情,比如设置一些属性的初始值。这时候就需要用到 Component 的 completed() 信号:
|
||||
|
||||
```qml
|
||||
```js
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Window 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
@ -113,7 +217,7 @@ Window {
|
|||
|
||||
编写 QML 应用时需要像 include 那样引用一些软件包,有的时候软件包中的对象会有重名的情况,比如 QtQuick.Dialogs 1.3 和 Qt.labs.qmlmodels 1.0 中均包含了 FileDialog 对象,但他们的功能并不相同。此时可以使用 import as 来实现类似别名或者命名空间的功能。
|
||||
|
||||
```qml
|
||||
```js
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Window 2.12
|
||||
import QtQuick.Dialogs 1.3
|
||||
|
@ -147,19 +251,19 @@ magick.exe convert icon-16.png icon-32.png icon-256.png myappico.ico
|
|||
|
||||
在 Qt .pro 文件中添加以下内容,以便将图标编译到 Qt 程序中:
|
||||
|
||||
```qt
|
||||
```js
|
||||
RC_ICONS = myappico.ico
|
||||
```
|
||||
|
||||
However, if you already have an .rc file, for example, with the name myapp.rc, which you want to reuse, the following two steps will be required. First, put a single line of text to the myapp.rc file:
|
||||
|
||||
```qt
|
||||
```js
|
||||
IDI_ICON1 ICON "myappico.ico"
|
||||
```
|
||||
|
||||
Then, add this line to your myapp.pro file:
|
||||
|
||||
```qt
|
||||
```js
|
||||
RC_FILE = myapp.rc
|
||||
```
|
||||
|
||||
|
@ -196,7 +300,7 @@ Dialog 对象默认不显示,当调用 Dialog 的 open() 方法后弹出窗口
|
|||
|
||||
FileDialog 为标准文件对话框。
|
||||
|
||||
```qml
|
||||
```js
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Window 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
@ -235,7 +339,7 @@ Window {
|
|||
|
||||
MessageDialog 为标准消息对话框。
|
||||
|
||||
```qml
|
||||
```js
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Window 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
@ -275,7 +379,7 @@ Window {
|
|||
|
||||
ComboBox 为标准组合框
|
||||
|
||||
```qml
|
||||
```js
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Window 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
@ -307,7 +411,7 @@ ScrollView 会为其所容纳的对象创建滚动条。
|
|||
|
||||
GridView 可以以网格的形式显示模型内容。可以使用 ListModel 或 XmlListModel 作为模型。
|
||||
|
||||
```qml
|
||||
```js
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Window 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
@ -431,9 +535,13 @@ QML 使用 C++ 中声明的类型可以为类、结构体或枚举等。若需
|
|||
qmlRegisterType<Type>("package.Type", <version>, <sub-version>,"Type");
|
||||
```
|
||||
|
||||
之后在 QML 中使用 C++ 类创建对象即可。
|
||||
之后在 QML 中使用 C++ 类创建对象即可。若需要在 QML 中使用类中定义的枚举,格式如下:
|
||||
|
||||
若 QML 需要使用 C++ 中声明的枚举类型,则该枚举需要使用 Q_ENUM() 进行修饰;若访问属性成员则需要使用 Q_PROPERTY() 进行修饰;若访问方法则该方法需要使用 Q_INVOKABLE() 来修饰。C++ 中的信号不需要特殊处理,QML 可直接访问。
|
||||
```js
|
||||
<类名>.<枚举值>
|
||||
```
|
||||
|
||||
若 QML 需要使用 C++ 中声明的枚举类型,则该枚举需要使用 Q_ENUM() 进行修饰(必须放在声明之后);若访问属性成员则需要使用 Q_PROPERTY() 进行修饰;若访问方法则该方法需要使用 Q_INVOKABLE() 来修饰。C++ 中的信号不需要特殊处理,QML 可直接访问。
|
||||
|
||||
若对象在 C++ 上下文中创建,并需要在 QML 中使用该对象,可以使用:
|
||||
|
||||
|
@ -457,9 +565,9 @@ auto qmlObj = root.first()->findChild<QObject*>("object name");
|
|||
|
||||
大部分情况下在 QML 中访问 C++ 即可实现较完善的功能,QML 传递信息给 C++ 完全可以通过信号槽机制实现。除非需要在 C++ 中动态创建对象并连接到 QML 中的信号槽,否则没必要这样设计。
|
||||
|
||||
## 12.3. qRegisterMetaType
|
||||
### 12.3. 通过信号槽传递自建类型
|
||||
|
||||
当使用信号槽机制是,需要注意一点:如果需要通过信号槽传递自建类型数据,则需要使用 qRegisterMetaType() 方法进行注册。
|
||||
当使用信号槽机制时,需要注意一点:如果需要通过信号槽传递自建类型数据,需要使用 qRegisterMetaType() 方法进行注册。
|
||||
|
||||
```cpp
|
||||
qRegisterMetaType<MyClass>("Myclass");
|
||||
|
@ -467,16 +575,353 @@ qRegisterMetaType<MyClass>("Myclass");
|
|||
|
||||
### 12.4. QML 与 C++ 交互综合示例
|
||||
|
||||
```cpp
|
||||
TODO: 添加示例
|
||||
该示例包含以下文件:
|
||||
|
||||
- QmlDemo.por
|
||||
- qml.qrc
|
||||
- DemoDirect.h
|
||||
- DemoDirect.cpp
|
||||
- DemoJoint.h
|
||||
- DemoJoint.cpp
|
||||
- DemoIndirect.h
|
||||
- DemoIndirect.cpp
|
||||
- main.qml
|
||||
- main.cpp
|
||||
|
||||
QmlDemo.por 内容如下:
|
||||
|
||||
```js
|
||||
QT += quick widgets
|
||||
|
||||
# You can make your code fail to compile if it uses deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
DemoDirect.cpp \
|
||||
DemoIndirect.cpp \
|
||||
DemoJoint.cpp \
|
||||
main.cpp
|
||||
|
||||
RESOURCES += qml.qrc
|
||||
|
||||
# Additional import path used to resolve QML modules in Qt Creator's code model
|
||||
QML_IMPORT_PATH =
|
||||
|
||||
# Additional import path used to resolve QML modules just for Qt Quick Designer
|
||||
QML_DESIGNER_IMPORT_PATH =
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
|
||||
HEADERS += \
|
||||
DemoDirect.h \
|
||||
DemoIndirect.h \
|
||||
DemoJoint.h
|
||||
```
|
||||
|
||||
```cpp
|
||||
TODO: 添加示例
|
||||
qml.qrc 内容如下:
|
||||
|
||||
```xml
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
```
|
||||
|
||||
```qml
|
||||
TODO: 添加示例
|
||||
DemoDirect.h 内容如下
|
||||
|
||||
```cpp
|
||||
#ifndef DEMODIRECT_H
|
||||
#define DEMODIRECT_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class DemoDirect : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
// 声明 cppStr 为只读属性. NOTIFY 信号是必须的.
|
||||
Q_PROPERTY(QString cppStr READ readCppStr NOTIFY cppStrChanged)
|
||||
public:
|
||||
explicit DemoDirect(QObject *parent = nullptr);
|
||||
|
||||
// 使用 Q_INVOKABLE 向 QML 声明函数方法.
|
||||
Q_INVOKABLE void writeCppStr(QString str);
|
||||
Q_INVOKABLE QString readCppStr();
|
||||
|
||||
signals:
|
||||
void cppStrChanged(QString str);
|
||||
|
||||
protected:
|
||||
QString cppStr;
|
||||
|
||||
};
|
||||
|
||||
#endif // DEMODIRECT_H
|
||||
```
|
||||
|
||||
DemoDirect.cpp 内容如下
|
||||
|
||||
```cpp
|
||||
#include "DemoDirect.h"
|
||||
#include <QDebug>
|
||||
|
||||
DemoDirect::DemoDirect(QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
cppStr = "Hello";
|
||||
}
|
||||
|
||||
void DemoDirect::writeCppStr(QString str)
|
||||
{
|
||||
cppStr = str;
|
||||
qDebug()<<"[CPP:DemoDirect:writeCppStr]srt="<<cppStr;
|
||||
emit cppStrChanged(cppStr);
|
||||
}
|
||||
|
||||
QString DemoDirect::readCppStr()
|
||||
{
|
||||
return cppStr;
|
||||
}
|
||||
```
|
||||
|
||||
DemoJoint.h 内容如下
|
||||
|
||||
```cpp
|
||||
#ifndef DEMOJOINT_H
|
||||
#define DEMOJOINT_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QSemaphore>
|
||||
|
||||
class DemoJoint : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum DemoEnum {
|
||||
DE_OPEN,
|
||||
DE_READ,
|
||||
DE_WRITE,
|
||||
DE_CLOSE,
|
||||
|
||||
DE_OPEN_DONE,
|
||||
DE_READ_DONE,
|
||||
DE_WRITE_DONE,
|
||||
DE_CLOSE_DONE
|
||||
};
|
||||
// 向 QML 声明 DemoEnum 类型.
|
||||
Q_ENUM(DemoEnum);
|
||||
|
||||
explicit DemoJoint(QObject *parent = nullptr);
|
||||
~DemoJoint();
|
||||
|
||||
signals:
|
||||
// 从 QML 调用的信号, 信号不必使用 Q_INVOKABLE 进行显式声明.
|
||||
void qml2Cpp(DemoJoint::DemoEnum op);
|
||||
// 从 DemoIndirect 中发射该信号, QML 中响应该信号.
|
||||
void cpp2Qml(DemoJoint::DemoEnum op);
|
||||
|
||||
protected:
|
||||
class DemoIndirect* demoIndirect;
|
||||
|
||||
void run() override;
|
||||
|
||||
private:
|
||||
QSemaphore initLock;
|
||||
|
||||
};
|
||||
|
||||
#endif // DEMOJOINT_H
|
||||
```
|
||||
|
||||
DemoJoint.cpp 内容如下
|
||||
|
||||
```cpp
|
||||
#include "DemoJoint.h"
|
||||
#include "DemoIndirect.h"
|
||||
|
||||
DemoJoint::DemoJoint(QObject *parent)
|
||||
: QThread{parent}
|
||||
{
|
||||
this->start();
|
||||
initLock.acquire(1);
|
||||
}
|
||||
|
||||
DemoJoint::~DemoJoint()
|
||||
{
|
||||
this->wait();
|
||||
}
|
||||
|
||||
void DemoJoint::run()
|
||||
{
|
||||
this->setPriority(QThread::NormalPriority);
|
||||
demoIndirect = new DemoIndirect(this, nullptr);
|
||||
connect(this, &DemoJoint::qml2Cpp, demoIndirect, &DemoIndirect::onQml2Cpp, Qt::QueuedConnection);
|
||||
initLock.release(1);
|
||||
this->exec();
|
||||
demoIndirect->deleteLater();
|
||||
}
|
||||
```
|
||||
|
||||
DemoIndirect.h 内容如下
|
||||
|
||||
```cpp
|
||||
#ifndef DEMOINDIRECT_H
|
||||
#define DEMOINDIRECT_H
|
||||
|
||||
#include <QObject>
|
||||
#include "DemoJoint.h"
|
||||
|
||||
class DemoIndirect : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DemoIndirect(DemoJoint* j, QObject *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
// 在 DemoJoint run() 方法中连接了该槽.
|
||||
void onQml2Cpp(DemoJoint::DemoEnum op);
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
DemoJoint* joint;
|
||||
|
||||
};
|
||||
|
||||
#endif // DEMOINDIRECT_H
|
||||
```
|
||||
|
||||
DemoIndirect.cpp 内容如下
|
||||
|
||||
```cpp
|
||||
#include "DemoIndirect.h"
|
||||
#include <QDebug>
|
||||
|
||||
DemoIndirect::DemoIndirect(class DemoJoint* j, QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
joint = j;
|
||||
}
|
||||
|
||||
void DemoIndirect::onQml2Cpp(DemoJoint::DemoEnum op)
|
||||
{
|
||||
qDebug()<<"[CPP:DemoIndirect:onQml2Cpp]op="<<op;
|
||||
switch (op) {
|
||||
case DemoJoint::DE_OPEN:
|
||||
emit joint->cpp2Qml(DemoJoint::DE_OPEN_DONE);
|
||||
break;
|
||||
default:
|
||||
emit joint->cpp2Qml(DemoJoint::DE_CLOSE_DONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
main.cpp 内容如下:
|
||||
|
||||
```cpp
|
||||
#include <QApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QQmlContext>
|
||||
#include "DemoJoint.h"
|
||||
#include "DemoDirect.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 注册 DemoDirect 类型, 否则无法在 QML 中使用 DemoDirect 创建对象.
|
||||
qmlRegisterType<DemoDirect>("project.DemoDirect", 1, 0, "DemoDirect");
|
||||
// 注册 DemoJoint 类型, 否则无法在 QML 中使用 DemoJoint.DemoEnum 类型.
|
||||
qmlRegisterType<DemoDirect>("project.DemoJoint", 1, 0, "DemoJoint");
|
||||
// 注册用于在信号槽中使用的类型.
|
||||
qRegisterMetaType<DemoJoint::DemoEnum>("DemoJoint::DemoEnum");
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
QApplication app(argc, argv);
|
||||
|
||||
// 在 C 上下文创建 demoJoint 对象.
|
||||
DemoJoint* demoJoint = new DemoJoint();
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
const QUrl url(QStringLiteral("qrc:/main.qml"));
|
||||
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
|
||||
&app, [url](QObject *obj, const QUrl &objUrl) {
|
||||
if (!obj && url == objUrl)
|
||||
QCoreApplication::exit(-1);
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
// 将 C 环境下的 demoJoint 注册到 QML 上下文中.
|
||||
engine.rootContext()->setContextProperty("demoJoint", demoJoint);
|
||||
engine.load(url);
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
```
|
||||
|
||||
main.qml 内容如下:
|
||||
|
||||
```js
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Window 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
// 导入自定义包, 包名与版本号要与 C 环境下注册的一致.
|
||||
import project.DemoDirect 1.0
|
||||
import project.DemoJoint 1.0
|
||||
|
||||
Window {
|
||||
width: 640
|
||||
height: 480
|
||||
visible: true
|
||||
id: window
|
||||
|
||||
// 直接从 QML 环境下实例化 C 对象.
|
||||
DemoDirect {
|
||||
id: demoDirect
|
||||
}
|
||||
|
||||
Text {
|
||||
id: demoText
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.rightMargin: 8
|
||||
anchors.leftMargin: 8
|
||||
anchors.topMargin: 8
|
||||
// 显示 demoDirect 的 cppStr 属性值, 注意这是一个只读属性.
|
||||
text: demoDirect.cppStr
|
||||
}
|
||||
|
||||
Button {
|
||||
id: demoBut
|
||||
width: 64
|
||||
height: 24
|
||||
text: qsTr("信号测试")
|
||||
anchors.left: parent.left
|
||||
anchors.top: demoText.bottom
|
||||
anchors.leftMargin: 8
|
||||
anchors.topMargin: 8
|
||||
|
||||
onClicked: {
|
||||
// 从 QML 环境中向 C 环境发送信号.
|
||||
demoJoint.qml2Cpp(DemoJoint.DE_OPEN)
|
||||
// 直接调用 C 方法.
|
||||
demoDirect.writeCppStr("Hello")
|
||||
}
|
||||
}
|
||||
|
||||
// 使用 Connections 与 C 信号建立连接, 并处理 cpp2Qml() 信号.
|
||||
Connections {
|
||||
target: demoJoint
|
||||
function onCpp2Qml(op) {
|
||||
console.log("[QML:onCpp2Qml]op=", op)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 13. Windows 下 QML 程序的打包发布
|
||||
|
@ -494,12 +939,13 @@ Qt 自带的打包程序会添加额外的库,如果想进一步减小体积
|
|||
|
||||
1. [深入了解JS中的整数](https://www.jianshu.com/p/1ba45c3894ab)
|
||||
2. [QML 中的信号与槽](https://blog.csdn.net/Love_XiaoQinEr/article/details/123746983)
|
||||
3. [QML 控件类型:ScrollBar、ScrollIndicator](https://blog.csdn.net/kenfan1647/article/details/122522063)
|
||||
4. [QML类型:GridView](https://blog.csdn.net/kenfan1647/article/details/120761466)
|
||||
5. [Qt Quick 常用元素:ComboBox(下拉列表) 与 ProgressBar(进度条)](https://www.cnblogs.com/linuxAndMcu/p/11949814.html)
|
||||
6. [【QML Model-View】ListView-增删改查(二)](https://www.cnblogs.com/linuxAndMcu/p/13597106.html)
|
||||
7. [关于 Q_ENUMS 和 Q_ENUM 的区别和用法](https://blog.csdn.net/lsylovezsl/article/details/108766437)
|
||||
8. [C++ 共享枚举类型给 QML](https://www.cnblogs.com/linkyip/p/14462288.html)
|
||||
9. [QML Connections: Implicitly defined onFoo properties in Connections are deprecated.](https://blog.csdn.net/weixin_43720622/article/details/112346039)
|
||||
10. [QML 调用 C++ 方法](https://blog.csdn.net/woshouji1/article/details/121348179)
|
||||
11. [Qml 与 C++ 交互3:Qml 的信号与 C++ 的槽函数连接](https://blog.csdn.net/tanxuan231/article/details/124990296)
|
||||
3. [QML 信号与响应方法的总结](https://zhuanlan.zhihu.com/p/576316521)
|
||||
4. [QML 控件类型:ScrollBar、ScrollIndicator](https://blog.csdn.net/kenfan1647/article/details/122522063)
|
||||
5. [QML 类型:GridView](https://blog.csdn.net/kenfan1647/article/details/120761466)
|
||||
6. [Qt Quick 常用元素:ComboBox(下拉列表) 与 ProgressBar(进度条)](https://www.cnblogs.com/linuxAndMcu/p/11949814.html)
|
||||
7. [【QML Model-View】ListView-增删改查(二)](https://www.cnblogs.com/linuxAndMcu/p/13597106.html)
|
||||
8. [关于 Q_ENUMS 和 Q_ENUM 的区别和用法](https://blog.csdn.net/lsylovezsl/article/details/108766437)
|
||||
9. [C++ 共享枚举类型给 QML](https://www.cnblogs.com/linkyip/p/14462288.html)
|
||||
10. [QML Connections: Implicitly defined onFoo properties in Connections are deprecated.](https://blog.csdn.net/weixin_43720622/article/details/112346039)
|
||||
11. [QML 调用 C++ 方法](https://blog.csdn.net/woshouji1/article/details/121348179)
|
||||
12. [Qml 与 C++ 交互3:Qml 的信号与 C++ 的槽函数连接](https://blog.csdn.net/tanxuan231/article/details/124990296)
|
||||
|
|
Loading…
Reference in New Issue