I have a macro which is used to define qt property in one line. But it only works when it is used in header where it is defined.
-
I have a macro which is used to define qt property in one line. But it only works when it is used in the header where it is defined.
For example there is A.h file:#define LpProperty(type, name, getterAccessModifier, setterAccessModifier) \ Q_PROPERTY(type name READ get##name WRITE set##name) \ getterAccessModifier: \ type get##name() { \ return _##name; \ } \ setterAccessModifier: \ void set##name(type value) { \ _##name = value; \ } \ private: \ type _##name{};
and B.h file:
#include "A.h" struct Foo : public QObject { Q_OBJECT LpProperty(QString, Bar, public, public) };
LpProperty
is defined in different header than where it is used, the Q_PROPERTY line does not work andFoo::staticMetaObject.propertyCount()
returns 1 instead of 2(QObject::objectname + Foo::bar). Can you tell me why and how to solve it? -
I have a macro which is used to define qt property in one line. But it only works when it is used in the header where it is defined.
For example there is A.h file:#define LpProperty(type, name, getterAccessModifier, setterAccessModifier) \ Q_PROPERTY(type name READ get##name WRITE set##name) \ getterAccessModifier: \ type get##name() { \ return _##name; \ } \ setterAccessModifier: \ void set##name(type value) { \ _##name = value; \ } \ private: \ type _##name{};
and B.h file:
#include "A.h" struct Foo : public QObject { Q_OBJECT LpProperty(QString, Bar, public, public) };
LpProperty
is defined in different header than where it is used, the Q_PROPERTY line does not work andFoo::staticMetaObject.propertyCount()
returns 1 instead of 2(QObject::objectname + Foo::bar). Can you tell me why and how to solve it?@LJN_leaper
Does the moc stage needs to seeQ_PROPERTY
actually in the class/struct definition?
Or, if you say it works only in certain places, are you using precompiled headers? I believe I have heard this can make some header things work in one place but not another? -
Hi,
Not that I want you to stop your research into making it work but your macro seems to reimplement what the MEMBER qualifier does already.
See the Qt Properties documentation.
-
Hi,
Not that I want you to stop your research into making it work but your macro seems to reimplement what the MEMBER qualifier does already.
See the Qt Properties documentation.
@SGaist Hi,
I read the documentation and changed my macro to this:#define LpProperty2(type, name) \ Q_PROPERTY(type name MEMBER _##name) \ type _##name{};
I still want to make it work because I think it is still tedious to use the MEMBER qualifier if I have many properties to define.
-
@LJN_leaper
Does the moc stage needs to seeQ_PROPERTY
actually in the class/struct definition?
Or, if you say it works only in certain places, are you using precompiled headers? I believe I have heard this can make some header things work in one place but not another?@JonB No, I'm not using precompiled headers.
-
Works fine here.
a.h
must be in the same directory asb.h
or on the include path passed tomoc
.moc
does not warn if the include is not found, and this is the most likely cause of your difficulty.a.h
is:#ifndef A_H #define A_H #define LpProperty(type, name) \ Q_PROPERTY(type name MEMBER _##name) \ type _##name{}; #endif
b.h
is:#ifndef B_H #include <QObject> #include "a.h" struct Foo : public QObject { Q_OBJECT LpProperty(QString, Bar) }; #endif
$ ls a.h b.h # Count references to your member property in moc output $ ~/Qt/6.8.1/gcc_64/libexec/moc b.h > moc.h $ grep -c Bar moc.h 5 # Move a.h $ mkdir include $ mv a.h include # Repeat test # Bar disappears # Note: no complaints about missing header $ ~/Qt/6.8.1/gcc_64/libexec/moc b.h > moc.h $ grep -c Bar moc.h 0 # Repeat test with include path # Bar returns $ ~/Qt/6.8.1/gcc_64/libexec/moc -I include b.h > moc.h $ grep -c Bar moc.h 5
qmake
arranges for INCLUDEPATH to be passed tomoc
-
Works fine here.
a.h
must be in the same directory asb.h
or on the include path passed tomoc
.moc
does not warn if the include is not found, and this is the most likely cause of your difficulty.a.h
is:#ifndef A_H #define A_H #define LpProperty(type, name) \ Q_PROPERTY(type name MEMBER _##name) \ type _##name{}; #endif
b.h
is:#ifndef B_H #include <QObject> #include "a.h" struct Foo : public QObject { Q_OBJECT LpProperty(QString, Bar) }; #endif
$ ls a.h b.h # Count references to your member property in moc output $ ~/Qt/6.8.1/gcc_64/libexec/moc b.h > moc.h $ grep -c Bar moc.h 5 # Move a.h $ mkdir include $ mv a.h include # Repeat test # Bar disappears # Note: no complaints about missing header $ ~/Qt/6.8.1/gcc_64/libexec/moc b.h > moc.h $ grep -c Bar moc.h 0 # Repeat test with include path # Bar returns $ ~/Qt/6.8.1/gcc_64/libexec/moc -I include b.h > moc.h $ grep -c Bar moc.h 5
qmake
arranges for INCLUDEPATH to be passed tomoc
@ChrisW67 In my case, a.h and b.h are under same folder, but it still not working. I use qt vs tools and Visual Studio 2022, Qt version is 5.9.4.
-
moc is not good with macros, esp. not such an ancient version so I would not be surprised if this is simply not supported in 5.9.4
-
My project path contains non-ASCII characters, which might cause this macro not to work.
-