Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Metaobject Reflect child classes from base classes in C++

Metaobject Reflect child classes from base classes in C++

Scheduled Pinned Locked Moved QML and Qt Quick
9 Posts 3 Posters 2.6k 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.
  • C Offline
    C Offline
    christoffk
    wrote on last edited by
    #1

    We want a solution in C++ that must be able to do the following:
    Given a string of particular type, lets say 'A', we want to find all the types that derives from 'A'.
    Instantiate new objects out of the types that are derived from 'A'.
    E.g. Lets say we have a class, VehicleEntity. VehicleEntityhas child classes, PassangerCarEntity, TruckEntity, TrainEntity, BoatEntity.
    We are unsure what vehicle entities there may be as the a library could be added containing more VehicleEntities. E.g. an AirplaneEntity thaterives from VehicleEntity could be added after deployment.
    In the application, when a user wants to select a VehicleEntity, the user should be able to pick any of the entities deriving from VehicleEntity. This includes the PassangerCarEntity, TruckEntity, TrainEntity, BoatEntity and AirplaneEntity.
    The user selects an Entity, lets say AirplaneEntity, A new object of type AirplaneEntity must be instantiated.

    The following is an concept example in C# of what we want to achieve in C++.
    In C# the items for the dropdown list can be retrieved as follows:
    @Type vehicleEntityType = typeof(VehicleEntity);
    List<Type> types = new List<Type>();
    foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
    types.AddRange(assembly.GetTypes().Where(x => vehicleEntityType.IsAssignableFrom(x) && !x.IsGenericType && !x.IsAbstract));
    dropDownBox.ItemList = types;

    //To instantiate the object:
    List<VehicleEntity> vehicleList = new List<VehicleEntity>();
    Type newVehicleType = (Type)dropDownBox.SelectedItem;
    object newVehicle = Activator.CreateInstance(newVehicleType ); // defrault constructor used, parameterless constructors for vehicles.
    vehicleList.Add(newVehicle);@

    Is this possible in QT?
    From the documentation it seems that all this is possible with the possible exception of finding a list of all the classes deriving from a base class. Finding all of the types in the application would be usefull, but this does not seem possible. Is this correct?

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      Check out the documentation of Qt Meta Object System. Yes, most of the stuff should be possible as long as you have some concrete objects of those classes.

      (Z(:^

      1 Reply Last reply
      0
      • C Offline
        C Offline
        christoffk
        wrote on last edited by
        #3

        From the documentation it does not seem possible to access the types if the types has not been instantiated into an object yet. This is unfortunately a requirement for us. Am I perhaps missing something?

        I did discover to other solutions. http://seal-reflex.web.cern.ch/seal-reflex/examples.html and http://www.cplusplus.com/forum/general/118016/

        We are planning to make use of QT for our UI regardless of this issue. It would be good to be certain whether this is possible in QT or not.

        1 Reply Last reply
        0
        • sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #4

          [quote author="christoffk" date="1386137416"]From the documentation it does not seem possible to access the types if the types has not been instantiated into an object yet. This is unfortunately a requirement for us. Am I perhaps missing something?[/quote]

          No, as far as I know you are completely right here.

          (Z(:^

          1 Reply Last reply
          0
          • C Offline
            C Offline
            christoffk
            wrote on last edited by
            #5

            Thank you very much for you helpful answers. Much appreciated.

            1 Reply Last reply
            0
            • T Offline
              T Offline
              theoriginalgri
              wrote on last edited by
              #6

              What you're requesting is possible:

              • VehicleEntity must be a subclass of QObject
              • CarEntity etc. must be subclasses of VehicleEntry and have a Q_INVOKABLE prefix on the constructor

              All these classes then have "staticMetaObject" which is a QMetaObject.

              @
              QList<const QMetaObject*> metaObjects;
              metaObjects.append(&CarEntity::staticMetaObject);
              metaObjects.append(&AirplaneEntity::staticMetaObject);
              ...

              foreach(const QMetaObject* meta, metaObjects) {
              if (meta->superClass() == &VehicleEntity::staticMetaObject) {
              QObject* instance = meta->newInstance();
              VehicleEntity* entity = qobject_cast<VehicleEntity*>(instance);
              ...
              }
              }
              @

              • You have to maintain a list of all your possible entities somewhere, there is no global list of all staticMetaObjects. This should not be a big problem if you have some kind of plugin-architecture.
              • Only instances of QObject have the inherits() method, if you only have MetaObjects, you have to walk the superClass() tree up and check the inheritance manually.
              • There is no isAbstract method like in your C# code. But you can check for Q_INVOKABLE constructors or whether newInstance() returns a value.
              1 Reply Last reply
              0
              • C Offline
                C Offline
                christoffk
                wrote on last edited by
                #7

                Thanks gri.

                "You have to maintain a list of all your possible entities somewhere, there is no global list of all staticMetaObjects"

                We want to avoid this if possible, for maintainability and speed of development reasons. (manual intervention adds more chance for err + added effort by the user).

                This is something to consider, but we will try out the above solutions which caters for this scenario first.

                Thanks again.

                1 Reply Last reply
                0
                • T Offline
                  T Offline
                  theoriginalgri
                  wrote on last edited by
                  #8

                  If you want to fetch all staticMetaObjects of the whole application there is a hacky solution which I've done for my former company. The moc tool is written in a way that you can use it's code (without modifying it) to implement your own tool. This means you can add your own tool that executes after the moc compilation step and builds a database for staticMetaObject's.
                  Since this introduces an additional tool that runs on build, it is rather the hacky solution ;)

                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    christoffk
                    wrote on last edited by
                    #9

                    Thanks grl, This is definitely an option to keep in mind.

                    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