QMetaObject::invokeMethod call QML method from C++, with more than 10 arguments
-
I'm wondering how can I call
QMetaObject::invokeMethodwith many arguments.I know I can do like this for multiple arguments:
QMetaObject::invokeMethod( myobject, "methodname", Q_ARG(QVariant, 123), Q_ARG(QVariant, 123), Q_ARG(QVariant, 123), Q_ARG(QVariant, 123), Q_ARG(QVariant, 123), Q_ARG(QVariant, 123) ... );My problem is that the function I'm trying to call has many (11) fields, and the signature for
QMetaObject::invokeMethodis:bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, QGenericArgument val0 = QGenericArgument(nullptr), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), QGenericArgument val4 = QGenericArgument(), QGenericArgument val5 = QGenericArgument(), QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(), QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument())Therefore only up to 10 arguments are possible. Is there a way to circumvent this without splitting the method into 2?
-
I'm wondering how can I call
QMetaObject::invokeMethodwith many arguments.I know I can do like this for multiple arguments:
QMetaObject::invokeMethod( myobject, "methodname", Q_ARG(QVariant, 123), Q_ARG(QVariant, 123), Q_ARG(QVariant, 123), Q_ARG(QVariant, 123), Q_ARG(QVariant, 123), Q_ARG(QVariant, 123) ... );My problem is that the function I'm trying to call has many (11) fields, and the signature for
QMetaObject::invokeMethodis:bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, QGenericArgument val0 = QGenericArgument(nullptr), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), QGenericArgument val4 = QGenericArgument(), QGenericArgument val5 = QGenericArgument(), QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(), QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument())Therefore only up to 10 arguments are possible. Is there a way to circumvent this without splitting the method into 2?
@Developer123 said in QMetaObject::invokeMethod call QML method from C++, with more than 10 arguments:
without splitting the method into 2?
Why would you need to "split" the method? You can simply put at least some of the parameters into a struct and pass this struct as parameter. It is anyway bad design to have so many parameters in a function/method.
-
@Developer123 said in QMetaObject::invokeMethod call QML method from C++, with more than 10 arguments:
without splitting the method into 2?
Why would you need to "split" the method? You can simply put at least some of the parameters into a struct and pass this struct as parameter. It is anyway bad design to have so many parameters in a function/method.
@jsulm Ok that's a good idea, do you know how can I do that? I tried passing a custom struct, such as:
MyStruct { int val1; int val2; }; MyStruct params; auto result = QMetaObject::invokeMethod( object, "mymethod", Q_ARG(QVariant, params)But I get:
no instance of constructor "QArgument<T>::QArgument [with T=QVariant]" matches the argument list.I'm using
QVariantin theQ_ARG()call because I want to access this variable in the QML side as a javascript object, not sure if it would be possible usingQ_ARG(MyStruct , params), even though that does compile... -
@jsulm Ok that's a good idea, do you know how can I do that? I tried passing a custom struct, such as:
MyStruct { int val1; int val2; }; MyStruct params; auto result = QMetaObject::invokeMethod( object, "mymethod", Q_ARG(QVariant, params)But I get:
no instance of constructor "QArgument<T>::QArgument [with T=QVariant]" matches the argument list.I'm using
QVariantin theQ_ARG()call because I want to access this variable in the QML side as a javascript object, not sure if it would be possible usingQ_ARG(MyStruct , params), even though that does compile...@Developer123 said in QMetaObject::invokeMethod call QML method from C++, with more than 10 arguments:
not sure if it would be possible using
Did you try?
You probably will need to register MyStruct, see https://doc.qt.io/qt-6/custom-types.html -
@Developer123 said in QMetaObject::invokeMethod call QML method from C++, with more than 10 arguments:
not sure if it would be possible using
Did you try?
You probably will need to register MyStruct, see https://doc.qt.io/qt-6/custom-types.html@jsulm Yep, tried and got error:
QMetaObject::invokeMethod: No such method SomeQObject_QMLTYPE_15::myMethod(MyStruct) Candidates are: myMethod(QVariant,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant)Also, I tried
Q_DECLARE_METATYPE(MyStruct);on the header file containing the struct definition ofMyStruct, same error... I guess I need to declare the class with the constructor, destructor, etc, instead of a struct, but I'm pretty sure that won't work out of the box.
Edit: I managed to send the QVariant doing:
MyStruct mystruct; QVariant params; params.setValue(mystruct); QMetaObject::invokeMethod( qobject, "myMethod", Q_ARG(QVariant, params) );Now I'm stuck trying to access the values of
MyStructon QML. When I printparamson QML, I get:qml: QVariant(MyStruct, ) -
@jsulm Yep, tried and got error:
QMetaObject::invokeMethod: No such method SomeQObject_QMLTYPE_15::myMethod(MyStruct) Candidates are: myMethod(QVariant,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant)Also, I tried
Q_DECLARE_METATYPE(MyStruct);on the header file containing the struct definition ofMyStruct, same error... I guess I need to declare the class with the constructor, destructor, etc, instead of a struct, but I'm pretty sure that won't work out of the box.
Edit: I managed to send the QVariant doing:
MyStruct mystruct; QVariant params; params.setValue(mystruct); QMetaObject::invokeMethod( qobject, "myMethod", Q_ARG(QVariant, params) );Now I'm stuck trying to access the values of
MyStructon QML. When I printparamson QML, I get:qml: QVariant(MyStruct, )@Developer123 add the
Q_GADGETmacro to your struct, make those public access function Q_INVOKABLE or, (probably better) define Q_PROPERTY(ies)Q_PROPERTY(int val1 MEMBER m_val1 CONSTANT FINAL)IIRC this will require a
qRegisterMetaTypeof your struct -
@Developer123 add the
Q_GADGETmacro to your struct, make those public access function Q_INVOKABLE or, (probably better) define Q_PROPERTY(ies)Q_PROPERTY(int val1 MEMBER m_val1 CONSTANT FINAL)IIRC this will require a
qRegisterMetaTypeof your struct@J-Hilk Hello, I followed the steps exactly as defined here (they seem to correspond to your answer exactly).
I got some link errors. Then I cleaned the build and then it compiled and worked successfully. Thanks.
But I want to point out it was a lot of work to get this to work, I wish QT was simpler...
-
@J-Hilk Hello, I followed the steps exactly as defined here (they seem to correspond to your answer exactly).
I got some link errors. Then I cleaned the build and then it compiled and worked successfully. Thanks.
But I want to point out it was a lot of work to get this to work, I wish QT was simpler...
@Developer123 said in QMetaObject::invokeMethod call QML method from C++, with more than 10 arguments:
I wish QT was simpler...
Well, language interoperability (and C++ and QML are two different languages) is usually complicated at first. Once you have figured out how to interoperate it'll get a lot easier.