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. Access to an After Loaded View From Qml To C++
Forum Updated to NodeBB v4.3 + New Features

Access to an After Loaded View From Qml To C++

Scheduled Pinned Locked Moved QML and Qt Quick
11 Posts 3 Posters 5.4k Views 1 Watching
  • 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
    yohannvf
    wrote on last edited by
    #1

    Hello ! I'm new in Qt Devlopment and I have a short question that certainly won't take long time to resolve for such specialists ;)

    I made a Loader to display a splashscreen that will load the main.qml thereafter like this:

    @
    QDeclarativeView view;
    view.setSource(QUrl("MainAppLoader.qml"));
    view.setResizeMode(QDeclarativeView::SizeRootObjectToView);
    view.showFullScreen();@

    I would like to connect some stuff to a child of my PageStackWindows in main.qml : mainMenu.qml

    The problem if I do that :

    @ QObject rootObject = dynamic_cast<QObject>(view.rootObject());
    QObject mainMenu = rootObject->findChild<QObject>("mainMenu");
    QObject::connect(&myClass, SIGNAL(data(QVariant)), mainMenu, SLOT(updateData(QVariant)));@

    I get this error: QObject::connect: Cannot connect <MyClass>::data(QVariant) to (null)::updateData(QVariant)

    Yes mainMenu is null. Of course I put: objectName: "mainMenu"

    In my MainAppLoader.qml I have this that load the main.qml :

    @Loader {
    id: mainLoader
    width: parent.width
    height: parent.height
    }

        Timer {
            id: firstPhaseTimer
            interval: 700
            running: true
            repeat: false
    
            onTriggered: {
                if (!mainLoader.Loading) {
                    // Start to load the main application
                    mainLoader.source = Qt.resolvedUrl("main.qml");
                    secondPhaseTimer.start();
                }
            }
        }@
    

    Do you know how I could get / use the reference of my main.qml / MainMenu.qml freshly created to connect what I want from cpp ?

    If I do the same without my splashScreenLoader, it works.

    Thanks !

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

      You are probably asking for connection too early. Either emit a signal to C++ once loading is ready, or make the connection in QML.

      (Z(:^

      1 Reply Last reply
      0
      • Y Offline
        Y Offline
        yohannvf
        wrote on last edited by
        #3

        You say it's possible to connect a freshly created QML View with CPP in QML ?

        In other words, I just need to warn Cpp with a signal when my main.qml is created mainLoader.source = Qt.resolvedUrl("main.qml");
        to tell him to make the rootObject->findChild<QObject*>("mainMenu"); and connect it ? that's all ?

        I'l try tomorow, thank you for the quick anwser !

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

          I think so. To be honest I did not take time to read through and fully understand your post, I just gave a first impression.

          The definite point is that object needs to be ready before meta objects can be connected.

          BTW. you don't need the dynamic_cast line, root object should have ::findChild() available.

          (Z(:^

          1 Reply Last reply
          0
          • F Offline
            F Offline
            feldifux
            wrote on last edited by
            #5

            As I see it, you have the following options:

            1.) Call a C++ slot after the Loader finished, as sierdzio suggested
            You can call a C++ function from QML by registering the C++ object as a context property with @QDeclarativeContext::setContextProperty()@ and then call the slot function of this object. This is useful if the object you are calling only exists once, i.e. a Singleton.

            2.) By registering the C++ item as a QML item. You can do that with @qmlRegisterType<CppClassName>("NamespaceForImport", 1, 0 "QMLItemName")@

            In that way, you could also directly access the signal from QML, e.g. if the signal is called @dataChanged(QVariant newData)@

            , you can access it in QML with
            @
            import NamespaceForImport 1.0

            QMLItemName {
            onDataChanged: { ... "newData" is available as parameter ... }
            }
            @

            Founder of Felgo SDK - http://felgo.com/qt

            Felgo simplifies

            • Mobile App Dev with Qt esp. iOS & Android
            • Game Development with Qt

            What others say

            Felgo scored #1 in Cross-Platform App Development Tools Report - see why: https://goo.gl/rgp3rq

            1 Reply Last reply
            0
            • Y Offline
              Y Offline
              yohannvf
              wrote on last edited by
              #6

              Hello again, I think I'm doing it wrong

              I made a call to my C++ object when QML completed the launched of MainMenu.qml like this:

              in main.cpp:

              @QDeclarativeView view;
              view.rootContext()->setContextProperty("MyClass",myClass);@

              in MainMenu.qml

              @Component.onCompleted: {
              MyClass.mainMenuCreated();
              }@

              in MyClass c++

              @void MyClass::mainMenuCreated()
              {
              qDebug() << "Hello I'm created";

              }@

              This is working but now, How can I have access to QDeclarativeView / QDeclarativeContext from MyClass to connect my freshly created qml file with c++ signal ? I only have access in main.cpp and tried to pass it in MyClass constructor, but it seems private. I think I'm doing something wrong :D

              1 Reply Last reply
              0
              • F Offline
                F Offline
                feldifux
                wrote on last edited by
                #7

                You should be able to pass it with the constructor - what do you mean that it is private? You have control over MyClass implementation, so you can just do something like the following:
                @
                //in main.cpp:
                QMLApplicationViewer viewer;

                MyClass myClass = new MyClass(viewer);

                //and in MyClass constructor you can access the QDeclarativeEngine from the QMLApplicationViewer with:

                MyClass::MyClass(QMLApplicationViewer &viewer) {
                QDeclarativeEngine *engine = viewer.engine();
                QDeclarativeContext *context = engine->rootContext;
                }
                @

                From the QDeclarativeView you can call the method rootContext() to get the context in your MyClass.

                Alternatively, to receive the context from a QDeclarativeItem which you instantiate from QML, you can use the following:
                @QDeclarativeContext *currentContext = QDeclarativeEngine::contextForObject(this);
                QDeclarativeEngine *declarativeEngine = currentContext->engine();
                QDeclarativeContext *rootContext = declarativeEngine->rootContext();@

                Founder of Felgo SDK - http://felgo.com/qt

                Felgo simplifies

                • Mobile App Dev with Qt esp. iOS & Android
                • Game Development with Qt

                What others say

                Felgo scored #1 in Cross-Platform App Development Tools Report - see why: https://goo.gl/rgp3rq

                1 Reply Last reply
                0
                • Y Offline
                  Y Offline
                  yohannvf
                  wrote on last edited by
                  #8

                  I surely made a mistake somewhere :(

                  In main.cpp

                  @QDeclarativeView view;
                  MyClass *myClass = new MyClass(view);
                  @

                  MyClass.h

                  @class MyClass : public QObject
                  {
                  Q_OBJECT
                  public:
                  explicit MyClass();
                  explicit MyClass(QDeclarativeView &view);

                  signals:

                  public slots:

                  private:
                  QDeclarativeView mQDeclarativeView;
                  

                  };@

                  MyClass.cpp

                  @MyClass::MyClass() {
                  }

                  MyClass::MyClass(QDeclarativeView &view) {
                  mQDeclarativeView = view;
                  }@

                  Got this error:

                  @ error : 'QDeclarativeView& QDeclarativeView::operator=(const QDeclarativeView&)' is private
                  @

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

                    Use a pointer. You are trying to use an assignment operator while all QObject children cannot be copied.

                    (Z(:^

                    1 Reply Last reply
                    0
                    • Y Offline
                      Y Offline
                      yohannvf
                      wrote on last edited by
                      #10

                      It was what I did first but you gave me an example with references :P

                      It's working now :)

                      The final code for visitors:

                      @void MyClass::mainMenuCreated()
                      {
                      qDebug() << "Hello I'm created";

                      QObject *menu = (mQDeclarativeView->rootObject())->findChild<QObject*>("mainMenu");
                      QObject::connect(this, SIGNAL(data(QVariant)), menu, SLOT(updateData(QVariant)));
                      

                      }@

                      And now my function from MainMenu.qml is called :)

                      @updateData(text) { console.log("I'm here"); }
                      @

                      If you see any improvment that could be made or other better technique, don't hesitate :)

                      Thank you so much for this lesson :P

                      1 Reply Last reply
                      0
                      • F Offline
                        F Offline
                        feldifux
                        wrote on last edited by
                        #11

                        No worries :)

                        As a tiny improvement, it's good practice to name context properties with a small first letter to be able to distinguish them from classes/QML components. So instead of "MyClass", name it "myClass" - you could access enums for instance from QML with "MyClass.enumName" then, and so don't mix it up with a context property access.

                        Also, the data-signal could be renamed to dataChanged, as it is probably reflects more what it does. But that's syntactic sugar, just a suggestion..

                        Founder of Felgo SDK - http://felgo.com/qt

                        Felgo simplifies

                        • Mobile App Dev with Qt esp. iOS & Android
                        • Game Development with Qt

                        What others say

                        Felgo scored #1 in Cross-Platform App Development Tools Report - see why: https://goo.gl/rgp3rq

                        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