PDA

View Full Version : call Javascript from C++ method with QQuickItem parameter



gsv-chris
9th January 2015, 15:31
Hello,

we have an application that heavily integrates C++ and QML. Now, the need arises to call a javascript method defined on a QML component with a parameter that is a QQuickItem *. Here is the relevant QML code:

Rectangle {
function show(targetItem) {
_internal_stackView.push({item:targetItem,destroyO nPop:false})
}
}
from C++, I would like to do this:

QMetaObject::invokeMethod(m_qmlItem, "show", Q_RETURN_ARG(QVariant, retval), Q_ARG(QQuickItem *, nextItemToShow));
but alas, there seems to be no way to pass anything but primitve values (those supported by QVariant) as method parameter. The code compiles, but upon execution there is a message in the console that the parameter is inacceptable. I have also not found any other way to pass the "nextItemToShow" (context property doesn't work because context not writeable, QML property has the same restrictions as QML method)

Any suggestions?
thanks,
Chris

anda_skoa
9th January 2015, 16:19
Aside from the bad idea to call a QML method from C++, have you tried QObject* as the type, or putting the item into a QVariant first?

Cheers,
_

gsv-chris
9th January 2015, 17:03
Aside from the bad idea to call a QML method from C++
I wouldn't be so final about this, as it is an officially documented technique. Beyond that, our use case is a generator based on a higher-level DSL - not the typical QML application.


have you tried QObject* as the type, or putting the item into a QVariant first?
the runtime error message states that the JS method expects a QVariant, and putting the item into a QVariant is not possible, as I wrote in my first post

thanks, C.

wysota
9th January 2015, 17:53
I wouldn't be so final about this, as it is an officially documented technique.
And as far as I remember this is officially said to be a bad idea :)


and putting the item into a QVariant is not possible, as I wrote in my first post
Why not? I don't think the problem lies with putting a QObject in a QVariant.

This works just fine:


#include <QtGui>
#include <QQuickView>
#include <QQuickItem>

int main(int argc, char **argv) {
QGuiApplication app(argc, argv);
QQuickView view;
view.setSource(QUrl::fromLocalFile("main.qml"));
view.show();
app.processEvents();
QObject *rootObject = view.rootObject();
QVariant v;
v.setValue<QObject*>(rootObject);
QMetaObject::invokeMethod(rootObject, "abc", Q_ARG(QVariant, v));
return 0;
}

import QtQuick 2.0

Rectangle {
function abc(o) { console.log("I'm here") }
}

gsv-chris
9th January 2015, 20:11
Why not? I don't think the problem lies with putting a QObject in a QVariant.
perfect, thats the answer I was looking for. Thanks alot!

anda_skoa
10th January 2015, 10:39
the runtime error message states that the JS method expects a QVariant, and putting the item into a QVariant is not possible, as I wrote in my first post
No, you did not write anything like that in your first post.
And yes, it is possible.

Cheers,
_