Setting up a slot for QmlApplicationViewer
-
Hi there,
I've been trying to find a solution for this the past few hours and I'm kind of stuck here. I have a main.cpp file which loads my qml file like this:
@QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer.setMainQmlFile(QLatin1String("qml/test/main.qml"));
viewer.showExpanded();@So nothing special. Also, I have a QThread that's running and which is emitting signals. Now I try to set up a slot (or something else) that calls a function in my qml file. I tried to add a slot into qmlapplicationviewer.h and implemented it in qmlapplicationviewer.cpp like that:
@void QmlApplicationViewer::zoom(int scale){
QVariant sc = scale;
QObject* mainItem = this->findChild<QObject *>("mainItem");
QMetaObject::invokeMethod(mainItem, "zoomIn", Q_ARG(QVariant, sc));
}@In main.cpp I connect the signal to the slot:
@QObject::connect( canThread, SIGNAL( zoom(int) ), &viewer, SLOT( zoom(int) ));@
And this is my main.qml:
@import QtQuick 1.1
Rectangle{
id: mainItem
objectName: "mainItem"
...function zoomIn(steps) { bg.scale *= 2; }
}@
The signal is emitted correctly by my thread and also the slot gets called. Nevertheless, the function in qml is never executed
I'm no real c++ crack so maybe someone can figure out where I run into problems.
Thanks a lot!
-
Try naming them differently, it will help the debugging process so you can examine them individually and have better clarity as to what you are looking at and what is causing the problem
-
It seems to me that your solution is
@
QMetaObject::invokeMethod(
(QObject *)viewer->rootObject(), // for this object we will call method
"test" // name of the method to call
// without parameters
);
@
@
PageStackWindow {
id: mainApp
...
function test() {
myModel.test()
}ListModel { id: myModel ... function test() { console.log("TEST OK"); } } Page { ... }
}
@However, I am interested in more elegant solution.
-
OK, the reason for the problem is, that findChild() does not check "id", it looks for "objectName" property. Thanks to http://www.lothlorien.com/kf6gpe/?p=309 . Moreover, invokeMethod() should be called after setMainQmlFile() and must not be trigered from QML (i.e. qml calls C++ function which calls javascript function) before it finishes the initialization (not even from Component.onCompleted)
@
QMetaObject::invokeMethod(
viewer->rootObject()->findChild<QObject *>("myModel"), // QML item
"test" // method
// parameters
);
@
@
PageStackWindow {
id: mainApp
...ListModel { id: myModel objectName: myModel ... function test() { console.log("TEST OK"); } } Page { ... }
}
@