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. How to use a macro function as a Qt slot
QtWS25 Last Chance

How to use a macro function as a Qt slot

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 5 Posters 2.1k Views
  • 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.
  • S Offline
    S Offline
    Sivan
    wrote on 19 Jul 2018, 01:51 last edited by Sivan
    #1

    Hi all,

    I am trying to define some slots which will be expanded from a macro. I can achieve this if the macro definition is within the same file as the macro usage. However, if the macro definition and the usage is in different file, I am getting parsing error from the moc tool - Parse error at ")".

    Qt version used: 5.4.1

    I have provided some example below. Thanks in advance for the help.

    Working Example:

    foo.h

    public slots:
    #define SOME_FUNC(func, var) \
        void func##var()         \
        {                        \
            TestFunc(); // Assume this function is defined in this class         \
        }                        \
    
       SOME_FUNC(DoFunc, 1);
       SOME_FUNC(DoFunc, 2);
    

    Non-working example
    fooDef.h

    #define SOME_FUNC(func, var) \
        void func##var()         \
        {                        \
            TestFunc();// Assume this function is defined in the user class    \
        }                        \
    

    foo.h

    #include "fooDef.h"
    
    Class MyClass : public QObject
    {
        Q_OBJECT
    
    // Other definitions
    
    public slots:
       SOME_FUNC(DoFunc, 1);
       SOME_FUNC(DoFunc, 2);
    
    K 1 Reply Last reply 19 Jul 2018, 06:58
    0
    • S Sivan
      19 Jul 2018, 01:51

      Hi all,

      I am trying to define some slots which will be expanded from a macro. I can achieve this if the macro definition is within the same file as the macro usage. However, if the macro definition and the usage is in different file, I am getting parsing error from the moc tool - Parse error at ")".

      Qt version used: 5.4.1

      I have provided some example below. Thanks in advance for the help.

      Working Example:

      foo.h

      public slots:
      #define SOME_FUNC(func, var) \
          void func##var()         \
          {                        \
              TestFunc(); // Assume this function is defined in this class         \
          }                        \
      
         SOME_FUNC(DoFunc, 1);
         SOME_FUNC(DoFunc, 2);
      

      Non-working example
      fooDef.h

      #define SOME_FUNC(func, var) \
          void func##var()         \
          {                        \
              TestFunc();// Assume this function is defined in the user class    \
          }                        \
      

      foo.h

      #include "fooDef.h"
      
      Class MyClass : public QObject
      {
          Q_OBJECT
      
      // Other definitions
      
      public slots:
         SOME_FUNC(DoFunc, 1);
         SOME_FUNC(DoFunc, 2);
      
      K Offline
      K Offline
      koahnig
      wrote on 19 Jul 2018, 06:58 last edited by
      #2

      @Sivan

      This is certainly an advanced topic. Gut feeling tells me that there are at least a number of obstacles and most likely it is not possible.

      One reason is that the older style of connect statements are using already macros to do the connect. Therefore you would need a multi-level macro support.

      Possibly with the functor-based connect you can have a similar feature as you try to do with macros.

      Probably best is to describe a bit more what you try to achieve with your macros. I personally would favor any other solution, but macros.

      Vote the answer(s) that helped you to solve your issue(s)

      1 Reply Last reply
      3
      • S Online
        S Online
        sierdzio
        Moderators
        wrote on 19 Jul 2018, 07:03 last edited by
        #3

        I is quite likely that MOC parser just isn't clever enough to pick up a macro defined elsewhere.

        (Z(:^

        1 Reply Last reply
        2
        • S Offline
          S Offline
          Sivan
          wrote on 19 Jul 2018, 07:19 last edited by Sivan
          #4

          Thanks @koahnig & @sierdzio. I was afraid it is not possible too. But just wanted to try my luck if there is anyway in achieving it.

          @koahnig, the reason for me to do that is abit complex to be explained here as I am trying to make thing works in an existing framework.
          My requirement was that I may have a list of Q_SLOT functions with the following signature format myFuncXXX(), where XXX will vary.

          Eventually, all this functions will call one private function by passing in the appropriate enum or something. I can't directly do it due to the existing framework which will try to find the list of moc generated functions with the above mentioned signature. And the reason to put the macro in one file is to allow many other classes/files to reuse those macros rather than copying it definition in each file.

          But anyways, looks like I am constrained by the current design. Thanks for answering :-)

          1 Reply Last reply
          0
          • V Offline
            V Offline
            VRonin
            wrote on 19 Jul 2018, 07:37 last edited by
            #5

            @Sivan said in How to use a macro function as a Qt slot:

            But anyways, looks like I am constrained by the current design

            I think it's totally possible, just don't declare them as slots, declare them as public methods (so moc doesn't have to meddle with them) and use Qt5 Connection Sintax

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            S 1 Reply Last reply 19 Jul 2018, 07:59
            0
            • V VRonin
              19 Jul 2018, 07:37

              @Sivan said in How to use a macro function as a Qt slot:

              But anyways, looks like I am constrained by the current design

              I think it's totally possible, just don't declare them as slots, declare them as public methods (so moc doesn't have to meddle with them) and use Qt5 Connection Sintax

              S Offline
              S Offline
              Sivan
              wrote on 19 Jul 2018, 07:59 last edited by
              #6

              @VRonin, sorry if I missed this. I believe that will still not work for my case.

              Because the framework loop through the QObject::metaObject->method of QObject to find these functions that I have defined. So if I do not define it under the Slots section, then I don't think so it will come under QObject::metaObject->method

              1 Reply Last reply
              0
              • S Online
                S Online
                sierdzio
                Moderators
                wrote on 19 Jul 2018, 08:02 last edited by sierdzio
                #7

                You can define them with Q_INVOKABLE, then.

                Hm, unless that will trigger the same MOC error...

                (Z(:^

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  Sivan
                  wrote on 19 Jul 2018, 09:47 last edited by
                  #8

                  @sierdzio, that kinda gave me hope. But it is still not working :-(

                  I moved the MACRO usage to public instead of public slots, and added Q_INVOKABLE in front of the function as like this

                  Q_INVOKABLE void func##var()
                  

                  No luck - None of those MACRO functions were registered under Meta Object. I verified by looping through MetaObject->method() to find those functions.

                  However, the moc does not give any error. It just silently ignore. I guess that's because it ignores unsuccessful MACRO parsing that is not under the signal and slot sections

                  JKSHJ 1 Reply Last reply 20 Jul 2018, 05:00
                  2
                  • S Sivan
                    19 Jul 2018, 09:47

                    @sierdzio, that kinda gave me hope. But it is still not working :-(

                    I moved the MACRO usage to public instead of public slots, and added Q_INVOKABLE in front of the function as like this

                    Q_INVOKABLE void func##var()
                    

                    No luck - None of those MACRO functions were registered under Meta Object. I verified by looping through MetaObject->method() to find those functions.

                    However, the moc does not give any error. It just silently ignore. I guess that's because it ignores unsuccessful MACRO parsing that is not under the signal and slot sections

                    JKSHJ Offline
                    JKSHJ Offline
                    JKSH
                    Moderators
                    wrote on 20 Jul 2018, 05:00 last edited by
                    #9

                    @Sivan as you've discovered, moc doesn't work very well with custom macros. This is because moc uses simple string parsing, so when it sees Q_INVOKABLE void func##var() it thinks the function is literally called func##var().

                    For now, all slots must be explicitly written. This could change in the future if/when moc-ng (https://woboq.com/blog/moc-with-clang.html ) is integrated with Qt, but that's still a while away.

                    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                    1 Reply Last reply
                    5
                    • V Offline
                      V Offline
                      VRonin
                      wrote on 20 Jul 2018, 07:23 last edited by VRonin
                      #10

                      This is probably a long shot but if you really want this you could try a moc-less solution: https://woboq.com/blog/verdigris-qt-without-moc.html

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      1 Reply Last reply
                      2
                      • S Offline
                        S Offline
                        Sivan
                        wrote on 24 Jul 2018, 09:48 last edited by
                        #11

                        Thanks @JKSH and @VRonin for the input. As of now, I have settled down by explicitly writing the macros.

                        1 Reply Last reply
                        0

                        1/11

                        19 Jul 2018, 01:51

                        • Login

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