qml 调用 C++ 函数
qml 要使用 C++ 的函数有两个方法:
一种是,用Q_INVOKABLE
标记该函数,
另一种是,该函数为 Qt 槽函数。
案例 a:Q_INVOKABLE 标记 C++ 函数 + 视图设置进 qml 属性
案例 a 使用 视图(QQuickView),实现了 qml 调用 C++ 代码。
原理是,用视图调用接口,设置上下文属性 view.rootContext()->setContextProperty(/*xxx*/)
,将 C++ 的一个自定义类注册为 qml 属性。
🐎:main.cpp
#include <QApplication>
#include <QQuickView>
#include "applicationdata.h"
#include <QQmlContext>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
// 定义一个视图对象
QQuickView view;
ApplicationData data;
// 将C++对象作为属性注册到qml
view.rootContext()->setContextProperty("ApplicationData", &data);
view.setSource(QUrl("../item.qml"));
view.show();
return app.exec();
}
🐎:applicationdata.h
#ifndef APPLICATIONDATA_H
#define APPLICATIONDATA_H
#include <QObject>
#include <QDateTime>
class ApplicationData : public QObject
{
Q_OBJECT
public:
explicit ApplicationData(QObject *parent = nullptr){}
Q_INVOKABLE QDateTime getCurrentDateTime() const
{
return QDateTime::currentDateTime();
}
signals:
};
#endif // APPLICATIONDATA_H
🐎:item.qml
import QtQuick 2.15
Text {
text: ApplicationData.getCurrentDateTime()
}
运行结果:调用成功啦
案例 b:qml 通过发送信号的方式,调用 Qt 槽函数
qml 设置信号的语法:
signal SignalName(参数类型 参数名)
本案例在 onClicked 中调用槽函数,调用语法为:
信号所在对象的id.SignalName
🐎:myclass.h
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
#include <QDebug>
class MyClass : public QObject
{
Q_OBJECT
public:
explicit MyClass(QObject *parent = nullptr){}
public slots:
void slotPrint(QString msg)
{
qDebug() << msg;
}
signals:
};
#endif // MYCLASS_H
🐎:main.cpp
#include <QApplication>
#include <QQuickView>
#include <QQuickItem>
#include "myclass.h"
/*
* C++使用槽函数
* 接收信号:设置一个类对信号进行收到反馈的槽函数
* 发送信号:qml对象
*/
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
// 视图绑定的另一种写法
QQuickView view(QUrl::fromLocalFile("../QML_signal/item.qml"));
// 创建对象,用来标记发送信号方
QObject* item = view.rootObject();
// 创建信号槽的对象
MyClass myClass;
QObject::connect(item,
SIGNAL(qmlSignal(QString)),
&myClass,
SLOT(slotPrint(QString)));
view.show();
return app.exec();
}
🐎:item.qml
import QtQuick 2.15
Item {
id: item; width: 200; height: 200
signal qmlSignal(string msg)
MouseArea
{
anchors.fill: parent
onClicked: item.qmlSignal("你点了我一下");
}
}
运行结果:调用成功
C++调用qml函数
本案例使用 引擎(QQmlApplicationEngine):实现了C++调用qml的函数。
原理是,通过元对象的 invokeMethod
接口,调用需要的函数,其中要注意的是invokeMethod 的参数列表和返回值必须指定类型为 Qvariant
。
🐎:main.cpp
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlComponent>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
// 创建引擎
QQmlApplicationEngine engine;
// 添加组件到引擎中
QQmlComponent comp(&engine, "../item.qml");
// 用组件创建对象
QObject* obj = comp.create();
QVariant msg = "hello qml and c++"; // 传给obj中qmlFunc函数的参数
QVariant returnedValue; // 接收返回值
// invokeMethod 的参数列表和返回值必须指定类型为 Qvariant
QMetaObject::invokeMethod
(obj,
"qmlFunc",
Q_RETURN_ARG(QVariant, returnedValue), // 返回值
Q_ARG(QVariant, msg)); // 参数
// 打印返回值验证结果
qDebug() << "QML function returned: " << returnedValue.toString();
return app.exec();
}
🐎:item.qml
import QtQuick 2.15
Text {
function qmlFunc(msg)
{
console.log("this is a message: ", msg)
return "aoao"
}
}
运行结果:调用成功
🥰如果本文对你有些帮助,欢迎👉 点赞 收藏 关注,你的支持是对作者大大莫大的鼓励!!(✿◡‿◡) 若有差错恳请留言指正~~