qml: C++调用qml函数

时间:2021-11-09 11:47:28

C++调用qml函数,是通过下面的函数实现的:

bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, 
QGenericArgument val0 = QGenericArgument( Q_NULLPTR ), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(), QGenericArgument val4 = QGenericArgument(), QGenericArgument val5 = QGenericArgument(), QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(), QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument());

这里有两个常用的宏:Q_RETURN_ARG,Q_ARG,从字面意思就可以看出来,一个是用来获取返回值,另一个用于传参。 下面是一个例子:

QVariant returnedValue;
QVariant msg = "message sended from C++";
QMetaObject::invokeMethod(pctrlobj, "setTextString", Q_RETURN_ARG(QVariant, returnedValue),Q_ARG(QVariant, msg));

在应用该函数调用qml对象成员前,关键是要获取到要调用的qml对象,有两种方案可以很方便的获取到qml对象:

1)  从qml端直接传QOBject * 到C++端;

2)  通过设置objectName,利用findChild()找到对应的对象;

第一种方案就不说了,很简单实现,这里简略的讲解下第二种方案,  看下面的例子:

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.3
Window {
id: windows;
visible: true
width: 640
height: 480
title: qsTr("Hello World") Button{
id: test;
width: 70;
height: 30;
onClicked: test1.open();
} Test1{
id: test1;
visible: false;
onShowTest:{
}
} function test()
{
console.log("test ok!");
} }

Test1.qml

import QtQuick 2.0
import QtQuick.Window 2.2
import QtQuick.Controls 1.3
Window {
id: test;
width: 300;
height: 200;
visible:false;
signal showTest(); Button{
id: testButton;
objectName:"testButton" //这里设置了对象名称,用于findChild()获取对象;
text:"click me";
onClicked:{
showTest();
}
} function open()
{
test.visible = true;
} function close()
{
test.visible = false;
} }

  

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QObject>
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif QGuiApplication app(argc, argv); QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); QObject *pRoot = engine.rootObjects().first(); QObject *pButton = pRoot->findChild<QObject *>("testButton");
if( pButton )
{
QObject::connect(pButton,SIGNAL(clicked()),pRoot,SLOT(test()));
} if (engine.rootObjects().isEmpty())
return -1; return app.exec();
}