Unsolved JS Async Function in QML
-
I'm wondering if it is possible to use an async function in QML.
Like this:async function additem(clientName){ myListModel.append({name:clientName}); }
Instead of using this:
function additem(clientName){ myListModel.append({name:clientName}); }
I've tried it and I get a syntax error:
Expected token
:'` and couldn't find any documentation about QML supporting JavaScript "async function".
any idea why is that? or probably if there is any other way to do async in JS which can be used in QML?Note: I want to append data to my ListModel and I want to see it as its progress and I don't want whole application freeze until whole data appended to the model.
Appreciate your time.
-
@Bernard-Rouhi said in JS Async Function in QML:
I don't want whole application freeze until whole data appended to the model
when your whole application freezes by just appending a single value to the model you must have done something wrong in your implementation.
Even when you make this function asyncronous the application would freeze once it gets added anyway.
So whats the actual problem by calling the method directly? -
Hi,
you can't write 'async function' in qml.
What you need is QML "workerScript" to do your list initialisation in separated thread.WorkerScript doc : http://doc.qt.io/qt-4.8/qml-workerscript.html
LA
-
@raven-worx said in JS Async Function in QML:
@Bernard-Rouhi said in JS Async Function in QML:
I don't want whole application freeze until whole data appended to the model
when your whole application freezes by just appending a single value to the model you must have done something wrong in your implementation.
Even when you make this function asyncronous the application would freeze once it gets added anyway.
So whats the actual problem by calling the method directly?Thank you for the reply,
okay, I have a ListViewListView { id: myList anchors.fill: parent model: myList delegate: myDelegate }
and in my ListModel I have ListElement that contain an Array, and that Array contains multiple ListElement, one of the data is something like this:
ListModel { id: myList ListElement{ name: "Bernard" card: 100256 books:[ {value:"025684"}, {value:"568956"}, {value:"879256"}, {value:"125793"}, {value:"486257"}] } }
you might wonder why list of ListElement for books, well, it's because ListElement and ListModel doesn't support simple Array (it's not documented if any), they only mentioned string and integer. so I have to use ListElement in such way.
however, next I want to add the books to my ComboBox's model which is under Delegate:Component { id: myDelegate Rectangle { id: rowID width: 300 height: 40 color: "#323232" border.color: "white" Row { anchors.fill: parent anchors.leftMargin: 10 anchors.rightMargin: 10 Text{ id: nameID text: name font.pixelSize: 12 width: 50 wrapMode: Text.WrapAnywhere color: "white" } Text{ text: "out:" font.pixelSize: 12 color: "white" } ComboBox{ id: booksID height: 20 width: 50 model: books } } } }
as you can see I'm feeding the name to Text (id: nameID) but I want to add the books to ComboBox model (id: booksID) too, which it doesn't do it.
so the easiest way that I figured out is by adding onCompleted to ComboBox under Delegate and handling it like so:
ComboBox{ id: booksID height: 20 width: 50 model: [] Component.onCompleted:{ booksID.model = update_books(books); function update_books(data) { var booksArray = Array(); for (var n=0; n < data.count ;n++){ booksArray.push(data.get(n).value); } return booksArray; } } }
well, I know I shouldn't do that in Delegate, cause Delegate doesn't keep them and it should be done in Model, but I couldn't find a way to feed the books to ComboBox's model and I thought of doing async function to keep the performance, but not document regarding that too.
Hope that is clear my intention of using Async Function, but feel free to correct me if you find any process that I'm doing wrong, thanks for your time.
-
@LeLev said in JS Async Function in QML:
Hi,
you can't write 'async function' in qml.
What you need is QML "workerScript" to do your list initialisation in separated thread.WorkerScript doc : http://doc.qt.io/qt-4.8/qml-workerscript.html
LA
Hi @LeLev
Thanks for the reply, yeah, I try using that, but since it separates itself from QML Libraries and I need ListView's id to append ListElement to it, it doesn't look alike workable in my case.
Please look at my reply to Raven-worx question, I did explain why I need the async function. hope that gives a clear idea of my question. -
Take a look on this exemple maybe... http://doc.qt.io/qt-5/qtquick-threading-example.html
I hope it helps you.
LA -
@Bernard-Rouhi I believe you should be able to assign the books to the ComboBox model using modelData.
Like so:
ComboBox{
id: booksID
model: modelData.books
}Also, you can use a plain JavaScript array for a model. Works fine. That's all I ever use, for all my models — arrays of strings, arrays of objects, etc.
-
@LeLev said in JS Async Function in QML:
Take a look on this exemple maybe... http://doc.qt.io/qt-5/qtquick-threading-example.html
I hope it helps you.
LAThanks for the reply, I found a solution by adding
textRole
to ComBox like so:ComboBox{ id: booksID height: 20 width: 50 model: books textRole: "value" }
but still, I'm looking for asyncing my javascript function, I could think of an existing similar idea called Ajax for web development in Restful API, but I want to do the same thing in QML with javascript functions.
-
@wpurvis said in JS Async Function in QML:
@Bernard-Rouhi I believe you should be able to assign the books to the ComboBox model using modelData.
Like so:
ComboBox{
id: booksID
model: modelData.books
}Also, you can use a plain JavaScript array for a model. Works fine. That's all I ever use, for all my models — arrays of strings, arrays of objects, etc.
Hi @wpurvis , thanks for the reply, I didn't get the modelData, you mean ListModel id?
also again I'm looking for a way to async my javascript functions, something similar to Ajax in Restful API but in QML without Restful API of course. -
@LeLev said in JS Async Function in QML:
Take a look on this exemple maybe... http://doc.qt.io/qt-5/qtquick-threading-example.html
I hope it helps you.
LAHi @LeLev , thanks for the reply, yeah, I think the solution is to handle it on multi threads, I didn't get it at first but now I go through the documentations that make lots of sense.
-
@Bernard-Rouhi said in JS Async Function in QML:
I didn't get the modelData, you mean ListModel id?
No, I mean modelData, as described here.
It's an alternative way for the delegate to refer to its model data, i.e., an alternative to using named roles.
E.g., in your example, your delegate could refer to modelData.name, modelData.card, etc., and you should be able to set the ComboBox model to modelData.books. That's assuming you wanted to just use a plain JavaScript array of book values, rather than creating a bunch of ListElement entries.