Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved Dynamic cast (interface) class in QML

    General and Desktop
    c++ and qml cod
    3
    6
    265
    Loading More Posts
    • 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
      Krulle last edited by

      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 Reply Quote 0
      • JoeCFD
        JoeCFD last edited by

        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 Reply Quote 0
        • K
          Krulle last edited by

          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 Reply Quote 0
          • C
            ChrisW67 last edited by

            I would guess you need to start with QML_INTERFACE and QML_IMPLEMENTS_INTERFACES

            K 1 Reply Last reply Reply Quote 0
            • K
              Krulle @ChrisW67 last edited by

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

              1 Reply Last reply Reply Quote 0
              • K
                Krulle last edited by

                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 Reply Quote 0
                • First post
                  Last post