PDA

View Full Version : Need help passing data to qml



brasscs
19th April 2015, 22:24
Hi i am having difficulty in passing a struct from cpp to qml. Can someone give me some pointers. I am using qt 5.4/64 bit under debian lenny rc1. Here is what i have been working with which was just a new dialog project with the following added. Note the code seems to work if i pass it just a string but not with a simple struct.

my .h


namespace Ui {
class Dialog;
struct MyStruct {
int i;
QString name;
};
}

Q_DECLARE_METATYPE(Ui::MyStruct)
#endif // DIALOG_H


.cpp file


Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
test();
}

void Dialog::test() {
using namespace Ui;
MyStruct test;

test.i=12;
test.name="Hello world";

QVariant v = QVariant::fromValue(test);
QQmlEngine engine;
QQmlComponent component(&engine, "/home/user/projects-qt5/test_qml/MyItem.qml");
QObject *object = component.create();

QVariant returnedValue;
QVariant msg = "Hello from C++";
QMetaObject::invokeMethod(object, "myQmlFunction",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant,v));

qDebug() << "QML function returned:" << returnedValue.toString();
qDebug() << "comp error is " << component.errors();
delete object;

}

.qml


import QtQuick 2.0

// MyItem.qml

Item {
function myQmlFunction(v) {
console.log("Got message:",v.name)
return "some return value"
}
}

wysota
20th April 2015, 07:13
It doesn't work like that. Wrapping a structure into a variant will not teach Qt to understand its structure and thus be able to access its members. For that you should derive your class from QObject and make members into properties or you should use QVariantMap and manually copy each field value to the map.

anda_skoa
20th April 2015, 10:06
Note the code seems to work if i pass it just a string but not with a simple struct.
You can pass any type that is wrapable in a QVariant.

If you mean that you can't access the data inside the variant, then see wysota's comment.

Cheers,
_

brasscs
21st April 2015, 14:16
ok so how about an example of passing a struct. gave up finding something online

wysota
21st April 2015, 14:39
ok so how about an example of passing a struct. gave up finding something online


MyStruct s;
QVariantMap map;
map["i"] = s.i;
map["name"] = s.name;
QVariant v = map;
QMetaObject::invokeMethod(object, "myQmlFunction",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant,v));

brasscs
22nd April 2015, 15:10
hey thanks for the code but it still does not work. this is what i am using

.cpp


using namespace Ui;
QQmlEngine engine;
QQmlComponent component(&engine, "/home/user/projects-qt5/test_qml/MyItem.qml");
QObject *object = component.create();
QVariant returnedValue;

MyStruct s;
s.i=12;
s.name="Hello QML";
QVariantMap map;
map["i"] = s.i;
map["name"] = s.name;

QVariant v = map;
QMetaObject::invokeMethod(object, "myQmlFunction",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant,v));

.h


namespace Ui {
class Dialog;
struct MyStruct {
int i;
QString name;
};
}
...
Q_DECLARE_METATYPE(Ui::MyStruct)
#endif // DIALOG_H

.qml


import QtQuick 2.0

// MyItem.qml

Item {

function myQmlFunction(v) {
console.log("Got message:",v.name)
return "some return value"
}
}

app output
qml: QML Got message: undefined
QML function returned: "some return value"
comp error is ()

wysota
22nd April 2015, 15:28
It works just fine for me.


#include <QtGui>
#include <QtQml>

int main(int argc, char **argv) {
QGuiApplication app(argc, argv);
QQmlEngine e;
QQmlComponent c(&e, "test.qml");
QObject *o = c.create();
QVariantMap m;
m["i"] = 10;
m["name"] = "someName";
QVariant v = m;
QVariant ret;
QMetaObject::invokeMethod(o, "testFunc", Q_RETURN_ARG(QVariant, ret), Q_ARG(QVariant, v));
// return app.exec();
return 0;
}

import QtQml 2.0

QtObject {
function testFunc(v) { console.log("v.name = ", v.name); }
}

brasscs
22nd April 2015, 17:10
hey wysota

i finally found my error. the code you supplied is now working fine.

thanks for your help.