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.
-
wrote on 9 Jun 2025, 09:35 last edited by
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?wrote on 9 Jun 2025, 12:43 last edited by@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.
wrote on 10 Jun 2025, 01:34 last edited by LJN_leaper 6 Oct 2025, 01:36@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?wrote on 10 Jun 2025, 01:49 last edited by@JonB No, I'm not using precompiled headers.
-
wrote on 10 Jun 2025, 07:22 last edited by ChrisW67 6 Oct 2025, 07:23
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
wrote on 11 Jun 2025, 06:06 last edited by LJN_leaper 6 Nov 2025, 06:06@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
-
wrote on 11 Jun 2025, 22:09 last edited by ChrisW67 6 Nov 2025, 22:09
My Qt 5.15.2 and 5.15.13 instances perform the same way as the Qt 6 version above. Still could be a 5.15 vs. 5.9 difference.
Could it be that Qt VS Tools is not passing the include path to moc?
-
wrote on 13 Jun 2025, 09:32 last edited by
My project path contains non-ASCII characters, which might cause this macro not to work.
-
1/10