QML学习之QML与C++交互,Qml访问C++(三)

简述

Qml要访问C++的内容,需要先从C++把要访问的内容注册进Qml。
先说说能用哪些:
注册过后,Qml中可以访问的内容,包括 Q_INVOKABLE 修饰的函数、枚举、 QObject的属性 信号 槽
Q_INVOKABLE 函数可以用在普通的结构体或者类中,但是这种用法不常见/不方便。常见的是在QObject的子类中,给非槽函数设置为Q_INVOKABLE。QObject的属性 信号 槽,都是可以通过注册后,在qml中使用的。信号、槽都可以带参数,槽可以有返回值。
这里要说的是,属性、函数参数、返回值的类型,都需要是Qml能识别的类型。
Qt的常用类型已经在Qt内部注册好了,自定义的需要单独注册。再说说怎么用:
注册分为两种:注册类型和注册实例。

注册类并使用

qmlRegisterType<类>("导入模块名“,主版本号,次版本号,"模块名称”)

qmlRegisterType<ZhouJing>("myZhou",1,0,"ComZhou");

类的头文件

#ifndef ZHOUJING_H
#define ZHOUJING_H

#include <QObject>

class Zhou : public QObject
{
    Q_OBJECT
public:
    explicit Zhou(QObject *parent = nullptr);

    Q_INVOKABLE void sing(); //invok函数,可以被Qml调用。可以带参数和返回值
public slots:
    //打游戏,参数为次数,返回值为得分
    int playGame(int count);    //槽函数,可以被Qml调用。可以带参数和返回值
signals:
    //想吃东西函数
    void hungry(const QString &foodName); //信号,可以被Qml接收到
};

#endif // ZHOUJING_H

类的源文件:

#include "zhoujing.h"
#include <QDebug>

Zhou::Zhou(QObject *parent)
    : QObject{parent}
{

}

void Zhou::sing()
{
    qDebug()<<"小周在唱歌告白气球:";
}

int Zhou::playGame(int count)
{
    int num = count;
    return num;
}

main.cpp文件:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "zhou.h"

int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    qmlRegisterType<Zhou>("myZhou",1,0,"ComZhou");
    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);
    engine.load(url);

    return app.exec();
}

qml文件:

import QtQuick 2.15
import QtQuick.Window 2.15
import myZhou 1.0
import QtQuick.Controls 2.15

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    ComZhou{
        id: zj
        onHungry: {  //给信号写个槽函数
            if(foodName =="蛋炒饭")
                console.log("小周要吃蛋炒饭")
            else if(foodName == "面条")
                console.log("小周要吃面条")

        }
    }

    Button {
        onClicked: {
            //这个按钮按下的时候,涛哥开始唱歌
            tao.sing();
        }
    }
    Button {
        onClicked: {
            //这个按钮按下的时候,周靖开始打游戏
            zj.sing();
            zj.hungry("面条");
            let score = zj.playGame(23);
            console.log("小周打游戏次数",4,"得分为", score)
        }
    }
}

注册实例并使用

Zhou obj;     //C++中创建的实例

//如果用QQ'u'ic'kView加载Qml
QQuickView view;
...
view.rootContext()->setContextProperty("obj", &obj);    //注意这个名字不要用大写字母开头,规则和Qml中的id不能用大写字母开头一样。

//如果用QQmlEngine加载Qml
QQmlEngine engine;
...
engine..rootContext()->setContextProperty("obj", &obj); //注意这个名字不要用大写字母开头,规则和Qml中的id不能用大写字母开头一样。
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "zhoujing.h"

int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    Zhou obj;
//    qmlRegisterType<Zhou>("myZhou",1,0,"ComZhou");
    engine.rootContext()->setContextProperty("obj",&obj);
    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);
    engine.load(url);

    return app.exec();
}

qml文件:

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    Connections{
        target: obj   //指定target
        onHungry: {  //给信号写个槽函数
            if(foodName =="蛋炒饭")
                console.log("小周要吃蛋炒饭")
            else if(foodName == "面条")
                console.log("小周要吃面条")

        }
    }

    Button {
        onClicked: {
            //这个按钮按下的时候,涛哥开始唱歌
            obj.sing();
        }
    }
    Button {
        onClicked: {
            //这个按钮按下的时候,周靖开始打游戏
            obj.sing();
            obj.hungry("面条");
            let score = obj.playGame(23);
            console.log("小周打游戏次数",4,"得分为", score)
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值