Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. 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.
Forum Updated to NodeBB v4.3 + New Features

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.

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 5 Posters 460 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    LJN_leaper
    wrote last edited by
    #1

    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 and Foo::staticMetaObject.propertyCount() returns 1 instead of 2(QObject::objectname + Foo::bar). Can you tell me why and how to solve it?

    JonBJ 1 Reply Last reply
    0
    • L LJN_leaper

      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 and Foo::staticMetaObject.propertyCount() returns 1 instead of 2(QObject::objectname + Foo::bar). Can you tell me why and how to solve it?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote last edited by
      #2

      @LJN_leaper
      Does the moc stage needs to see Q_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?

      L 1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote last edited by
        #3

        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.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        L 1 Reply Last reply
        1
        • SGaistS SGaist

          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.

          L Offline
          L Offline
          LJN_leaper
          wrote last edited by LJN_leaper
          #4

          @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.

          1 Reply Last reply
          0
          • JonBJ JonB

            @LJN_leaper
            Does the moc stage needs to see Q_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?

            L Offline
            L Offline
            LJN_leaper
            wrote last edited by
            #5

            @JonB No, I'm not using precompiled headers.

            1 Reply Last reply
            0
            • C Offline
              C Offline
              ChrisW67
              wrote last edited by ChrisW67
              #6

              Works fine here. a.h must be in the same directory as b.h or on the include path passed to moc. 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 to moc

              L 1 Reply Last reply
              4
              • C ChrisW67

                Works fine here. a.h must be in the same directory as b.h or on the include path passed to moc. 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 to moc

                L Offline
                L Offline
                LJN_leaper
                wrote last edited by LJN_leaper
                #7

                @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.

                1 Reply Last reply
                0
                • Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote last edited by
                  #8

                  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

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  1 Reply Last reply
                  1
                  • C Offline
                    C Offline
                    ChrisW67
                    wrote last edited by ChrisW67
                    #9

                    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?

                    1 Reply Last reply
                    0
                    • L Offline
                      L Offline
                      LJN_leaper
                      wrote last edited by
                      #10

                      My project path contains non-ASCII characters, which might cause this macro not to work.

                      1 Reply Last reply
                      0
                      • L LJN_leaper has marked this topic as solved

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved