Qml调用C++方法,属性,信号,槽

有两种方法,一种是向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++ 的信号')
            }

}

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值