Change roles in XmlListModel



  • Hi,

    I want change roles in XmlListModel.
    In the first time, I have this XmlListModel.

    Item {
        property string myQuery:  "/maj/version"
        XmlRole {id: versionDataBaseRole ; name: "version" ; query: "number()"}
    
        XmlListModel {
            id: xmlDocLocal
            source: "file:/myPath/maj.xml"
            query:  myQuery
            roles: [versionDataBaseRole]
        }
    }
    

    This code works. Now, I want use this code :

    Item {
        property string myQuery:  "/maj/version"
        XmlRole {id: versionDataBaseRole ; name: "version" ; query: "number()"}
    
        function updateXmlListModel(){
            xmlDocLocal.query = myQuery
            xmlDocLocal.roles = [versionDataBaseRole]
    
        }
    
        XmlListModel {
            id: xmlDocLocal
            source: "file:/myPath/maj.xml"
        }
    }
    

    where updateXmlListModel()is called by a button. But it doesn't work. I've tested with reload()but it's same issue.

    The goal is to change them based query my needs and therefore don't have many XmlListModel.

    Is it possible ?

    Thank you in advance.


  • Moderators

    @CharlieG Also try setting model's source from the JS function.



  • @p3c0 It's the same problem, but I find the solution.
    To work, rolesproperty must already use :

    Item {
        property string myQuery:  "/maj/version"
        XmlRole {id: versionDataBaseRole ; name: "version" ; query: "number()"}
        XmlRole {id: otherRole ; name: "version" ; query: "number()"}
    
        function updateXmlListModel(){
            xmlDocLocal.query = myQuery
            xmlDocLocal.roles = [versionDataBaseRole]
    
        }
    
        XmlListModel {
            id: xmlDocLocal
            source: "file:/myPath/maj.xml"
            roles :  otherRole
        }
    }
    

    With this code, the function correctly works... Strange , no ?


  • Moderators

    @CharlieG Probably because both roles have same attributes.
    Setting source in the JS function actually worked for me. Here's the test code:

    ListView {
        width: 300;
        height: 200
        model: model
    
        XmlRole { id: role1; name: "title"; query: "title/string()" }
    
        XmlListModel {
            id: model
        }
    
        delegate: Rectangle {
            width: 300
            height: 60
            border.color: "red"
            Text { text: title }
        }
    
        Button {
            anchors.bottom: parent.bottom
            text: "Add"
            onClicked: {
                model.query= "/catalog/book"
                model.source= "xmltest.xml"
                model.roles = [role1]
            }
        }
    }
    

    The test XML file is here. Can you try if this works for you?



  • @p3c0 Yes it works, but...

    Here, an example of my real need :

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.3
    import QtQuick.XmlListModel 2.0
    import QFile 1.0
    
    ColumnLayout {
        id: updateView
        anchors.fill: parent
    
        XmlRole {id: versionFileRole ; name: "year" ; query: "year/number()" }
    
    
        function update(){
            for (var i=0 ; i < xmlDocLocal.count ; i++){
                infoMaj.text += "Saving %1 / %2   -   Year : %3".arg(i+1).arg(xmlDocLocal.count).arg(xmlDocLocal.get(0).year)
            }
        }
    
        XmlListModel {
            id: xmlDocLocal
            query: "/catalog/book"
            source: "file:///myPath/maj.xml"
            roles: [versionFileRole]
        }
    
        Button {
            text: "Add"
            onClicked: {
                //xmlDocLocal.query= "/catalog/book"
                //xmlDocLocal.source= "file:///myPath/maj.xml"
                //xmlDocLocal.roles = [versionFileRole]
                updateView.update()
            }
        }
        ListView {
            id: listView
            height: 300
            width: 300
            model: xmlDocLocal
            delegate: Text{text: year}
        }
    
        Flickable {
            id: flickable
            Layout.fillHeight: true
            Layout.fillWidth: true
    
            TextArea.flickable: TextArea {
                id: infoMaj
                //text: downloader.infoDl
                text: "Test update<br>"
                wrapMode: TextArea.Wrap
                readOnly: true
                textFormat: TextEdit.RichText
            }
    
            ScrollBar.vertical: ScrollBar { }
        }
    }
    

    This view is opened with another button. If you execute update function when you open this view : It works.
    If you want execute this function with "Add" button, it work.
    But if I declare source, queryand rolesin the slot onClicked of "Add" Button, updateView.update() don't display the comment in loop for.

    What do you think about it ?



  • Hi,

    I've found "the problem". In fact, with my first code, I don't expect that XmlListModel is ready.

    Here, an example of a correction available :

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.3
    import QtQuick.XmlListModel 2.0
    
    ColumnLayout {
        id: updateView
        anchors.fill: parent
        
        property int countXml: xmlDocLocal.count
        
        XmlRole {id: nameFileRole ; name: "fileName" ; query: "fileName/string()" }
        XmlRole {id: sizeFileRole ; name: "fileSize" ; query: "fileSize/number()" ; isKey: true}
        XmlRole {id: versionFileRole ; name: "year" ; query: "year/number()" ; isKey: true}
        XmlRole {id: versionDataBaseRole ; name: "version" ; query: "number()"}
        
        function update(){
            infoMaj.text += "Start search of update<br>"
            timer.start()
            
        }
        
        XmlListModel {
            id: xmlDocLocal
        }
        
        Timer {
            id: timer
            interval: 100 ; repeat: true
            onTriggered: {
                if (xmlDocLocal.status === XmlListModel.Ready){
                    infoMaj.text += "updates available : " + xmlDocLocal.count+"<br>"
                    infoMaj.text += "End search of updates<br>"
                    stop()
                }
                
                if (xmlDocLocal.status === XmlListModel.Null){
                    stop()
                    infoMaj.text += "No XML data<br>"
                }
    
                if (xmlDocLocal.status === XmlListModel.Loading)infoMaj.text += "Search available updates<br>"
                
                if (xmlDocLocal.status === XmlListModel.Error){
                    stop()
                    infoMaj.text += xmlDocLocal.errorString()+"<br>"
                }
            }
        }
        
        Button {
            id: btn
            text: "Add - Count : %1".arg(countXml)
            
            onClicked: {
                xmlDocLocal.source = "file:///myPath/maj.xml"
                xmlDocLocal.query = "/catalog/book"
                xmlDocLocal.roles = [versionFileRole]
                updateView.update()
            }
        }
        ListView {
            id: listView
            height: 300
            width: 300
            model: xmlDocLocal
            delegate: Text{text: year}
        }
        
        Flickable {
            id: flickable
            Layout.fillHeight: true
            Layout.fillWidth: true
            
            TextArea.flickable: TextArea {
                id: infoMaj
                text: "Test update<br>"
                wrapMode: TextArea.Wrap
                readOnly: true
                textFormat: TextEdit.RichText
            }
            
            ScrollBar.vertical: ScrollBar { }
        }
    }
    

    Now, it correctly works.


Log in to reply
 

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