有两种方法,一种是向qml注册c++类,把这个类当做qml组件使用。二种是向qml注册c++实例对象,在qml中直接使用这个对象。
(1)向qml注册c++类
创建一个类,定义属性和方法,信号,槽
#ifndef QMLOBJ_H
#define QMLOBJ_H
#include <QObject>
#include<qdebug.h>
class QmlObj: public QObject
{
Q_OBJECT //这个宏定义必须写这里
//在qml中可以访问c++中的属性,方法,信号和槽
//访问属性要使用Q_PROPERTY注意写法,比如访问age这个属性,
//READ: qml获取age的值,WRITE:qml可以修改age的值,
//NOTIFY:信号函数,qml可以接受c++的信号。
//例如age的值改变时发信号给qml
Q_PROPERTY(int age READ getAge WRITE setAge NOTIFY ageChanged)
public:
QmlObj();
//通过Q_INVOKABLE宏标记的public函数可以在QML中访问
Q_INVOKABLE void doCPPFun(){
qDebug("qml调用了c++的方法age=%d",age);
emit ageChanged();
}//功能为发送信号
//给属性添加qml访问方法,
int getAge(){ return age;}
void setAge(int a){age = a;}
signals:
void ageChanged();
public slots:
void funSlots(){
qDebug("c++的收到qml信号");
}
private:
int age;
};
#endif // QMLOBJ_H
注册c++类
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include<qstring.h>
#include<qfile.h>
#include<qtranslator.h>
#include<qdebug.h>
#include"qmlobj.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
//在qml加载之前注册c++类
//qmlRegisterType注册C++类到QML
//arg1:import时模块名 在qml中使用import QmlTestObject 1.0引入文件,1.0是主版本和次版本号
//arg2:主版本号
//arg3:次版本号
//arg4:QML类型名
qmlRegisterType<QmlObj>("QmlTestObject",1,0,"QmlObj");
//注册完成后去qml文件去使用
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
在qml文件里面这样写
import QtQuick 2.9
import QtQuick.Controls 2.2
//这里引入模板
import QmlTestObject 1.0
ApplicationWindow {
id:root
visible: true
width: 640
height: 480
title: qsTr("Scroll")
//写一个qml的信号,然后绑定到c++
signal qmlSignal
Button{
text: "button"
onClicked: {
//qml去调属性用c++属性
cppObj.age = 11
//调用c++的方法
qobj.doCPPFun()
//qml发送信号,c++也能收到
root.qmlSignal()
//c++去调属性用c++属性
qobj.age = 1000
//调用c++的方法
qobj.doCPPFun()
//qml发送信号,c++也能收到
root.qmlSignal()
}
}
//也可以把c++对象设置给Qml的属性,
property var cppObj : qobj
//用cppObj去调用age属性
property int qmmlAge: cppObj.age
//c++文件这样使用,当做一个qml对象
QmlObj{
id:qobj
//也可以添加额外的属性
property int height: 100
//也可以这样绑定c++的信号,前面加on首字母大写,当c++发送信号时,就可以收到
onAgeChanged: {
console.log('qml接收c++信号')
}
}
//组件加载完成
Component.onCompleted: {
//关联信号与信号处理函数的方式同QML中的类型
//把C++对象的信号关联到Qml
qobj.onAgeChanged.connect(soltfun) //js的lambda
//Qml对象的信号关联到C++的槽函数
root.onQmlSignal.connect(qobj.funSlots)
}
//定义槽函数
function soltfun(){
console.log('qml 收到 c++ 的信号')
}
}
这样就完成了
(2)向qml注册c++实例对象
创建一个类,把这个类的一个实例对象注册给qml
用qmlRegisterSingletonType()注册
#ifndef SINGLETONOBJ_H
#define SINGLETONOBJ_H
#include <QObject>
#include"qmlobj.h"
class SingletonObj : public QObject
{
Q_OBJECT //这个宏定义必须写这里
//属性也可以是一个对象,在qml中可以访问这个对象的属性,方法等。
//这里是一个对象
Q_PROPERTY(QmlObj* qmlobj READ qmlobj CONSTANT)
public:
explicit SingletonObj(QObject *parent = nullptr);
QmlObj * qmlobj(){
return _qmlobj;
}
private:
QmlObj *_qmlobj = new QmlObj();
};
#endif // SINGLETONOBJ_H
在main方法中注册
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include<qstring.h>
#include<qfile.h>
#include<qtranslator.h>
#include<qdebug.h>
#include"qmlobj.h"
#include"singletonobj.h"
#include<qqml.h>
static QObject* qmlGlobalSingletonFactory(QQmlEngine*, QJSEngine*)
{
// We create this object as a QGCTool even though it isn't in the toolbox
SingletonObj* qmlGlobal = new SingletonObj();
return qmlGlobal;
}
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
//在qml加载之前注册c++类
//qmlRegisterType注册C++类到QML
//arg1:import时模块名 在qml中使用import QmlTestObject 1.0引入文件,1.0是主版本和次版本号
//arg2:主版本号
//arg3:次版本号
//arg4:QML类型名
//qmlRegisterType<QmlObj>("QmlTestObject",1,0,"QmlObj");
//注册一个单例对象
qmlRegisterSingletonType<SingletonObj>("SingleObj",1,0,"SingleObj",qmlGlobalSingletonFactory);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
在qml中这样使用
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtLocation 5.6
import QtPositioning 5.6
//这里引入模板
//import QmlTestObject 1.0
import SingleObj 1.0
ApplicationWindow {
id:root
visible: true
width: 640
height: 480
title: qsTr("Scroll")
//把qmlobj对象赋值给qml的属性qobj,qobj其实是c++对象
property var qobj: SingleObj.qmlobj
//qobj其实是c++对象,所以可以使用对象的属性,方法等
property int age: qobj.age
//写一个qml的信号,然后绑定到c++
signal qmlSignal
Button{
text: qsTr("Scroll")
onClicked: {
//qml去调属性用c++属性
qobj.age = 11
//调用c++的方法
qobj.doCPPFun()
//qml发送信号,c++也能收到
root.qmlSignal()
//c++去调属性用c++属性
qobj.age = 1000
//调用c++的方法
qobj.doCPPFun()
//qml发送信号,c++也能收到
root.qmlSignal()
}
}
//组件加载完成
Component.onCompleted: {
//关联信号与信号处理函数的方式同QML中的类型
//把C++对象的信号关联到Qml
qobj.onAgeChanged.connect(soltfun) //js的lambda
//Qml对象的信号关联到C++的槽函数
root.onQmlSignal.connect(qobj.funSlots)
}
//定义槽函数
function soltfun(){
console.log('qml 收到 c++ 的信号')
}
}