Consumiendo JSON con QML
Hace un tiempo escribí sobre lo fácil que es consumir XML con QML, hoy le toca el turno a JSON, consumir JSON con QML requiere un poco mas de trabajo comparado con XML, pero no mucho mas.
Pasemos al código, lo primero que haremos sera crear un archivo data.js que contendrá la lógica que poblara al Model con los datos, para este ejemplo vamos a usar el API de Wikileaks para mostrar un listado con los últimos cables liberados, lo siguiente es agregar el ListModel, el Delegate cuyo código esta al final y no necesita muchos comentarios, el ListView que mostrara los datos y vamos a disparar la función getLatestCables() cuando la view se haya cargado.
main.qml
import QtQuick 1.0
import "data.js" as Data
Rectangle {
width:360
height:640
Component.onCompleted:Data.getLatestCables();
ListModel {
id:cablesModel
}
CablesDelegate {
id:cablesDelegate
}
Item {
id:cablesList
anchors.fill:parent
ListView {
model:cablesModel
delegate:cablesDelegate
anchors.fill:parent
}
}
}
La magia que no es mucha, pasa aquí, esto es simple y puro JavaScript, utilizaremos un XMLHttpRequest para acceder al feed con los datos, luego lo parseamos e iremos agregando uno a uno los datos al Model.
data.js
function getLatestCables(){
var xhr = new XMLHttpRequest;
xhr.open("GET", "http://api.leakfeed.com/v1/cables/latest.json");
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
var a = JSON.parse(xhr.responseText);
for (var c in a) {
var i = a[c];
cablesModel.append({identifier: i.identifier, classification: i.classification, office: i.office, subject: i.subject});
}
}
}
xhr.send();
}
CablesDelegate.qml
import QtQuick 1.0
Component {
Rectangle {
border.color:"#b7b7b7"
border.width:1
width:parent.width
height:cableIdentifier.height + cableOffice.height + cableClass.height + cableSubject.height + 10
color:"#fff"
Item {
width:parent.width
height:parent.height
Grid {
rows:4
width:parent.width
anchors.verticalCenter:parent.verticalCenter
anchors.left:parent.left
anchors.leftMargin:5
anchors.right:parent.right
anchors.rightMargin:5
Text {
id:cableIdentifier
text:identifier
font.bold:true
font.pixelSize:18
smooth:true
color:"#333"
}
Text {
id:cableOffice
color:"#0076A3"
text:office
font.pixelSize:18
font.bold:true
smooth:true
}
Text {
id:cableClass
color:"#aa1317"
text:classification
font.pixelSize:16
font.bold:true
smooth:true
}
Text {
id:cableSubject
text:subject
font.pixelSize: 14
wrapMode:Text.WrapAtWordBoundaryOrAnywhere
width:parent.width
smooth:true
color:"#333"
}
}
}
}
}
Si todo sale bien, al correr la demo deberíamos obtener como resultado algo parecido a los que se ve en la siguiente imagen.

3 responses