C++调用QML中的函数
//main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
QObject *object = engine.rootObjects().first();
QObject *rect = object->findChild<QObject*>("rect");
if(object){
QVariant sum;
QMetaObject::invokeMethod(object, "myAdd", Q_RETURN_ARG(QVariant, sum), Q_ARG(QVariant, 1), Q_ARG(QVariant, 2));
if(sum.isValid()){
qDebug() << "sum : " << sum.toDouble();
}
}
if(rect){
QMetaObject::invokeMethod(rect, "myPrint");
}
return app.exec();
}
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
function myAdd(left, right){
return left + right;
}
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle{
id: rect
objectName: "rect"
function myPrint(){
console.log(rect.width + "x" + rect.height + "rectangle");
}
width: 40
height: 40
color: "red"
anchors.centerIn: parent
}
}
这就是最简单的 C++ 调用 qml的函数。
**注意 : ** 如果是按照正常的 javaScript函数的写法,因为 JavaScript是弱类型语言。所有在QT中参数包括返回值的类型都要使用QVariant
来代替。而且如果要获取返回值在 QMetaObject::invokeMethod
一定要把 Q_RETURN_ARG
写在第一个Q_ARG
参数的前方。如果想要调用的 qml 的函数不是在根 object 中,那么还要在qml的对象中设置objectName
属性。然后QT C++使用 findChild
找到该 对象后然后在进行调用。
C++中链接qml中的信号或者槽
//MyTest.h
#ifndef MYTEST_H
#define MYTEST_H
#include <QObject>
class MyTest : public QObject
{
Q_OBJECT
public:
explicit MyTest(QObject *parent = nullptr);
signals:
public slots:
void slotClick();
};
#endif // MYTEST_H
//MyTest.cpp
#include "MyTest.h"
#include <QDebug>
MyTest::MyTest(QObject *parent) : QObject(parent)
{
}
void MyTest::slotClick()
{
qDebug() << QStringLiteral("按钮点击了");
}
//main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
function myAdd(left, right){
return left + right;
}
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Button{
id: button
objectName: "button"
width: 40
height: 20
text: "按钮"
}
Rectangle{
id: rect
objectName: "rect"
function myPrint(){
console.log(rect.width + "x" + rect.height + "rectangle");
}
width: 40
height: 40
color: "red"
anchors.centerIn: parent
}
}
//main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QDebug>
#include "MyTest.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
QObject *object = engine.rootObjects().first();
QObject *rect = object->findChild<QObject*>("rect");
if(object){
QVariant sum;
QMetaObject::invokeMethod(object, "myAdd", Q_RETURN_ARG(QVariant, sum), Q_ARG(QVariant, 1), Q_ARG(QVariant, 2));
if(sum.isValid()){
qDebug() << "sum : " << sum.toDouble();
}
}
if(rect){
QMetaObject::invokeMethod(rect, "myPrint");
}
MyTest *test = new MyTest;
QObject *button = object->findChild<QObject*>("button");
QObject::connect(button, SIGNAL(clicked()), test, SLOT(slotClick()));
return app.exec();
}
**注意 ** 要注意的点就是使用的是 QObject::connect
是QT4的连接方式。注意QT4的连接方式是这么写的。