Reputation: 43
Im trying to create and pass a custom class instance to a Q_INVOKABLE function with the respective parameter. I tried to make an example to point out what im trying to do. So basically i have a class Foo and another class Bar with a function that takes Foo as a parameter. I want to call this function in QML but i don't know how to instantiate Foo to pass it as the parameter for that function.
EDIT - More information about the main goal:
The real goal is to have a subclassed QAbstractItemModel that has a list of a custom class objects. That list will then be represented using the models data() function. The model should be represented some how as a view in QML. Also i want to populate the model at runtime. So the model class should have a function that takes a custom class instance and appends it to the internal list. So my approach was to create and pass the custom class instance within qml. I haven't found any example to do that kind of taks. Here is what i've got:
Foo.h
class Foo : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ getName WRITE setName)
public:
Foo(QString fooName, QObject *parent = 0) : QObject(parent){
name = fooName;
}
QString getName() const {
return name;
}
void setName(const QString &value){
name = value;
}
private:
QString name;
};
Bar.h
class Bar : public QObject
{
Q_OBJECT
public:
explicit Bar(QObject *parent = 0) : QObject(parent){}
Q_INVOKABLE void addFoo(const Foo &foo){
fooList.append(foo);
}
private:
QList<Foo> fooList;
};
main.cpp
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterType<Foo>("Test", 1, 0, "Foo");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
engine.rootContext()->setContextProperty("bar", new Bar());
return app.exec();
}
main.qml
import Test 1.0
Window {
Button {
id: addFoo
text: "Add new Foo to Bar"
onClicked: {
bar.addFoo(????)
}
}
}
Upvotes: 4
Views: 4822
Reputation: 5207
You either make Foo
instantiable, by giving it a constructor that can be called without arguments, and then use the approach suggested by CMLDMR or you add a "factory" function that can create instances.
In the latter case you either need to work with Foo*
as the return value of the factory function and the argument of addFoo()
or you change Foo
to be a value class with the Q_GADGET
macro for properties instead of deriving from QObject
Given that you have no signals in Foo
I would recommend the latter.
Roughly like this:
class Foo
{
Q_GADGET
Q_PROPERTY(...)
// ....
};
class Bar : public QObject
{
// ...
Q_INVOKABLE Foo createFoo(const QString &name);
Q_INVOKABLE void addFoo(const Foo &foo);
};
Edit: it also requires
qRegisterMetaType<Foo>();
Upvotes: 1
Reputation: 344
you should create a object by Foo before passing object in QML. Source: Qt5 C++ GUI Programming Cookbook. Lee Zhi Eng, page:37
import Test 1.0
Window {
Foo {
id: Foo_object
}
Button {
id: addFoo
text: "Add new Foo to Bar"
onClicked: {
bar.addFoo(Foo_object)
}
}
}
Upvotes: 1