0

I am attempting something (perhaps stupid).

Have used some macroes to create "amounts" of functions in C++ domain;

#define THR_CONFIG_VALUE(path, value, type, name, defaultvalue) \
    type name() { return m_##name; } \
    void set##name(type data) { m_##name = data; }
#include <backend/config.i>
#undef THR_CONFIG_VALUE

Based upon following config.i file:

THR_CONFIG_VALUE("", "type", int, ThisType, 0)
THR_CONFIG_VALUE("", "auto", bool, AutoVar1, false)
THR_CONFIG_VALUE("", "auto", bool, AutoVar2, false)

That works fine, i get a number of getter setter functions, also generate member variables the same way (for the record).

Now I start mixing up with QT stuff, trying to use the MOC to generate the Q_PROPERTIES:

#define THR_CONFIG_VALUE(path, value, type, name, defaultvalue) \
    Q_PROPERTY(type name READ name WRITE set##name NOTIFY indexChanged)
#include <backend/vessel/thruster/thruster_config.i>
#undef THR_CONFIG_VALUE

The MOC do not care for such attempts. This would have saved me typing 170 Q_PROPERTY lines and in the future several 100's more.

Question 1: Why, preprocessor and MOC sequence? Question 2: Is there a "QT way" ?

Thanks,

Tore H
  • 39
  • 6

3 Answers3

0

Qt has its own way to generate getters and setters base on the name of the variable as you did.

Look at property system

PBareil
  • 157
  • 6
0

I've implemented a macro for Qt that does what you want, but it must be used within the context of a QObject or Q_GADGET. (Q_PROPERTY can not be used outside of them.)

When I first wrote the macro, I didn't understand that Q_PROPERTY does not generate the setter, getter, notification method, or even the storage for the value. Those need to be generated separately (which is easy in a macro).

The NOTIFY part of Q_PROPERTY requires a signal be defined. Since signals are coded into C++ by MOC before the preprocessor is called, using a #define will not work. (I don't use NOTIFY in my code.)

Incomplete example:

#define THR_CONFIG_VALUE(type, name) \
    Q_PROPERTY(type name READ name WRITE set##name) \
    type m_##name; \
    void set##name(const type &a_value) { m_##name = a_value; } \
    ...
jwernerny
  • 6,978
  • 2
  • 31
  • 32
  • I believe your answer confirms my suspicions, MOC before preprocessor. So as long as i wish to use the preprocessor to generate multiple Q_PROPERTY() 's , I'm outa luck... The member variable part is ok and also the setter function gets generated by preprocessor. But running the Q_PROPERTY macro does not generate the desired MOC file... – Tore H Mar 08 '18 at 09:50
  • @ToreH The only restriction is on the NOTIFY element, which must be a signal. Everything else should still work. (Like I said, I use it very heavily in my projects, and have extended to function templates for things like comparing all the properties.) – jwernerny Mar 09 '18 at 14:42
  • I'll perhaps give it another go. I had one notify for all signals due to the macro not being expanded before MOC. Perhaps I was still wrong to have the notify in the Q_PROPERTY – Tore H Mar 09 '18 at 17:24
  • Sorry to say, the Q_PROPERTY macro does not work from within an X-MACRO even without NOTIFY – Tore H Mar 10 '18 at 16:44
0

Now i Have an implementation that works. Used Verdigris's contribution.

A little bit tricky, had to enable c++14 and also add this define to the PRO file:

DEFINES += __cpp_constexpr=201304 __cpp_variable_templates=201304

Also as i used namespaces; had to do the includes inside the namespace:

FRONTEND_BEGIN_NAMESPACE

#include <frontend/gui/helper/wobjectdefs.h>

Then it works:

#define THR_CONFIG_VALUE(path, value, type, name, defaultvalue) \
    W_PROPERTY(type, name MEMBER m_##name) 
#include <backend/config.i>
#undef THR_CONFIG_VALUE
Tore H
  • 39
  • 6
  • Now, it did work, In QT Creator it compiled (after some heavy pre-processing work it seems based on my laptops fans). In VS2017 (using msvc2017 in both) it did not, complaining about running out of heap..... To be continued... Have not tested on a gcc compiler yet. – Tore H Mar 09 '18 at 17:23
  • Using verdigris, it does work as explained in the previous comment. QT Creator completely blocks my laptop during compile that takes forever. Using MSVC2017 compiler. Now, same compiler, from Visual studio runs out of heap as explained. The config.i file has the type and names i wish to create properties for. The limit after trial and error is found to be 58 entries (going down from original 160ish). Perhaps QT Creator uses pagefile and VS not... not sure yet. But as far as I can figure out until now it has to do with the, to me, new constexpr used by verdigris implementation (C++14 feature), – Tore H Mar 10 '18 at 21:34
  • Solution for use of X-Macro and QT underway with Olivers Verdigris implementation, for details, follow: https://github.com/woboq/verdigris/issues/28 – Tore H Mar 15 '18 at 09:01