Reload .qml file runtime



  • Hi, I'm trying to create an application where .qml files are accessible for the user (he can edit / change visual aspect ).

    When the application starts : if users .qml file is present at given path, application must load that file, else it must load the 'same' (default version) file from qrc .

    if (while app is running) user edits the file, application must reload file with changes.

    I have tryed lot of things with Loader/ QQuickPaintedItem etc..

    Finnaly i dit this reusable thing :

    RunTimeLoader.qml

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    
    Item {
        id:customLoader
        Component.onCompleted: {
            initUserFile()
        }
        property url userFileUrl: "file:///C:/Users/user/Documents/QML_CUSTOM_ITEM/Customizable.qml"  // user accessible path/YourComponent.qml
        property url defaultFile: "Customizable.qml"  // default
        property string userFileStr
        property string defaultFileStr
        signal setDefault()
        signal reload()
        onSetDefault:{
            var request = new XMLHttpRequest()
            request.open('GET',defaultFile)
            request.onreadystatechange = function(event) {
                if (request.readyState === XMLHttpRequest.DONE&&request.responseText.length>0) {
                    defaultFileStr = request.responseText;
                    Qt.createQmlObject(defaultFileStr,loaderItem,null)
                }
            }
            request.send()
            delete(request)
        }
        onUserFileStrChanged: {
            if(userFileStr.length>0){
                Qt.createQmlObject(userFileStr,loaderItem,null)
            }
        }
        function initUserFile(){
            var request = new XMLHttpRequest()
            request.open('GET',userFileUrl)
            request.onreadystatechange = function(event) {
                if (request.readyState === XMLHttpRequest.DONE&&request.responseText.length>0) {
                    userFileStr = request.responseText;
                }
            }
            request.send()
            delete(request)
        }
        onReload: {
            for(var i = loaderItem.children.length; i > 0 ; i--) {
                console.log("destroying: " + i)
                loaderItem.children[i-1].destroy()
            }
            initUserFile()
            initTimer.start()
        }
        Timer{
            id:initTimer
            running: true
            interval: 1200
            repeat: false
            onTriggered: {
                if(userFileStr.length>0&&loaderItem.children.length<1){
                    Qt.createQmlObject(userFileStr,loaderItem,null)
                }
                else if (loaderItem.children.length<1){
                    setDefault()
                }
            }
        }
        Button{
            text: "Reload"
            onClicked: {
                reload()
            }
        }
        Item{
            id:loaderItem
            anchors.fill:  parent
        }
    }
    

    To use this : just change 'userFileUrl' and 'defaultFile'

    then in your main.qml

    RunTimeLoader{
       height:parent.height
       width: parent.width
    }
    

    Please tell me if you know better way to implement this dynamic reloading behavior.


  • Qt Champions 2017

    It is not a good idea to present the qml file itself for the user to edit. You can provide some property file where user can edit the file and reload your app. You can do this easily with QML and C++ integration.



  • @dheerendra I thought it was a good idea :p
    But seriously, when i'm sayin 'user' this is just for the exemple... i'm trying to load a *.qml file from 'standartPath, like c:\Documents\etc....' runtime.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.