Local files

Is it also possible to load local (XML/JSON) files using the XMLHttpRequest. For example a local file named “colors.json” can be loaded using:

  1. xhr.open("GET", "colors.json");

We use this to read a color table and display it as a grid. It is not possible to modify the file from the Qt Quick side. To store data back to the source we would need a small REST based HTTP server or a native Qt Quick extension for file access.

  1. import QtQuick
  2. Rectangle {
  3. width: 360
  4. height: 360
  5. color: '#000'
  6. GridView {
  7. id: view
  8. anchors.fill: parent
  9. cellWidth: width/4
  10. cellHeight: cellWidth
  11. delegate: Rectangle {
  12. width: view.cellWidth
  13. height: view.cellHeight
  14. color: modelData.value
  15. }
  16. }
  17. function request() {
  18. var xhr = new XMLHttpRequest();
  19. xhr.onreadystatechange = function() {
  20. if (xhr.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
  21. print('HEADERS_RECEIVED')
  22. } else if(xhr.readyState === XMLHttpRequest.DONE) {
  23. print('DONE');
  24. var obj = JSON.parse(xhr.responseText.toString());
  25. view.model = obj.colors
  26. }
  27. }
  28. xhr.open("GET", "colors.json");
  29. xhr.send();
  30. }
  31. Component.onCompleted: {
  32. request()
  33. }
  34. }

TIP

For this to work, the QML_XHR_ALLOW_FILE_READ must be set and enabled (set to 1). You can do so by running:

  1. QML_XHR_ALLOW_FILE_READ=1 qml -f localfiles.qml

The issue is when allowing a QML application to read local files through an XMLHttpRequest, hence XHR, this opens up the entire file system for reading, which is a potential security issue. Qt will allow you to read local files only if the environment variable is set, so that this is a concious decision.

Instead of using the XMLHttpRequest it is also possible to use the XmlListModel to access local files.

  1. import QtQuick
  2. import QtQml.XmlListModel
  3. Rectangle {
  4. width: 360
  5. height: 360
  6. color: '#000'
  7. GridView {
  8. id: view
  9. anchors.fill: parent
  10. cellWidth: width/4
  11. cellHeight: cellWidth
  12. model: xmlModel
  13. delegate: Rectangle {
  14. width: view.cellWidth
  15. height: view.cellHeight
  16. color: model.value
  17. Text {
  18. anchors.centerIn: parent
  19. text: model.name
  20. }
  21. }
  22. }
  23. XmlListModel {
  24. id: xmlModel
  25. source: "colors.xml"
  26. query: "/colors/color"
  27. XmlListModelRole { name: 'name'; elementName: 'name' }
  28. XmlListModelRole { name: 'value'; elementName: 'value' }
  29. }
  30. }

With the XmlListModel it is only possible to read XML files and not JSON files.