C++調用qml函數,是通過下面的函數實現的:
bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, <br>QGenericArgument val0 = QGenericArgument( Q_NULLPTR ), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(),<br> QGenericArgument val3 = QGenericArgument(), QGenericArgument val4 = QGenericArgument(), QGenericArgument val5 = QGenericArgument(), QGenericArgument val6 = QGenericArgument(),<br> 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();
}
