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.
-
@p3c0 It's the same problem, but I find the solution.
To work,roles
property 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 ?
-
@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?
-
@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 declaresource
,query
androles
in the slotonClicked
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.