[网页](https://blog.csdn.net/baidu_33850454/article/details/81907857?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166731863916782429784725%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=166731863916782429784725&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-3-81907857-null-null.nonecase&utm_term=QML%20%E4%B8%8E%20C%2B%2B&spm=1018.2226.3001.4450)
QML与C++进行数据交互的方法包括信号与槽链接、QML调用C++类等。
# 1、QML调用(实例化)C++类
**思路:**
[官方案例](https://doc.qt.io/qt-5/qtqml-cppintegration-topic.html)
再QML中实例化自己定义的C++类;
**优点:**
- 可以方便的利用Qt的属性系统从QML中访问C++类中的属性。再QML程序中定义该C++类时会直接实例化该类。
**缺点:**
- 无法再C++中对QML中实例化的类对象进行操作;
- 只能访问使用属性系统`Q_PROPERTY`声明的属性;
- 无法设置QML中访问指定的对象,即无法访问C++中的单例;
**详细描述:**
1. 使用Qt Creator中的"Qt Quick Application"模板创建一个新的项目;
> 注意:取消选中New Project Wizard的Define Project Details部分中的With ui.qml文件选项。
2. 添加C++类,命名为Call_Back,作为QML中使用的C++类,类的方法如下:
<details>
<summary>点击查看:头文件</summary>
```
#ifndef CALL_BACK_H
#define CALL_BACK_H
#include <QObject>
#include <QString>
class Call_Back: public QObject
{
Q_OBJECT
//只读,只写,改变信号
Q_PROPERTY(QString userName READ userName WRITE setuserName NOTIFY userNameChanged)
public:
explicit Call_Back(QObject *parent = nullptr);
QString userName;
void setuserName(const QString &userName);
void callClassFunction();
signals:
void userNameChanged();
private:
QString m_userName;
};
#endif // CALL_BACK_H
```
</details>
<details>
<summary>点击查看:源文件</summary>
```
#include "call_back.h"
#include <QDebug>
// 构造函数
Call_Back::Call_Back(QObject *parent):
QObject(parent)
{
qDebug() << "-------Class construct-------";
m_userName = "hello world";
}
QString Call_Back::userName()
{
qDebug() << __FILE__ << __func__ << m_userName;
return m_userName;
}
void Call_Back::setuserName(const QString &userName)
{
qDebug() << __FILE__ << __func__ << userName;
if (userName == m_userName)
return;
m_userName = userName;
emit userNameChanged();
}
void Call_Back::callClassFunction()
{
qDebug() << __FILE__ << __func__ << __LINE__;
}
```
</details>
> 每次值改变时,该setUserName函数都会>发出userNameChanged信号。可以在QML中使用onUserNameChanged处理该信号。
3. 在main.cpp中注册该方法到QML
包含头文件Call_Back.h
使用`qmlRegisterType<BackEnd>("io.qt.examples", 1, 0, "Call_Back");`注册方法;
4. 将main.qml的内容替换如下:
<details>
<summary>点击查看:main.qml</summary>
```
import QtQuick 2.6
import QtQuick.Controls 2.0
import io.qt.examples 1.0
//io.qt.examples 是使用qmlRegisterType进行注册的方法,名称必须和注册时一致
ApplicationWindow {
id: root
width: 300
height: 480
visible: true
BackEnd {
id: backend
}
Text {
id: txt1
x: 20
y: 20
text: backend.userName
}
TextField {
text: backend.userName
placeholderText: qsTr("User name")
anchors.centerIn: parent
onTextChanged:{
backend.userName = text
}
}
}
```
</details>
每当`m_userName`的值发生变化时,`setUserName`函数就会发出`userNameChanged`信号。可以使用`onUserNameChanged`处理程序从QML处理信号。