12-06-2012 09:25 AM
Passing data back and forth between QML and C++ is (relatively) quite a lot of work and complicates apps. A lot of the performance benefit is lost in converting data types (particularly JSON -> QVariant<List/Map> structures -> JavaScript Objects is a bit crazy if you ask me). If you don't need to do much processing of the data then simply accessing the network from JavaScript is much more convenient. If you're accessing a webservice that uses JSON then it's ideal.
Looking at this thread:
With developers claiming this doesn't work and an official BB dev advisor answer with a C++ mixing example, plus total lack of QML only samples I was wondering if this was really broken.
I know it worked fine for others in QtQuick with standard Qt, so it was worth a go trying in Cascades. Took me a couple of hours to get it working due to the lack of a debugger or useful error messages from QML (plus I'd not used the web service before) so I thought I'd share some skeleton code:
function submitPost(postString) {
var request = new XMLHttpRequest();
request.onreadystatechange=function() {
// Need to wait for the DONE state or you'll get errors
if(request.readyState === XMLHttpRequest.DONE) {
if (request.status === 200) {
console.log("Response = " + request.responseText);
// if response is JSON you can parse it
var response = JSON.parse(request.responseText);
// then do something with it here
}
else {
// This is very handy for finding out why your web service won't talk to you
console.log("Status: " + request.status + ", Status Text: " + request.statusText);
}
}
}
// Make sure whatever you post is URI encoded
var encodedString = encodeURIComponent(postString);
// This is for a POST request but GET etc. work fine too
request.open("POST", "https://<your_service_endpoint_here>", true); // only async supported
// You might not need an auth header, or might need to modify - check web service docs
request.setRequestHeader("Authorization", "Bearer " + yourAccessToken);
// Post types other than forms should work fine too but I've not tried
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// Form data is web service dependent - check parameter format
var requestString = "text=" + encodedString;
request.send(requestString);
}
While researching this I discovered that *apparently* adding elements to a ListModel in JavaScript is very slow compared to C++, so you don't want to do it with very large numbers of objects. That said, there are pure QML/JS Twitter clients with decent performance on slow old Symbian devices. I can't confirm how slow because:
"Currently, you can use the profiler only for C++ code. You can't use the profiler for QML or JavaScript code." ![]()
If you've only got fairly small amounts of data to pass around, particularly if it's JSON, then I think this is going to be MUCH easier with minimal performance impact. Being able to do this kind of simple web-connected app entirely in QML was part of the original vision for the language. Have fun playing with it anyway.
Mark
12-06-2012 10:39 AM
12-06-2012 11:11 AM
12-06-2012 11:17 AM
12-06-2012 11:29 AM
12-29-2012 02:26 PM