注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

沙漠里de烟雨

原创分享,禁止转载

 
 
 

日志

 
 

Qt C++与 QML之间的相互调用  

2017-05-11 02:34:13|  分类: QT5.x与QML |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
废话多余,上代码:
C++调用QML
xx.pro :  
QT       += core quick qml

main.cpp =>
#include <QGuiApplication>
#include <QtQml>
//#include <QQmlEngine>
//#include <QQmlComponent>
#include <QList>
#include <QDebug>

//C++中加载了qml文件并进行组件实例化后,就可以在C++中访问,修改这个实例的属性值了,可以是qml内建的属性,
//也可以是自定义属性;C++加载qml文件可以用QQmlComponent或QQuickView,然后就可以在C++中访问QML对象了,
//QQuickView提供了一个显示用户界面的窗口,而QQmlComponent则没有;
//QQuickView::rootObject()返回了组件的实例;
int main(int argc, char *argv[])
{
    QGuiApplication a(argc, argv);

    QQmlEngine engine;
    QQmlComponent component(&engine);
    component.loadUrl(QUrl("../CppClassInvokeQml/main.qml"));
    QObject* obj = NULL;
    if(component.isReady())
        obj = component.create();
    else
        qWarning() << component.errorString();

    qDebug() << obj->setProperty("height",600) << endl;//设置属性;
    qDebug() << "height:" << obj->property("height").toInt() << endl;//读取属性;
    qDebug() << "height value:" << QQmlProperty::read(obj,"height").toInt() << endl;//读取属性

    QQmlProperty::write(obj,"width",450);//设置属性;
    qDebug() << "width:" << obj->property("width").toInt() << endl;

    //注:
    //如果对象是QQuickItem类型,则可以使用QQuickView::rootObject()的返回值,
    //此时可以使用:QQuickItem::width/setWidth()来访问与修改width属性值;

    QObject* childObj = obj->findChild<QObject*>("subItem"); //寻找子项,qml中必须要设置objectName值,在C++中才可以找到相应的对象;
    if(childObj)
    {
        childObj->setProperty("height",500);
        qDebug() << "child height:" << childObj->property("height").toInt() << endl;
    }

    //遍历对象下的子对象;Qt::FindChildrenRecursively表明会迭代遍历子对象的子对象,最终找出所有的子对象,Qt::FindDirectChildrenOnly只是遍历当前节点的下一级的节点,不会遍历到孙子节点;
    QList<QObject*> childList = /*obj->findChildren<QObject*>();*/obj->findChildren<QObject*>(QString(),/*Qt::FindChildrenRecursively*/Qt::FindDirectChildrenOnly);
    if(childList.count()>0)
    {
        foreach(QObject* o,childList)
        {
            qDebug() << "child name:" << o->objectName() <<endl;
            qDebug() << "child width:" << o->property("width").toInt() << endl;
        }
    }

    //调用qml的函数与信号;
    //C++中使用QMetaObject::invokeMethod()调用qml的函数;QObject::connect()来访问qml的信号;
    //从qml传递过来的函数参数和返回值均被转换为C++中的QVariant类型,成功为true,失败为false;
    //必须使用Q_ARG()宏来声明函数参数,用Q_RETURN_ARG()宏来声明函数返回值;
    //QGenericArgument  Q_ARG(Type,const Type & value)
    //QGenericReturnArgument Q_RETURN_ARG(Type,Type & value)
    //QObject::connet()连接qml信号,QObject::disconnect()解除连接;
    QVariant res;
    QVariant msg = "msg from Cpp";
    QMetaObject::invokeMethod(obj,"qmlFunction",Q_RETURN_ARG(QVariant,res),Q_ARG(QVariant,msg));
    qDebug() << "res:" << res.toString() << endl;

 //   QObject::connect(obj,SIGNAL(qmlSignal(QString)),this,SLOT(..));


    return a.exec();
}


main.qml =>
import QtQuick 2.0

Item {
    objectName:"rootItem"
    visible:true
    width: 360
    height: 360
    Item {
        id: subId
        objectName: "subItem"
        width:200
        height:100
        Item
        {
            id: subsubId
            objectName:"subsubItem"
            width:50
            height:20
        }
    }
    Item
    {
        id: subId2
        objectName: "subItem2"
        width:100
        height:100
    }

    signal qmlSignal(string msg)    //qml信号;
    onQmlSignal: console.log("qml signal msg :",msg) //上面qmlSignal信号的槽函数;
    function qmlFunction(param) //qml函数;
    {
        console.log("qml function param:",param)
        return "qml function's return"
    }

    Component.onCompleted:qmlSignal("I am a message from qml."); //qml发送了一个信号;
}



