Q_INVOKABLE method returning custom C++ type
This is possible but you need to define your custom type as an interface.
First of all in your main() function:
qmlRegisterInterface<MyType>("MyType");
Now you can proceed to create an object and return a pointer
in a Q_INVOKABLE
:
MyType* example = new MyType(parent);
return example;
Note: it might be beneficial to pass the parent to your custom QObject to ensure that this object is deleted together with his parent (to avoid memory leaks).
Note that the target of this answer are people with a similar problem, rather than the original asker.
The described method should work, at least in recent versions of Qt (I'm using Qt 5.12, but it should work in older versions too). Maybe it was a bug in one of the first QML releases.
Checklist: Verify you have done the following:
- Registered your type
qmlRegisterType<MyType>("Mine", 1, 0, "MyType");
(or use qmlRegisterUncreatableType) - Imported your custom types in qml:
import Mine 1.0
- Derived your class from QObject.
- Added
Q_OBJECT
to your class definition.
When returning pointers from a Q_INVOKABLE
method, please take object ownership into account.
Yes, QVariant
is the way to go for your custom class in that construction. Make sure you register your class.
That being said, you may wish to consider using Q_PROPERTY instead, for your custom type and then you can access that even without a function call. If you need custom parameters to the method and you cannot rearrange the code, this is obviously not an option.
I think Dimitri's answer only applies when your type is copyable (so it wouldn't work for QObject). My understanding is that when you have a type that is being manipulated by Qt, for example if it is being returned by an invokable, the type has to be registered as a metatype:
- Non-copyable types like any QObject derived model cannot be metatypes
- A pointer type is a different type, therefore it needs to register separately from the classes it points to
- For pointer type
Foo*
you can register it with metatype system:qRegisterMetaType<Foo*>("Foo*");