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. Dynamic cast (interface) class in QML
Forum Updated to NodeBB v4.3 + New Features

Dynamic cast (interface) class in QML

Scheduled Pinned Locked Moved Solved General and Desktop
c++ and qml cod
6 Posts 3 Posters 957 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.
  • K Offline
    K Offline
    Krulle
    wrote on last edited by
    #1

    Hello all,

    what is the best practice to make an C++ interface/base class accessible in QML?

    For example (not complete and not right):

    class IFoo : public QObject 
    {
        explicit IFoo(QObject *parent = nullptr) {}
        ~virtual IFoo() {}
        virtual void overrideMe() = 0;
    }
    
    class FooA : public IFoo
    {
        FooA(QObject *parent = nullptr) {}
    }
    
    class FooB : public IFoo
    {
        FooB(QObject *parent = nullptr) {}
    }
    

    main:

    int main(int argc, char *argv[])
    {
        QQmlApplicationEngine engine;
        
        IFoo *foo1 = new FooA;
        IFoo *foo2 = new FooB;
        
        FooB *foo3 = new FooB;
    
        engine.rootContext()->setContextProperty("foo", foo1); // which type it is in QML? IFoo?
        // or
        engine.rootContext()->setContextProperty("foo", qobject_cast<FooA*>(foo1)); // and
        engine.rootContext()->setContextProperty("foo2", qobject_cast<FooB*>(foo2));
    
        engine.rootContext()->setContextProperty("foo3", foo3); // FooB
    }
    

    Is there a way to cast foo1 in QML? Or is this fundamentally a bad idea and evidence of bad code?

    Thank you very much!

    1 Reply Last reply
    0
    • JoeCFDJ Offline
      JoeCFDJ Offline
      JoeCFD
      wrote on last edited by
      #2

      I do no think you need any cast. The following code should work.

          auto foo1 = new FooA;
          auto foo2 = new FooB;
          
          engine.rootContext()->setContextProperty("foo1", foo1); // and
          engine.rootContext()->setContextProperty("foo2", foo2);
      
      1 Reply Last reply
      0
      • K Offline
        K Offline
        Krulle
        wrote on last edited by
        #3

        You're right.

        And how can i use and cast the Base in QML?
        Or is this impossible and i have to use the exact type in QML?
        What is the best way to represent this in QML then?

        What first came to my mind:

        Item {
            property QtObject modul: foo1 ? foo1 : foo2
            property bool isFoo1: foo1 ? true : false
        
            Component.onCompleted: { 
                modul.overrideMe()
            }
        }
        

        But this is of course quite bullshit and I have to check each time which type is present.
        Are there any other ideas?

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

          I would guess you need to start with QML_INTERFACE and QML_IMPLEMENTS_INTERFACES

          K 1 Reply Last reply
          0
          • C ChrisW67

            I would guess you need to start with QML_INTERFACE and QML_IMPLEMENTS_INTERFACES

            K Offline
            K Offline
            Krulle
            wrote on last edited by
            #5

            @ChrisW67
            Thank you. That is the right input :)

            1 Reply Last reply
            0
            • K Offline
              K Offline
              Krulle
              wrote on last edited by
              #6

              Hello folks,

              I would like to give some feedback.
              Basically, it's quite simple: Only the interface class is passed as a ContextProperty, QML then automatically casts the class into the correct type.
              This also works very reliably.

              int main(int argc, char *argv[])
              {
                  QQmlApplicationEngine engine;
                  
                  IFoo *foo = new FooA;
              
                 engine.rootContext()->setContextProperty("iFoo", foo); // in QML it is FooA
              
              }
              

              For differentiation, I return the class name in the interface class with the meta system. I have not found a function in QML that does this reliably (but I also use 5.9).

              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