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. [solved] MetaObject not referencing slots in derived class

[solved] MetaObject not referencing slots in derived class

Scheduled Pinned Locked Moved Unsolved General and Desktop
metadataslots
16 Posts 3 Posters 4.8k 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.
  • X Offline
    X Offline
    XavierLL
    wrote on last edited by XavierLL
    #1

    Hello everyone,

    I have created this program:

    base.h

    #ifndef BASE_H
    #define BASE_H
    
    #include <QObject>
    class Base : public QObject
    {
        Q_OBJECT
    
    public:
        Base(QObject *parent = nullptr): QObject(parent) {}
    };
    
    #endif // BASE_H
    

    derived.h

    #ifndef DERIVED_H
    #define DERIVED_H
    
    #include "base.h"
    #include <QDebug>
    
    class Derived : public Base
    {
    public:
        Derived(QObject *parent = nullptr): Base(parent) {}
    
        void printSlots(){
            for(int i = 0; i < metaObject()->methodCount(); i++)
                qDebug() << "Method:" << metaObject()->method(i).name();
        }
    public slots:
        void slot1(){}
    };
    
    #endif // DERIVED_H
    

    main.cpp

    #include <QCoreApplication>
    #include <QDebug>
    
    #include "derived.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        Derived der(0);
        der.printSlots();
    
        return 0;
    }
    

    The problem is that printSlots is not printing the "slot1" defined in derived. It only prints the slotname if I define "slot1" in the base class like this:

    base.h

    #ifndef BASE_H
    #define BASE_H
    
    #include <QObject>
    class Base : public QObject
    {
        Q_OBJECT
    
    public:
        Base(QObject *parent = nullptr): QObject(parent) {}
    public slots:
        virtual void slot1(){}
    };
    
    #endif // BASE_H
    

    Is there anyway for the derived metaobject to see the slots defined in the derived class?

    thanks in advance,

    Xllr

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi
      I wonder if Derived class need

      Q_OBJECT

      too ?

      kshegunovK 1 Reply Last reply
      3
      • mrjjM mrjj

        Hi
        I wonder if Derived class need

        Q_OBJECT

        too ?

        kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by
        #3

        @mrjj

        I wonder if Derived class need

        It does, so why do you wonder? :)

        Read and abide by the Qt Code of Conduct

        mrjjM 1 Reply Last reply
        0
        • kshegunovK kshegunov

          @mrjj

          I wonder if Derived class need

          It does, so why do you wonder? :)

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @kshegunov

          I often just wonder :)
          nah, i never used
          metaObject()->methodCount();

          so was not 100% sure.

          kshegunovK 1 Reply Last reply
          0
          • mrjjM mrjj

            @kshegunov

            I often just wonder :)
            nah, i never used
            metaObject()->methodCount();

            so was not 100% sure.

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by
            #5

            @mrjj
            QObject::metaObject() returns the QMetaObject associated with the class (it's a static member, and the method provides virtualization over the class tree). If you don't have the Q_OBJECT macro, there's no staticMetaObject member for the class, and consequently there's no metaObject() override, thus you get the parent's staticMetaObject (or the last class that had the macro). Like in this case, there can't be reflection for the derived type, because the needed meta information isn't generated (i.e. the missing macro); the best you get is the information for the parent class.

            Although, a need for this kind of introspection is rather rare ...

            Read and abide by the Qt Code of Conduct

            mrjjM 1 Reply Last reply
            2
            • kshegunovK kshegunov

              @mrjj
              QObject::metaObject() returns the QMetaObject associated with the class (it's a static member, and the method provides virtualization over the class tree). If you don't have the Q_OBJECT macro, there's no staticMetaObject member for the class, and consequently there's no metaObject() override, thus you get the parent's staticMetaObject (or the last class that had the macro). Like in this case, there can't be reflection for the derived type, because the needed meta information isn't generated (i.e. the missing macro); the best you get is the information for the parent class.

              Although, a need for this kind of introspection is rather rare ...

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @kshegunov
              ahh, i never really examined the macro.
              So thats how it works.
              Its very cool.
              I wish it was a pure c++ feature :)

              kshegunovK 1 Reply Last reply
              0
              • mrjjM mrjj

                @kshegunov
                ahh, i never really examined the macro.
                So thats how it works.
                Its very cool.
                I wish it was a pure c++ feature :)

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by kshegunov
                #7

                @mrjj
                Actually it is, somewhat. See here. The moc is needed to generate the meta information about the class, and the methods implementations, but for the static members or virtual functions declarations we have the good ol' preprocessor. ;)

                Read and abide by the Qt Code of Conduct

                mrjjM 1 Reply Last reply
                0
                • X Offline
                  X Offline
                  XavierLL
                  wrote on last edited by
                  #8

                  Resolved!

                  I tried with the Q_OBJECT before but didn't rerun qmake... my fault :) and the errors I was obtaining made me think that maybe I could only use Q_OBJECT in classes directly derived from QObject, didn't think deeply about it.

                  I am just experimenting with all the metadata classes for a property based system UI.

                  Thanks a lot!

                  Xllr

                  1 Reply Last reply
                  1
                  • kshegunovK kshegunov

                    @mrjj
                    Actually it is, somewhat. See here. The moc is needed to generate the meta information about the class, and the methods implementations, but for the static members or virtual functions declarations we have the good ol' preprocessor. ;)

                    mrjjM Offline
                    mrjjM Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @kshegunov
                    oh. pretty neat.
                    I just wish it could list
                    members variables + type too :)

                    I never used the Qt metasystem. (directly)
                    Can moc be used to extract (plain) variables or does it has to be properties?

                    kshegunovK 1 Reply Last reply
                    0
                    • X Offline
                      X Offline
                      XavierLL
                      wrote on last edited by
                      #10

                      Not sure, because I have been working with this for 2 days, but I think they must be properties.

                      1 Reply Last reply
                      0
                      • mrjjM mrjj

                        @kshegunov
                        oh. pretty neat.
                        I just wish it could list
                        members variables + type too :)

                        I never used the Qt metasystem. (directly)
                        Can moc be used to extract (plain) variables or does it has to be properties?

                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by
                        #11

                        @mrjj said:

                        I just wish it could list
                        members variables + type too

                        Well, this wouldn't be very helpful, as you already know what member variables you have (and some of them may be private), or as in the usual case you only have a PIMPL pointer. You can however get the declared properties (such as declared with the Q_PROPERTY macro) and this is used extensively, e.g. in QML.

                        Read and abide by the Qt Code of Conduct

                        mrjjM 1 Reply Last reply
                        1
                        • kshegunovK kshegunov

                          @mrjj said:

                          I just wish it could list
                          members variables + type too

                          Well, this wouldn't be very helpful, as you already know what member variables you have (and some of them may be private), or as in the usual case you only have a PIMPL pointer. You can however get the declared properties (such as declared with the Q_PROPERTY macro) and this is used extensively, e.g. in QML.

                          mrjjM Offline
                          mrjjM Offline
                          mrjj
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @kshegunov
                          well it would be extremely helpful for creating boilerplate code for serialization and
                          trace systems & module tests and all kind of code gen.
                          Without adding ANYTHING to the source code as all serialization
                          frameworks i have seen does.

                          Maybe in c++32 :)

                          kshegunovK 1 Reply Last reply
                          0
                          • mrjjM mrjj

                            @kshegunov
                            well it would be extremely helpful for creating boilerplate code for serialization and
                            trace systems & module tests and all kind of code gen.
                            Without adding ANYTHING to the source code as all serialization
                            frameworks i have seen does.

                            Maybe in c++32 :)

                            kshegunovK Offline
                            kshegunovK Offline
                            kshegunov
                            Moderators
                            wrote on last edited by
                            #13

                            @mrjj said:

                            well it would be extremely helpful for creating boilerplate code for serialization

                            You have QDataStream for that. My suspicion is that moc's source will just explode if you start adding more and more parsing features. It already does a lot, e.g. RTTI without compiler RTTI and of course the signal-slot mechanism. If you need to wrap some boilerplate code you can always use a combination of the preprocessor with virtualization (similarly to what Qt does). I, personally, use a virtual stream operator for such things:

                            class MyClass
                            {
                                friend QDataStream & operator << (QDataStream &, const MyClass &);
                                friend QDataStream & operator >> (QDataStream &, MyClass &);
                            
                            protected:
                                virtual bool serialize(QDataStream &) = 0;
                                virtual bool deserialize(QDataStream &) = 0;
                            }
                            
                            inline QDataStream & operator << (QDataStream & out, const MyClass & obj)
                            {
                                obj.serialize(out);
                                return out;
                            }
                            
                            inline QDataStream & operator >> (QDataStream & in, MyClass & obj)
                            {
                                obj.deserialize(in);
                                return in;
                            }
                            

                            Read and abide by the Qt Code of Conduct

                            mrjjM 1 Reply Last reply
                            2
                            • kshegunovK kshegunov

                              @mrjj said:

                              well it would be extremely helpful for creating boilerplate code for serialization

                              You have QDataStream for that. My suspicion is that moc's source will just explode if you start adding more and more parsing features. It already does a lot, e.g. RTTI without compiler RTTI and of course the signal-slot mechanism. If you need to wrap some boilerplate code you can always use a combination of the preprocessor with virtualization (similarly to what Qt does). I, personally, use a virtual stream operator for such things:

                              class MyClass
                              {
                                  friend QDataStream & operator << (QDataStream &, const MyClass &);
                                  friend QDataStream & operator >> (QDataStream &, MyClass &);
                              
                              protected:
                                  virtual bool serialize(QDataStream &) = 0;
                                  virtual bool deserialize(QDataStream &) = 0;
                              }
                              
                              inline QDataStream & operator << (QDataStream & out, const MyClass & obj)
                              {
                                  obj.serialize(out);
                                  return out;
                              }
                              
                              inline QDataStream & operator >> (QDataStream & in, MyClass & obj)
                              {
                                  obj.deserialize(in);
                                  return in;
                              }
                              
                              mrjjM Offline
                              mrjjM Offline
                              mrjj
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              @kshegunov
                              Well I guess it then again boils down to
                              out << var1 << var2 << var3 pr class which is what
                              i would like NOT to have to ever write. :)

                              So if could

                              for ( all member vars : curvar)
                              out << curvar;

                              make me very happy.

                              It seems Qt properties would allow such thing ? :)

                              kshegunovK 1 Reply Last reply
                              0
                              • mrjjM mrjj

                                @kshegunov
                                Well I guess it then again boils down to
                                out << var1 << var2 << var3 pr class which is what
                                i would like NOT to have to ever write. :)

                                So if could

                                for ( all member vars : curvar)
                                out << curvar;

                                make me very happy.

                                It seems Qt properties would allow such thing ? :)

                                kshegunovK Offline
                                kshegunovK Offline
                                kshegunov
                                Moderators
                                wrote on last edited by kshegunov
                                #15

                                @mrjj

                                It seems Qt properties would allow such thing ? :)

                                Yes, you can list them, but then again you have to declare them with Q_PROPERTY, and also you might want to save internal data that's not exposed through a property ... which could pose a significant problem.

                                I prefer the mentioned method, because I can delegate to the parent. Consider the following example:

                                class MyClassImpl : public MyClass
                                {
                                    // ...
                                
                                protected:
                                    bool serialize(QDataStream & out) override
                                    {
                                        out << x;
                                        return true;
                                    }
                                
                                    bool deserialize(QDataStream & in) override
                                    {
                                        in >> x;
                                        return true;
                                    }
                                
                                private:
                                    int x;
                                }
                                
                                class MyDerivedClassImpl : public MyClassImpl
                                {
                                    // ...
                                
                                protected:
                                    bool serialize(QDataStream & out) override
                                    {
                                        MyClassImpl::serialize(out);
                                        out << y << str;
                                        return true;
                                    }
                                
                                    bool deserialize(QDataStream & in) override
                                    {
                                        MyClassImpl::deserialize(in);
                                        out >> y >> str;
                                        return true;
                                    }
                                
                                private:
                                    double y;
                                    QString str;
                                }
                                

                                Read and abide by the Qt Code of Conduct

                                mrjjM 1 Reply Last reply
                                0
                                • kshegunovK kshegunov

                                  @mrjj

                                  It seems Qt properties would allow such thing ? :)

                                  Yes, you can list them, but then again you have to declare them with Q_PROPERTY, and also you might want to save internal data that's not exposed through a property ... which could pose a significant problem.

                                  I prefer the mentioned method, because I can delegate to the parent. Consider the following example:

                                  class MyClassImpl : public MyClass
                                  {
                                      // ...
                                  
                                  protected:
                                      bool serialize(QDataStream & out) override
                                      {
                                          out << x;
                                          return true;
                                      }
                                  
                                      bool deserialize(QDataStream & in) override
                                      {
                                          in >> x;
                                          return true;
                                      }
                                  
                                  private:
                                      int x;
                                  }
                                  
                                  class MyDerivedClassImpl : public MyClassImpl
                                  {
                                      // ...
                                  
                                  protected:
                                      bool serialize(QDataStream & out) override
                                      {
                                          MyClassImpl::serialize(out);
                                          out << y << str;
                                          return true;
                                      }
                                  
                                      bool deserialize(QDataStream & in) override
                                      {
                                          MyClassImpl::deserialize(in);
                                          out >> y >> str;
                                          return true;
                                      }
                                  
                                  private:
                                      double y;
                                      QString str;
                                  }
                                  
                                  mrjjM Offline
                                  mrjjM Offline
                                  mrjj
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #16

                                  @kshegunov
                                  Yeah, 50% is not Qt enabled so would be an issue.
                                  Im just daydreaming :)

                                  Hmm, that is actually neat.

                                  1 Reply Last reply
                                  0

                                  • Login

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