简述
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)
}
}
}