我前一段时间在我的博客里写了一篇文章“如何在QML应用中读写文件”,那篇文章是介绍如何使用C++来读取文件的。那种方法是一个比较通用的方法。但是对于有些应用来说,我们可以通过配置JSON来创建我们的UI,或者对不同的平台进行配置,而不用写一个单独的设置文件来做这件事。那么我们如何不需要通过C++的方法来读取Json文件呢?
我们可以使用我们的SDK创建一个最基本的QML应用。为了能够读取Json文件,我们创建一个叫做“jsonparser.js”的文件:
/* Based on:
* JSONListModel - a QML ListModel with JSON and JSONPath support
*
* Copyright (c) 2012 Romain Pokrzywka (KDAB) (romain@kdab.com)
* Licensed under the MIT licence
* (http://opensource.org/licenses/mit-license.php)
* https://github.com/s3u/JSONPath
*/
//Qt.include("jsonpath.js")
function readJsonFile(source, callback) {
var xhr = new XMLHttpRequest;
xhr.open("GET", source);
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
var doc = xhr.responseText;
// console.log("JSON: " + json)
var json = JSON.parse(doc);
callback.update(json);
}
}
xhr.send();
}
我们通过XMLHttpRequest来完成本地文件的请求工作,并使用callback中的update来传人到QML文件中进行解析。为了能够更加方便地解析我们得到的Json文件,我们使用了
https://github.com/s3u/JSONPath
里提供的库。我们可以把“jsonpath.js”下载到我们项目的根目录下,以方便使用。具体的使用方法可以在网上查看。
为了显示我们的JSO数据,我们对我们的Main.qml进行了修改:
import QtQuick 2.0
import Ubuntu.Components 1.1
import "jsonparser.js" as API
import "jsonpath.js" as JSONPath
/*!
\brief MainView with a Label and Button elements.
*/
MainView {
id: main
// objectName for functional testing purposes (autopilot-qt5)
objectName: "mainView"
// Note! applicationName needs to match the "name" field of the click manifest
applicationName: "readjsonfile.liu-xiao-guo"
/*
This property enables the application to change orientation
when the device is rotated. The default is false.
*/
//automaticOrientation: true
// Removes the old toolbar and enables new features of the new header.
useDeprecatedToolbar: false
width: units.gu(60)
height: units.gu(85)
function update(json) {
console.log("it is called in update!");
// we can start to interpret the returned json
var authors = JSONPath.jsonPath(json, "$.store.book[*].author");
console.log("length: " + authors.length);
for (var i in authors ) {
console.log("author[" + i +"] " + authors[i]);
mymodel.append( { "content": authors[i],
"type": "Authors"
});
}
// Get all of the books
var books = JSONPath.jsonPath(json, "$.store.book[*].title");
console.log("length: " + books.length);
for (var j in books ) {
console.log("author[" + j +"] " + books[j]);
mymodel.append( { "content": books[j],
"type": "Books"
});
}
}
Page {
id: mainPage
title: i18n.tr("Read Json File")
ListModel {
id: mymodel
}
Component {
id: sectionHeading
Rectangle {
width: mainPage.width
height: childrenRect.height
color: "lightsteelblue"
Text {
text: section
font.bold: true
font.pixelSize: 20
}
}
}
ListView {
id: listview
anchors.fill: parent
model: mymodel
delegate: Text {
text: content
}
section.property: "type"
section.criteria: ViewSection.FullString
section.delegate: sectionHeading
}
Component.onCompleted: {
console.log("Start to read JSON file");
API.readJsonFile("sample.json", main)
}
}
}
为了完成我们的实验,我们也创建了一个sample.json文件。内容如下:
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
运行我们的应用,我们应用显示的结果如下:
