Best way to access a cpp structure in QML
-
One more thing, you did this...
struct MyStruct { Q_GADGET int m_val; QString m_name1; QString m_name2; QString m_name3; QString m_name4; Q_PROPERTY(int val MEMBER m_val) Q_PROPERTY(QString name1 MEMBER m_name1) Q_PROPERTY(QString name2 MEMBER m_name2) Q_PROPERTY(QString name3 MEMBER m_name3) Q_PROPERTY(QString name4 MEMBER m_name4) };
... where you put
Q_GADGET
in the public section. This has the side effect that all the members that come afterQ_GADGET
are private now. That's becauseQ_GADGET
is a macro that expands to...#define Q_GADGET \ public: \ static const QMetaObject staticMetaObject; \ void qt_check_for_QGADGET_macro(); \ typedef void QtGadgetHelper; \ private: \ QT_WARNING_PUSH \ Q_OBJECT_NO_ATTRIBUTES_WARNING \ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \ QT_WARNING_POP \ QT_ANNOTATE_CLASS(qt_qgadget, "") \ /*end*/
... , see qobjectdefs.h.
So maybe better follow the usual convention to avoid surprises:
class MyStruct { Q_GADGET Q_PROPERTY(int val MEMBER m_val) Q_PROPERTY(QString name1 MEMBER m_name1) Q_PROPERTY(QString name2 MEMBER m_name2) Q_PROPERTY(QString name3 MEMBER m_name3) Q_PROPERTY(QString name4 MEMBER m_name4) public: int m_val; QString m_name1; QString m_name2; QString m_name3; QString m_name4; };
-
One more thing, you did this...
struct MyStruct { Q_GADGET int m_val; QString m_name1; QString m_name2; QString m_name3; QString m_name4; Q_PROPERTY(int val MEMBER m_val) Q_PROPERTY(QString name1 MEMBER m_name1) Q_PROPERTY(QString name2 MEMBER m_name2) Q_PROPERTY(QString name3 MEMBER m_name3) Q_PROPERTY(QString name4 MEMBER m_name4) };
... where you put
Q_GADGET
in the public section. This has the side effect that all the members that come afterQ_GADGET
are private now. That's becauseQ_GADGET
is a macro that expands to...#define Q_GADGET \ public: \ static const QMetaObject staticMetaObject; \ void qt_check_for_QGADGET_macro(); \ typedef void QtGadgetHelper; \ private: \ QT_WARNING_PUSH \ Q_OBJECT_NO_ATTRIBUTES_WARNING \ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \ QT_WARNING_POP \ QT_ANNOTATE_CLASS(qt_qgadget, "") \ /*end*/
... , see qobjectdefs.h.
So maybe better follow the usual convention to avoid surprises:
class MyStruct { Q_GADGET Q_PROPERTY(int val MEMBER m_val) Q_PROPERTY(QString name1 MEMBER m_name1) Q_PROPERTY(QString name2 MEMBER m_name2) Q_PROPERTY(QString name3 MEMBER m_name3) Q_PROPERTY(QString name4 MEMBER m_name4) public: int m_val; QString m_name1; QString m_name2; QString m_name3; QString m_name4; };
-
One more thing, you did this...
struct MyStruct { Q_GADGET int m_val; QString m_name1; QString m_name2; QString m_name3; QString m_name4; Q_PROPERTY(int val MEMBER m_val) Q_PROPERTY(QString name1 MEMBER m_name1) Q_PROPERTY(QString name2 MEMBER m_name2) Q_PROPERTY(QString name3 MEMBER m_name3) Q_PROPERTY(QString name4 MEMBER m_name4) };
... where you put
Q_GADGET
in the public section. This has the side effect that all the members that come afterQ_GADGET
are private now. That's becauseQ_GADGET
is a macro that expands to...#define Q_GADGET \ public: \ static const QMetaObject staticMetaObject; \ void qt_check_for_QGADGET_macro(); \ typedef void QtGadgetHelper; \ private: \ QT_WARNING_PUSH \ Q_OBJECT_NO_ATTRIBUTES_WARNING \ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \ QT_WARNING_POP \ QT_ANNOTATE_CLASS(qt_qgadget, "") \ /*end*/
... , see qobjectdefs.h.
So maybe better follow the usual convention to avoid surprises:
class MyStruct { Q_GADGET Q_PROPERTY(int val MEMBER m_val) Q_PROPERTY(QString name1 MEMBER m_name1) Q_PROPERTY(QString name2 MEMBER m_name2) Q_PROPERTY(QString name3 MEMBER m_name3) Q_PROPERTY(QString name4 MEMBER m_name4) public: int m_val; QString m_name1; QString m_name2; QString m_name3; QString m_name4; };
@Wieland Is there any possibility that I can access structure inside a structure?
struct MyStruct { Q_GADGET int m_val; QString m_name1; QString m_name2; QString m_name3; QString m_name4; MyNewStruct m_newStr; //** new Struct includes Q_GADGET macro and member definations. Q_PROPERTY(int val MEMBER m_val) Q_PROPERTY(QString name1 MEMBER m_name1) Q_PROPERTY(QString name2 MEMBER m_name2) Q_PROPERTY(QString name3 MEMBER m_name3) Q_PROPERTY(QString name4 MEMBER m_name4) Q_PROPERTY(MyNewStruct newStr MEMBER m_newStr) //**Currently getting error };
-
-
This post is deleted!
-
-
The MOC generates some code for you to implement all the Gadget / Property stuff. Looks like the generated code uses the != operator for MyStruct. So you need to implement that:
public: bool operator==(MyStruct const &other) const; bool operator!=(MyStruct const &other) const;
bool MyStruct::operator==(const MyStruct &other) const { // compare members return true; } bool MyStruct::operator!=(MyStruct const &other) const { return !(*this == other); }
-
The MOC generates some code for you to implement all the Gadget / Property stuff. Looks like the generated code uses the != operator for MyStruct. So you need to implement that:
public: bool operator==(MyStruct const &other) const; bool operator!=(MyStruct const &other) const;
bool MyStruct::operator==(const MyStruct &other) const { // compare members return true; } bool MyStruct::operator!=(MyStruct const &other) const { return !(*this == other); }
-
@pra7 said in Best way to access a cpp structure in QML:
How to know that which all operators should be overloaded?
You can't really know. But when the compiler complains about a missing operator, just implement it. In this case we didn't really need the
==
operator, but I'd say it's common practice to implement the!=
operator using the==
operator. -
@pra7 said in Best way to access a cpp structure in QML:
How to know that which all operators should be overloaded?
You can't really know. But when the compiler complains about a missing operator, just implement it. In this case we didn't really need the
==
operator, but I'd say it's common practice to implement the!=
operator using the==
operator. -
@Wieland Is there any possibility that I can access structure inside a structure?
struct MyStruct { Q_GADGET int m_val; QString m_name1; QString m_name2; QString m_name3; QString m_name4; MyNewStruct m_newStr; //** new Struct includes Q_GADGET macro and member definations. Q_PROPERTY(int val MEMBER m_val) Q_PROPERTY(QString name1 MEMBER m_name1) Q_PROPERTY(QString name2 MEMBER m_name2) Q_PROPERTY(QString name3 MEMBER m_name3) Q_PROPERTY(QString name4 MEMBER m_name4) Q_PROPERTY(MyNewStruct newStr MEMBER m_newStr) //**Currently getting error };
@pra7, @Wieland how can I access a list of Structure inside another Structure.
Eg: From the above example, I need to useQList<MyNewStructure> m_StructList; How is that possible? I have tried, QList<MyNewStructure> m_StructList; Q_PROPERTY(QList<MyNewStruct> newStr MEMBER m_newStr) but didnt help.
-
@Wieland Thanks!!! for your suggestion after lot of reading and searching I got the answer ,Actually we can use structs or any object which is not derived from QObject by using Q_GADGET :
struct MyStruct { Q_GADGET int m_val; QString m_name1; QString m_name2; QString m_name3; QString m_name4; Q_PROPERTY(int val MEMBER m_val) Q_PROPERTY(QString name1 MEMBER m_name1) Q_PROPERTY(QString name2 MEMBER m_name2) Q_PROPERTY(QString name3 MEMBER m_name3) Q_PROPERTY(QString name4 MEMBER m_name4) };
Then in my class i just replaced QVariant as below :
class MyClass:public QObject { Q_OBJECT Q_PROPERTY(MyStruct mystr READ getMyStruct WRITE setMyStruct NOTIFY myStructChanged) public: explicit MyClass(QObject *parent = nullptr); MyStruct strObj; // Edit: changed get function MyStruct getMyStruct() const { return strObj; } // Edit: Added set function void setMyStruct(myStruct val) { mystr = val; emit myStructChanged(); } signals: void myStructChanged(); }
Now in QML file i can just use classObj.mystr.name1 to access the members and i can just use classObj.mystr.name1 = "abc" to set the values.
-
-