Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. JS Async Function in QML
Forum Updated to NodeBB v4.3 + New Features

JS Async Function in QML

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
11 Posts 4 Posters 11.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Bernard RouhiB Bernard Rouhi

    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.

    raven-worxR Offline
    raven-worxR Offline
    raven-worx
    Moderators
    wrote on last edited by
    #2

    @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?

    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
    If you have a question please use the forum so others can benefit from the solution in the future

    Bernard RouhiB 1 Reply Last reply
    0
    • ODБOïO Offline
      ODБOïO Offline
      ODБOï
      wrote on last edited by
      #3

      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

      Bernard RouhiB 1 Reply Last reply
      1
      • raven-worxR raven-worx

        @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?

        Bernard RouhiB Offline
        Bernard RouhiB Offline
        Bernard Rouhi
        wrote on last edited by
        #4

        @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 ListView

        ListView {
            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.

        W 1 Reply Last reply
        0
        • ODБOïO ODБOï

          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

          Bernard RouhiB Offline
          Bernard RouhiB Offline
          Bernard Rouhi
          wrote on last edited by
          #5

          @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.

          1 Reply Last reply
          0
          • ODБOïO Offline
            ODБOïO Offline
            ODБOï
            wrote on last edited by
            #6

            Take a look on this exemple maybe... http://doc.qt.io/qt-5/qtquick-threading-example.html

            I hope it helps you.
            LA

            Bernard RouhiB 2 Replies Last reply
            1
            • Bernard RouhiB Bernard Rouhi

              @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 ListView

              ListView {
                  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.

              W Offline
              W Offline
              wpurvis
              wrote on last edited by
              #7

              @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.

              Bernard RouhiB 1 Reply Last reply
              0
              • ODБOïO ODБOï

                Take a look on this exemple maybe... http://doc.qt.io/qt-5/qtquick-threading-example.html

                I hope it helps you.
                LA

                Bernard RouhiB Offline
                Bernard RouhiB Offline
                Bernard Rouhi
                wrote on last edited by
                #8

                @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.
                LA

                Thanks 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.

                1 Reply Last reply
                0
                • W wpurvis

                  @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.

                  Bernard RouhiB Offline
                  Bernard RouhiB Offline
                  Bernard Rouhi
                  wrote on last edited by
                  #9

                  @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.

                  W 1 Reply Last reply
                  0
                  • ODБOïO ODБOï

                    Take a look on this exemple maybe... http://doc.qt.io/qt-5/qtquick-threading-example.html

                    I hope it helps you.
                    LA

                    Bernard RouhiB Offline
                    Bernard RouhiB Offline
                    Bernard Rouhi
                    wrote on last edited by
                    #10

                    @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.
                    LA

                    Hi @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.

                    1 Reply Last reply
                    1
                    • Bernard RouhiB Bernard Rouhi

                      @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.

                      W Offline
                      W Offline
                      wpurvis
                      wrote on last edited by
                      #11

                      @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.

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved