Calling QML functions from C++ [SOLVED]
-
wrote on 7 Dec 2014, 10:43 last edited by
The first way gave an error:
ASSERT failure in QList<T>::at: "index out of range"
I try to do it like this:
@QObject * object = engine.rootObjects().value(0)->findChild<QObject*>("algoShow");
QMetaObject::invokeMethod(object, "insertText",
Q_ARG(QVariant, QVariant::fromValue(QString("Hello from c++!"))));@or like this:
@QObject * object = engine.findChild<QObject*>("algoShow");@
and QML:
@function insertText(msg) {
console.log(msg);
}@But nothing happened, i think that function was not invoked..
-
wrote on 7 Dec 2014, 10:58 last edited by
bq. ASSERT failure in QList<T>::at: “index out of range”
Do you have any QML created at the time you try that? If you don't have the first element in root objects, then you probably don't have anything at all, you HAVE TO HAVE root before you can have anything else. You are probably doing it before any QML is loaded.
The reason you don't get the out of range error with value() is because this method returns a default constructed value if nothing is found, so you get a null pointer, which is why invoke method doesn't do anything.
Make sure you have your QML loaded before you try to access it.
@engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); // or whatever your main QML file is@
-
wrote on 7 Dec 2014, 11:19 last edited by
Oh, i loaded main,qml, right like you wrote. But then i also created two qml files directly from qml document, in this way:
in main.cpp I load main.qml:
@Manager manager;
engine.load(QUrl(mainPath));
object = engine.rootObjects().value(0);
engine.rootContext()->setContextProperty("myObj", &manager);@in main.qml I load the second qml file :
@ApplicationWindow {
id: mainWindow
property variant win;button {
...
onClicked: {var component = Qt.createComponent("qrc:/Smejnost.qml"); win = component.createObject(mainWindow); win.show(); }
}}@
Maybe you can suggest a better way, how to load and manage qml files. I'm just a beginner :)
-
wrote on 7 Dec 2014, 11:44 last edited by
Actualy, this way has one big disadvantage.. I dont see any created qml windows, except the main,qml, when launching the project on android..
-
wrote on 7 Dec 2014, 11:44 last edited by
Well, you don't honestly expect that you will be able to find the object in C++ main() before it was created in QML, right?
There is nothing wrong with the way you create the Smejnost component, and regardless of the style of creation, you will always need to have it created before you can locate it with findChild().
You just have to put your call from C++ to QML in the proper "spot", not simply in main, because it will run immediately after the main component is set, before you have the chance to create extra components from QML.
But if you really want to put it in main, you can use a signal, add a signal to the ApplicationWindow, in main() find the main object and connect that signal to a free function or lambda which wraps the findChild() and inkoveMethod() call, and from QML emit the signal when Smejnost has been created. This way you will attempt to find the target component only after it is created.
-
wrote on 7 Dec 2014, 11:56 last edited by
I load qml file, using
@engine.load(QUrl(QStringLiteral("qrc:/Algo_Show.qml")));
object = engine.rootObjects().at(0);@it worked, but function is still not invoked.
Error:
QMetaObject::invokeMethod: No such method QThread::insertText(QVariant)
-
wrote on 7 Dec 2014, 12:20 last edited by
YES ! I just load qml file like in qt tutorial, and it's worked !
@QQmlEngine engine;
QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/Algo_Show.qml")));
QObject *object = component.create();
QVariant msg = "Hello from C++";
QMetaObject::invokeMethod(object, "insertText",
Q_ARG(QVariant, msg));
@Like i said before, i'm just a begginer ) But the problem solved! Thanks.
-
wrote on 7 Dec 2014, 12:39 last edited by
Yes, you could have created the QML object from C++ as well. All this is for the sake of getting a test to work I guess, you will have to figure out how to lay out your actual application so you avoid the "chicken or egg" paradox.
And since you already use Qt, you might as well be using QFile instead of fstream.
-
wrote on 7 Dec 2014, 13:12 last edited by
I got a new paradox, qml file was open, but i cant click at any button or qml object.. Like it's not active.
-
wrote on 7 Dec 2014, 13:51 last edited by
Problem is finaly solved!
12/12