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. Reloading QQuickWindow content without window recreation

Reloading QQuickWindow content without window recreation

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
8 Posts 3 Posters 1.8k 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.
  • Aleksey_K 0A Offline
    Aleksey_K 0A Offline
    Aleksey_K 0
    wrote on last edited by Aleksey_K 0
    #1

    For qml file with Item element as root of qml scene:

    Item {
    ...
    }
    

    it is possible to preview qml file content with QQuickView without window recreation - see relevant slightly modified and simplified qmlscene code:

    QQmlEngine engine;
    QPointer<QQmlComponent> component = new QQmlComponent(&engine);
    QQuickWindow *window = nullptr;
    auto qxView = new QQuickView(&engine, nullptr);
    
    ...
    
    // Call this slot on file update (for example by QFileSystemWatcher signal)
    updatePreview()
    {
        // Recreate Qml Component
        engine.clearComponentCache();
        component = new QQmlComponent(&engine);
        component->loadUrl(url);
        QObject *topLevel = component->create();
        
        // Recreate Quick Window
        window = qobject_cast<QQuickWindow *>(topLevel);
        if (window) {
            engine.setIncubationController(window->incubationController());
        } else {
            QQuickItem *contentItem = qobject_cast<QQuickItem *>(topLevel);
            if (contentItem) {
                window = qobject_cast<QQuickWindow *>(qxView);
                delete qxView->rootObject(); // Clear old root object before setting new one                
                qxView->setContent(url, component, contentItem);
            }
        }
    }
    

    For such qml file structure window become nullptr on Quick Window recreation and execution goes to else path of if statement. And there we use single QQuickView instance - qxView, just modifying its content without full reloading and recreation.

    BTW, QQuickView::setContent() is undocumented but used in qmlscene.

    However if qml file contains ApplicationWindow as root item of the scene:

    ApplicationWindow {
    ...
    }
    

    execution goes by the 1st variant of Quick Window recreation:

    engine.setIncubationController(window->incubationController());
    

    and new QQuickWindow instance created which takes much more time and force us to destroy and close previous one.

    Is it possible analogous to QQuickView reload scene content for QQuickWindow without full window recreation? Thanks!

    1 Reply Last reply
    0
    • dheerendraD Offline
      dheerendraD Offline
      dheerendra
      Qt Champions 2022
      wrote on last edited by dheerendra
      #2

      One way to look at this is - without window creation

      1. QQuickWIndow gives the invisible root item of the scene using contentItem function.

      2. I can just create the item based QML object and attach this to content item(invisible root item).

      3. This way we will not re-create the window, but just create the scene items and attach item to invisibleItem.

      Dheerendra
      @Community Service
      Certified Qt Specialist
      http://www.pthinks.com

      Aleksey_K 0A 1 Reply Last reply
      0
      • dheerendraD dheerendra

        One way to look at this is - without window creation

        1. QQuickWIndow gives the invisible root item of the scene using contentItem function.

        2. I can just create the item based QML object and attach this to content item(invisible root item).

        3. This way we will not re-create the window, but just create the scene items and attach item to invisibleItem.

        Aleksey_K 0A Offline
        Aleksey_K 0A Offline
        Aleksey_K 0
        wrote on last edited by Aleksey_K 0
        #3

        @dheerendra I'd tried to use contentItem() with no luck. Could You provide minimum working sample or few lines of code to clarify the idea please? How to create QML object from file containing ApplicationWindow element?

        1 Reply Last reply
        0
        • dheerendraD Offline
          dheerendraD Offline
          dheerendra
          Qt Champions 2022
          wrote on last edited by dheerendra
          #4

          Just check this..

          ======main.cpp====

          int main(int argc, char *argv[])
          {
              QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
          
              QGuiApplication app(argc, argv);
          
              QQmlApplicationEngine engine;
              engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
              if (engine.rootObjects().isEmpty())
                  return -1;
          
              qDebug() << engine.rootObjects().at(0)->objectName() <<endl;
              QObject *obj = engine.rootObjects().at(0);
              qDebug() << " Class Name =" << obj->metaObject()->className() <<endl;
          
              QQuickWindow *w = qobject_cast<QQuickWindow*>(obj);
              qDebug() << w->objectName() <<endl;
          
              QQuickItem *rootItem = w->contentItem();
          
              QQmlComponent *comp = new QQmlComponent(&engine,QUrl(QStringLiteral("qrc:/ChildItem.qml")));
              if(comp->isError()){
                 qWarning() << Q_FUNC_INFO << " Unable to create the component " << comp->errorString() << endl;
                 return 1;
              }
              QObject *o1 = comp->create();
              QQuickItem *childItem = qobject_cast<QQuickItem*>(o1);
              childItem->setParentItem(rootItem);
          
              return app.exec();
          }
          

          ===main.qml=======

          Window {
              visible: true
              width: 440
              height: 480
              title: qsTr("Hello World")
              objectName: "TopW"
          }
          

          ===========ChildItem.qml=========

          Rectangle {
              width: 400;height: 400;color: "red"
              Component.onCompleted: {
                  console.log("Child Item created")
              }
          }
          

          Dheerendra
          @Community Service
          Certified Qt Specialist
          http://www.pthinks.com

          Aleksey_K 0A 1 Reply Last reply
          0
          • dheerendraD dheerendra

            Just check this..

            ======main.cpp====

            int main(int argc, char *argv[])
            {
                QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
            
                QGuiApplication app(argc, argv);
            
                QQmlApplicationEngine engine;
                engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                if (engine.rootObjects().isEmpty())
                    return -1;
            
                qDebug() << engine.rootObjects().at(0)->objectName() <<endl;
                QObject *obj = engine.rootObjects().at(0);
                qDebug() << " Class Name =" << obj->metaObject()->className() <<endl;
            
                QQuickWindow *w = qobject_cast<QQuickWindow*>(obj);
                qDebug() << w->objectName() <<endl;
            
                QQuickItem *rootItem = w->contentItem();
            
                QQmlComponent *comp = new QQmlComponent(&engine,QUrl(QStringLiteral("qrc:/ChildItem.qml")));
                if(comp->isError()){
                   qWarning() << Q_FUNC_INFO << " Unable to create the component " << comp->errorString() << endl;
                   return 1;
                }
                QObject *o1 = comp->create();
                QQuickItem *childItem = qobject_cast<QQuickItem*>(o1);
                childItem->setParentItem(rootItem);
            
                return app.exec();
            }
            

            ===main.qml=======

            Window {
                visible: true
                width: 440
                height: 480
                title: qsTr("Hello World")
                objectName: "TopW"
            }
            

            ===========ChildItem.qml=========

            Rectangle {
                width: 400;height: 400;color: "red"
                Component.onCompleted: {
                    console.log("Child Item created")
                }
            }
            
            Aleksey_K 0A Offline
            Aleksey_K 0A Offline
            Aleksey_K 0
            wrote on last edited by Aleksey_K 0
            #5

            @dheerendra this not I'd like to achieve: You propose me to change ApplicationWindow content under root item. But I need to track qml changes in a file which contains whether qml Item (which works fine without reloading) or ApplicationWindow. For example I have such file from tutorial:

            import QtQuick 2.11
            import QtQuick.Controls 2.4
            import QtQuick.Controls.Material 2.4
            import QtQuick.Layouts 1.11
            import QtQuick.Window 2.11
            import Qt.labs.calendar 1.0
            
            ApplicationWindow {
                id: window
                width: 400
                height: 600
                visible: true
                color: "red"
            
                ListView {
                    id: alarmListView
                    anchors.fill: parent
                }
            
                RoundButton {
                    id: addAlarmButton
                    text: "+"
                    anchors.bottom: alarmListView.bottom
                    anchors.bottomMargin: 8
                    anchors.horizontalCenter: parent.horizontalCenter
                    onClicked: alarmDialog.open()
                }
            }
            

            and here I can change color, add, delete or modify items, dimension (width, height), etc. And see all this changes in real time without Window recreation like for QQuickView. For now it recreates and reloads QQuickWindow on every file change and need to close and delete old one.

            dheerendraD 1 Reply Last reply
            0
            • Aleksey_K 0A Aleksey_K 0

              @dheerendra this not I'd like to achieve: You propose me to change ApplicationWindow content under root item. But I need to track qml changes in a file which contains whether qml Item (which works fine without reloading) or ApplicationWindow. For example I have such file from tutorial:

              import QtQuick 2.11
              import QtQuick.Controls 2.4
              import QtQuick.Controls.Material 2.4
              import QtQuick.Layouts 1.11
              import QtQuick.Window 2.11
              import Qt.labs.calendar 1.0
              
              ApplicationWindow {
                  id: window
                  width: 400
                  height: 600
                  visible: true
                  color: "red"
              
                  ListView {
                      id: alarmListView
                      anchors.fill: parent
                  }
              
                  RoundButton {
                      id: addAlarmButton
                      text: "+"
                      anchors.bottom: alarmListView.bottom
                      anchors.bottomMargin: 8
                      anchors.horizontalCenter: parent.horizontalCenter
                      onClicked: alarmDialog.open()
                  }
              }
              

              and here I can change color, add, delete or modify items, dimension (width, height), etc. And see all this changes in real time without Window recreation like for QQuickView. For now it recreates and reloads QQuickWindow on every file change and need to close and delete old one.

              dheerendraD Offline
              dheerendraD Offline
              dheerendra
              Qt Champions 2022
              wrote on last edited by
              #6

              @Aleksey_K-0
              This is where I'm proposing to split the AppWIndows and Content separately. You change the content qml. It will update your AppWindow as well. In the QML what you have posted let me know what you would like to achieve with example. There are ways to monitor the changes.

              Dheerendra
              @Community Service
              Certified Qt Specialist
              http://www.pthinks.com

              Aleksey_K 0A 1 Reply Last reply
              0
              • dheerendraD dheerendra

                @Aleksey_K-0
                This is where I'm proposing to split the AppWIndows and Content separately. You change the content qml. It will update your AppWindow as well. In the QML what you have posted let me know what you would like to achieve with example. There are ways to monitor the changes.

                Aleksey_K 0A Offline
                Aleksey_K 0A Offline
                Aleksey_K 0
                wrote on last edited by
                #7

                @dheerendra https://github.com/penk/qml-livereload - this is what I try to achieve: live QML reload on file change. QQuickView works here without window recreation - just changed content, ApplicationWindow and QQuickWindow forces to recreate Window on every file change which I try to avoid.

                This is where I'm proposing to split the AppWIndows and Content separately.

                Not clear how?

                You change the content qml. It will update your AppWindow as well. In the QML what you have posted let me know what you would like to achieve with example.

                I mention above: edit file and see results in real time on preview application like qmlscene.

                There are ways to monitor the changes.

                What are they?

                1 Reply Last reply
                0
                • L Offline
                  L Offline
                  lduboeuf
                  wrote on last edited by
                  #8

                  it seems that there is no easy way to handle that problem. Did you succeeded since then ?

                  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