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
QtWS25 Last Chance

Dynamic cast (interface) class in QML

Scheduled Pinned Locked Moved Solved General and Desktop
c++ and qml cod
6 Posts 3 Posters 911 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 4 Aug 2022, 13:40 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
    • J Offline
      J Offline
      JoeCFD
      wrote on 4 Aug 2022, 16:34 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 10 Aug 2022, 07:58 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 10 Aug 2022, 08:47 last edited by
          #4

          I would guess you need to start with QML_INTERFACE and QML_IMPLEMENTS_INTERFACES

          K 1 Reply Last reply 10 Aug 2022, 09:05
          0
          • C ChrisW67
            10 Aug 2022, 08:47

            I would guess you need to start with QML_INTERFACE and QML_IMPLEMENTS_INTERFACES

            K Offline
            K Offline
            Krulle
            wrote on 10 Aug 2022, 09:05 last edited by
            #5

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

            1 Reply Last reply
            0
            • K Offline
              K Offline
              Krulle
              wrote on 17 Aug 2022, 09:14 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