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. Qt MetaType and Circular Dependency
QtWS25 Last Chance

Qt MetaType and Circular Dependency

Scheduled Pinned Locked Moved Unsolved General and Desktop
c++qmetatypecirculardependencies
8 Posts 3 Posters 1.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.
  • Y Offline
    Y Offline
    yassser
    wrote on 6 May 2020, 11:53 last edited by
    #1

    Hi!
    i have two qt classes which i intend to use in templates using the Grantlee library, the problem is the two classes use each other like in the code bellow that was working untill using grantlee if you are not familiar with grantlee it just fill template from qt objects like Django,jinja

    /file a.h
    class B;
    Q_DECLARE_METATYPE(QList<B*>)
    class A : public QOBject{
    QOBJECT
        Q_PROPERTY(QList<B*> bList...)
    
    };
    
    // file b.h
    class A;
    class B : public QOBject{
    QOBJECT
        Q_PROPERTY(A* a...)
    
    };
    

    the core problem is that to properly use 'a' and 'bList' in grantLee the Classes A&B need to be fully declared so i get this error QMetaProperty::read: Unable to handle unregistered datatype 'QList' for property 'A::bList'

    i tried using Q_DECLARE_METATYPE(QList) and same for 'a' but Q_DECLARE_METATYPE require the class to be fully described so i tried with Q_DECLARE_OPAQUE_POINTER(B) i get this error grantlee.customtype: Don't know how to handle metatype B

    is there a way to go around this circular dependency + qt properties problem ? or a change in the architecture is a must

    K 1 Reply Last reply 6 May 2020, 13:56
    0
    • Y yassser
      6 May 2020, 11:53

      Hi!
      i have two qt classes which i intend to use in templates using the Grantlee library, the problem is the two classes use each other like in the code bellow that was working untill using grantlee if you are not familiar with grantlee it just fill template from qt objects like Django,jinja

      /file a.h
      class B;
      Q_DECLARE_METATYPE(QList<B*>)
      class A : public QOBject{
      QOBJECT
          Q_PROPERTY(QList<B*> bList...)
      
      };
      
      // file b.h
      class A;
      class B : public QOBject{
      QOBJECT
          Q_PROPERTY(A* a...)
      
      };
      

      the core problem is that to properly use 'a' and 'bList' in grantLee the Classes A&B need to be fully declared so i get this error QMetaProperty::read: Unable to handle unregistered datatype 'QList' for property 'A::bList'

      i tried using Q_DECLARE_METATYPE(QList) and same for 'a' but Q_DECLARE_METATYPE require the class to be fully described so i tried with Q_DECLARE_OPAQUE_POINTER(B) i get this error grantlee.customtype: Don't know how to handle metatype B

      is there a way to go around this circular dependency + qt properties problem ? or a change in the architecture is a must

      K Offline
      K Offline
      kshegunov
      Moderators
      wrote on 6 May 2020, 13:56 last edited by kshegunov 5 Jun 2020, 13:57
      #2

      @yassser said in Qt MetaType and Circular Dependency:

      Hi!

      Hi.

      the core problem is that to properly use 'a' and 'bList' in grantLee the Classes A&B need to be fully declared so i get this error QMetaProperty::read: Unable to handle unregistered datatype 'QList' for property 'A::bList'

      Where is QMetaProperty::read called? Where do you get the error?

      i tried using Q_DECLARE_METATYPE(QList) and same for 'a' but Q_DECLARE_METATYPE require the class to be fully described so i tried with Q_DECLARE_OPAQUE_POINTER(B) i get this error grantlee.customtype: Don't know how to handle metatype B

      Q_DECLARE_METATYPE is used with the actual type, QList by itself isn't a "type" in the sense it's a template. To be compiled instantiantion needs to be performed, for which the template parameter must be known. Can you do something like this:

      typedef QList<B *> BList;
      Q_DECLARE_METATYPE(BList)
      

      Does this produce an error?

      is there a way to go around this circular dependency + qt properties problem ?

      To me it's not exactly clear where the problem lies, so let's take it a step at a time.

      Read and abide by the Qt Code of Conduct

      Y 1 Reply Last reply 7 May 2020, 12:58
      1
      • K kshegunov
        6 May 2020, 13:56

        @yassser said in Qt MetaType and Circular Dependency:

        Hi!

        Hi.

        the core problem is that to properly use 'a' and 'bList' in grantLee the Classes A&B need to be fully declared so i get this error QMetaProperty::read: Unable to handle unregistered datatype 'QList' for property 'A::bList'

        Where is QMetaProperty::read called? Where do you get the error?

        i tried using Q_DECLARE_METATYPE(QList) and same for 'a' but Q_DECLARE_METATYPE require the class to be fully described so i tried with Q_DECLARE_OPAQUE_POINTER(B) i get this error grantlee.customtype: Don't know how to handle metatype B

        Q_DECLARE_METATYPE is used with the actual type, QList by itself isn't a "type" in the sense it's a template. To be compiled instantiantion needs to be performed, for which the template parameter must be known. Can you do something like this:

        typedef QList<B *> BList;
        Q_DECLARE_METATYPE(BList)
        

        Does this produce an error?

        is there a way to go around this circular dependency + qt properties problem ?

        To me it's not exactly clear where the problem lies, so let's take it a step at a time.

        Y Offline
        Y Offline
        yassser
        wrote on 7 May 2020, 12:58 last edited by
        #3

        @kshegunov

        Where is QMetaProperty::read called? Where do you get the error?

        considering an instance 'aObj' given to grantlee engine to be rendered
        and we want to get the property 'a' of the first Bobject in the blist
        the error happened here {{ aObject.blist.0.a }} //0:first element
        in normal circumstances it would work providing that you use #include 'b.h' in A and
        #include 'a.h' in B to be able to render "aObject.blist.0" and "0.a"
        but that would cause circular dependency
        so is there some macro that register the type without having to include the file ?

        typedef QList<B *> BList;

        Q_DECLARE_METATYPE(BList)
        Does this produce an error?

        C2338: Type argument of Q_DECLARE_METATYPE(T*) must be fully defined
        this is the error that it produces, note that the error dosnt show up when you include the header files instead of predefining the class. even when you use Q_DECLARE_METATYPE(QList<B*>)

        1 Reply Last reply
        0
        • V Offline
          V Offline
          VRonin
          wrote on 7 May 2020, 14:11 last edited by
          #4

          If B is a QObject, QList<QObject*> will work out of the box so you don't need to declare it as a metatype at all. Can you explain why you have this need?

          "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

          Y 1 Reply Last reply 8 May 2020, 14:23
          0
          • V VRonin
            7 May 2020, 14:11

            If B is a QObject, QList<QObject*> will work out of the box so you don't need to declare it as a metatype at all. Can you explain why you have this need?

            Y Offline
            Y Offline
            yassser
            wrote on 8 May 2020, 14:23 last edited by
            #5

            @VRonin
            you are right ,when you are using just qt to access the property(getters/setters...) it would work whithout having to declare it, but grantlee require you to register the type to QVariant so it can use it in templates, like to access the first element and inspect it's properties {{ blist.0.propertyofb }}

            K 1 Reply Last reply 8 May 2020, 21:19
            0
            • Y yassser
              8 May 2020, 14:23

              @VRonin
              you are right ,when you are using just qt to access the property(getters/setters...) it would work whithout having to declare it, but grantlee require you to register the type to QVariant so it can use it in templates, like to access the first element and inspect it's properties {{ blist.0.propertyofb }}

              K Offline
              K Offline
              kshegunov
              Moderators
              wrote on 8 May 2020, 21:19 last edited by
              #6

              @yassser said in Qt MetaType and Circular Dependency:

              you are right ,when you are using just qt to access the property(getters/setters...) it would work whithout having to declare it, but grantlee require you to register the type to QVariant so it can use it in templates, like to access the first element and inspect it's properties {{ blist.0.propertyofb }}

              You can't register QObjects as metatypes and can't put QObjects in QVariant because they are can't be copied. By definition (a.k.a. metatype requirements) a QObject derived class isn't and can't be a meta-type. The only thing you could possibly do is to have a QObject * put into a QVariant, but that's rather different.
              That said, I still don't understand the problem, though, I have no idea what this library expects nor where (and by "where" I mean a concrete piece of c++ code) this error occurs.

              Read and abide by the Qt Code of Conduct

              Y 1 Reply Last reply 9 May 2020, 13:02
              2
              • K kshegunov
                8 May 2020, 21:19

                @yassser said in Qt MetaType and Circular Dependency:

                you are right ,when you are using just qt to access the property(getters/setters...) it would work whithout having to declare it, but grantlee require you to register the type to QVariant so it can use it in templates, like to access the first element and inspect it's properties {{ blist.0.propertyofb }}

                You can't register QObjects as metatypes and can't put QObjects in QVariant because they are can't be copied. By definition (a.k.a. metatype requirements) a QObject derived class isn't and can't be a meta-type. The only thing you could possibly do is to have a QObject * put into a QVariant, but that's rather different.
                That said, I still don't understand the problem, though, I have no idea what this library expects nor where (and by "where" I mean a concrete piece of c++ code) this error occurs.

                Y Offline
                Y Offline
                yassser
                wrote on 9 May 2020, 13:02 last edited by
                #7

                @kshegunov
                Hi!

                You can't register QObjects as metatypes and can't put QObjects in QVariant because they are can't be copied. By definition (a.k.a. metatype requirements)

                correct me if i'm wrong but does the copying part mean that you cant copy the properties to variant using QVariant::fromValue(QObject*) because it is working some QObject Derived classes in the Project , or you mean add the QObject subclass to the Qt Standard Types as in this exemple CustomTypes there is 3 requirement

                Before we begin, we need to ensure that the custom type we are creating meets all the requirements imposed by QMetaType. In other words, it must provide:

                a public default constructor,

                a public copy constructor, and

                a public destructor.or the

                as for declaring QList<B*> i will switch to the typedef solution as it is more safe like you said although the other one(declar_type(QList<B*>)) is working somehow

                but the core problem i'm facing is the requirement of Q_DECLARE_METATYPE(B*) that B should be fully defined(defining the class using #include'b.h' instead of 'class B') as i cant include the header files because it will cause circular dependency because A it self require the same process

                K 1 Reply Last reply 12 May 2020, 07:35
                0
                • Y yassser
                  9 May 2020, 13:02

                  @kshegunov
                  Hi!

                  You can't register QObjects as metatypes and can't put QObjects in QVariant because they are can't be copied. By definition (a.k.a. metatype requirements)

                  correct me if i'm wrong but does the copying part mean that you cant copy the properties to variant using QVariant::fromValue(QObject*) because it is working some QObject Derived classes in the Project , or you mean add the QObject subclass to the Qt Standard Types as in this exemple CustomTypes there is 3 requirement

                  Before we begin, we need to ensure that the custom type we are creating meets all the requirements imposed by QMetaType. In other words, it must provide:

                  a public default constructor,

                  a public copy constructor, and

                  a public destructor.or the

                  as for declaring QList<B*> i will switch to the typedef solution as it is more safe like you said although the other one(declar_type(QList<B*>)) is working somehow

                  but the core problem i'm facing is the requirement of Q_DECLARE_METATYPE(B*) that B should be fully defined(defining the class using #include'b.h' instead of 'class B') as i cant include the header files because it will cause circular dependency because A it self require the same process

                  K Offline
                  K Offline
                  kshegunov
                  Moderators
                  wrote on 12 May 2020, 07:35 last edited by
                  #8

                  @yassser said in Qt MetaType and Circular Dependency:

                  correct me if i'm wrong but does the copying part mean that you cant copy the properties to variant using QVariant::fromValue(QObject*) because it is working some QObject Derived classes in the Project , or you mean add the QObject subclass to the Qt Standard Types as in this exemple CustomTypes there is 3 requirement

                  Both. When adding a QObject * to a QVariant you copy nothing, you just transfer a reference, and if that reference disappears in the mean time, well that's cause for concern.

                  @yassser said in Qt MetaType and Circular Dependency:

                  as for declaring QList<B*> i will switch to the typedef solution as it is more safe like you said although the other one(declar_type(QList<B*>)) is working somehow

                  For what it's worth, declaration of metatypes should happen where the type is defined, not somewhere else. So even ideologically:

                  class B;
                  Q_DECLARE_METATYPE(QList<B*>)
                  

                  is wrong. That metatype declaration should've gone where B is defined, aside from it being needed or not.

                  but the core problem i'm facing is the requirement of Q_DECLARE_METATYPE(B*) that B should be fully defined(defining the class using #include'b.h' instead of 'class B')

                  Still talking hypotheticals. I don't see any concrete error that one gets from the compiler, nor a specific piece of cpp code that's the cause of said error.

                  as i cant include the header files because it will cause circular dependency because A it self require the same process

                  Where does it require that and why? Please post a snippet, I'm getting rather frustrated here. Consider this in the meantime:

                  class B;
                  typedef QList<B *> BList;
                  
                  class A
                  {
                  public:
                      void setBList(const BList &); //< This doesn't require a definition of BList, and by extension a definition of B isn't required
                      BList bList() const; //< Nor does this
                  };
                  

                  Read and abide by the Qt Code of Conduct

                  1 Reply Last reply
                  1

                  5/8

                  8 May 2020, 14:23

                  • Login

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