QML调用C++类:
xx.pro : 
QT += qml quick
main.cpp =>
#include <QGuiApplication>
//#include <QQmlApplicationEngine>

#include <QQuickView>
#include <QQmlContext>
#include "MyClass.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

 //   QQmlApplicationEngine engine;
 //   engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    QQuickView view;
    MyClass mycls;
    view.rootContext()->setContextProperty("MyClass",&mycls);
    view.setSource(QUrl(QStringLiteral("qrc:///main.qml")));
    view.show();

    return app.exec();
}

main.qml =>
import QtQuick 2.2
import QtQuick.Window 2.1

Item {
    width: 360
    height: 360

    MouseArea {
        anchors.fill: parent
        onClicked: {
         //   Qt.quit();
            MyClass.DoSomethingSlot() //槽;
            MyClass.myFunction() //函数;
        }
    }

    Connections
    {
        target:MyClass;
        onMySignal:console.log("....");
    }

}

myclass.h =>
#ifndef MYCLASS_H
#define MYCLASS_H

#include <QObject>

class MyClass : public QObject
{
    Q_OBJECT
//qml访问的C++类必须是基于QObject以及Q_OBJECT的C++类;
//qml访问C++中的成员必须是public或protected的成员函数(前加Q_INVOKABLE),Enum类型则必须是public类型;

    Q_ENUMS(MyEnum) //将公有的Enum类型MyEnum暴露给qml后,qml可以直接使用了;

    Q_PROPERTY(int myPrty READ GetMyProperty WRITE SetMyProperty NOTIFY myPropertyValueChanged)//"myPrty"为在qml中使用的属性名称;

public:
    explicit MyClass(QObject *parent = 0);
    ~MyClass();

signals:
    void mySignal(); //若需被qml调用,则信号首字母不能大写;在Qml中则以 onMySignal:槽 的方式做信号与槽的绑定;若是C++中调用,则无此大小写限制;
    void mySignal(int); //在qml中信号是不可实现重载的,故相同名的信号,尽管参数不一致,也只能识别最后一个信号;
    void mySignal2();
    void UseInCppSignal();//在qml中无法使用;
    void mySignal3();
public slots:
    void doSomethingSlot();
    void doSomethingSlot(int index);
    void DoSomethingSlot(); //注意大写,槽函数首字母无大小写限制,均可在qml中使用;
    void DoDoDoSlot(int nDo);
public:
    enum MyEnum
    {
        ENUM_RED=1,
        ENUM_BALCK=2,
        ENUM_HELLO=3
    };
public://or protected,且前面加Q_INVOKABLE,这样才能被qml使用,函数无首字母小写限制,也可支持重载;
    Q_INVOKABLE void myFunction();
    Q_INVOKABLE void myFunction(int index);
    Q_INVOKABLE void MyFunction();


//--要暴露给qml的属性m_MyPorperty,且还要在使用Q_PROPERTY宏声明此属性;
signals:
    void myPropertyValueChanged();//无参,或type类型的参数,用于记录属性改变后的值,这里type为int;
public:
    int GetMyProperty()const; //const,且无参;
    void SetMyProperty(int value);//return void,且只有一个参数,类型为 type,type& 或 type* ,这里type为int;
private:
    int m_MyPorperty;
//--



};

#endif // MYCLASS_H

myclass.cpp =>
#include "myclass.h"

#include <qdebug.h>

MyClass::MyClass(QObject *parent) : QObject(parent)
{

}

MyClass::~MyClass()
{

}

void MyClass::doSomethingSlot()
{
   qDebug() << "dosomethingSlot() called!" << endl;
}

void MyClass::doSomethingSlot(int index)
{
   qDebug() << "dosomethingSlot(int) called, index :" << index << endl;
}
void MyClass::DoSomethingSlot()
{
    qDebug() << "DosomethingSlot() called! caps.." << endl;
}

void MyClass::DoDoDoSlot(int nDo)
{
    qDebug() << "DoDoDoSlot(int) called, nDo:" << nDo << endl;
}

void MyClass::myFunction()
{
    qDebug() << "myFunction() called!" << endl;
}

void MyClass::myFunction(int index)
{
    qDebug() << "myFunction(int) called,index:" << index << endl;
}

void MyClass::MyFunction()
{
    qDebug() << "MyFunction() called! caps..." << endl;
}

int MyClass::GetMyProperty() const
{
    return m_MyPorperty;
}

void MyClass::SetMyProperty(int value)
{
    m_MyPorperty = value;
}


  评论这张
 
阅读(6)| 评论(0)
推荐

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017