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. Filling a listView model in seperate Thread .

Filling a listView model in seperate Thread .

Scheduled Pinned Locked Moved QML and Qt Quick
10 Posts 5 Posters 7.4k 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.
  • R Offline
    R Offline
    rafaelSorel
    wrote on last edited by
    #1

    Hi guys,

    I am facing a problem using QML and C++.

    In fact I'm creating a ListView model when starting the main program and a generator of a listView to generate that list from QML(key press or any other event..):

    @
    myModel model;
    Generator generator(&model);

    ctxt->setContextProperty("myModel", &model);
    ctxt->setContextProperty("generator", &generator);
    view.setSource(QUrl("qrc:///qmlFolder/mainView.qml"));
    

    @

    Then when the application starts I use a key event to show the listView:
    @
    if (event.key === Qt.Key_Return)
    {
    generator.generate("All");
    }
    @
    And the C++ part to generate the list is :
    @
    void Generator::generate()
    {

            for(int i = 0 ; i < N ; i++)
            {
                m_model->addModelElements("str1", "str2");
            }
    

    }
    @

    Every thing works perfect, But sometimes when the list is tooo long the annimated QML background freezes until the listView model is filled, so I have created a separete thread to handle the fill listView part and then post a signal to the main GUI thread. So in the model Class I Instantiate a New Thread and when receiving the user press button to call generate I fill ListView on the created thread. and then I have got this error :

    @
    [ 0x7f1a8377e700 ] Generate ChannelList
    QObject::connect: Cannot queue arguments of type 'QQmlChangeSet'
    (Make sure 'QQmlChangeSet' is registered using qRegisterMetaType().)
    @

    It is like QT does not like that I generate the ListView model from another thread and call the m_model->addModelElements() from another thread then the GUI thread ?

    Any Ideas Guys ??

    1 Reply Last reply
    0
    • A Offline
      A Offline
      andreyc
      wrote on last edited by
      #2

      See "this thread":http://qt-project.org/forums/viewthread/28884 for possible solution.

      1 Reply Last reply
      0
      • dheerendraD Offline
        dheerendraD Offline
        dheerendra
        Qt Champions 2022
        wrote on last edited by
        #3

        I suspect some UI components you are trying to access inside the worker thread. Can you post your complete simple example ? This will surely help.

        Dheerendra
        @Community Service
        Certified Qt Specialist
        http://www.pthinks.com

        1 Reply Last reply
        0
        • R Offline
          R Offline
          rafaelSorel
          wrote on last edited by
          #4

          :andreyc : I have already seen that post and unfortunately the solution is to post a signal from the QML to the GUI thread which turn to be the same acting thread, so the freeze problem will remains.

          :Dhreerendra : Yes indeed I'm trying to access to my model which is a ListView from a worker thread :
          @
          ListView {
          id: channelList
          anchors.left: channelScrollZone.left
          anchors.right: channelScrollZone.right
          anchors.top: channelScrollZone.top
          anchors.bottom: channelScrollZone.bottom

              model: myModel
              highlight: highlight
              highlightFollowsCurrentItem: false
              focus: true
              clip: true
              keyNavigationWraps: true
              interactive: false
              delegate: channelComponent
          }
          

          @

          As I have understand it is not possible to modify the GUI from a worker thread, But it has to be a solution to avoid the freeze when loading a big ListView.

          Thx

          1 Reply Last reply
          0
          • dheerendraD Offline
            dheerendraD Offline
            dheerendra
            Qt Champions 2022
            wrote on last edited by
            #5

            Yes. You are right. We need to do something like yours idea to solve the freeze issue. Here the issue is that you may be modifying/accessing something from worker thread which is not allowed. Is the model is your custom class ? Are you creating the thread inside your model class to just fill only data ? Which thread is creating the myModel object ?

            Dheerendra
            @Community Service
            Certified Qt Specialist
            http://www.pthinks.com

            1 Reply Last reply
            0
            • R Offline
              R Offline
              rafaelSorel
              wrote on last edited by
              #6

              The thread of the model class is created when declaring the class in the main which means that the thread that create the myModel Object is the GUI thread so that it can interact with the model in the QML scene. And yes the worker thread is created when the myModel Class is instantiated by the QuickView. So every time that the QML scene sends a request to update the ListView, I just pass the information to the worker thread, but indeed it is not possible to share the myModel Object with another thread to fill it . I don't know how a worker thread could possibely fill a QML listView model ?

              1 Reply Last reply
              0
              • R Offline
                R Offline
                rafaelSorel
                wrote on last edited by
                #7

                Well I have succeeded to perform the parsing on another thread. the thing is despite of this message :
                @
                QObject::connect: Cannot queue arguments of type 'QQmlChangeSet'
                (Make sure 'QQmlChangeSet' is registered using qRegisterMetaType().)
                @

                That I don't know what it is ? I have succeded to perform the model fills on another thread, the only thing that the QT does not accept is to make the model refresh in the different thread !
                Meaning that you need to call those two functions from the Gui thread other wise it does not work.
                @
                beginResetModel();
                endResetModel();
                @

                The final thing is that those two :
                @
                beginResetModel();
                endResetModel();
                @

                took about 200ms to excute which results on a noticable freeze on the screen .
                Have you guys an other way to update the ListView without using those two functions for refreshing the list ?

                1 Reply Last reply
                0
                • p3c0P Offline
                  p3c0P Offline
                  p3c0
                  Moderators
                  wrote on last edited by
                  #8

                  Hi,

                  bq. But sometimes when the list is tooo long the annimated QML background freezes until the listView model is filled, ...

                  Another idea would be to use fetchMore and canFetchMore functions of QAbstractListModel and load items as required and not all at a time.

                  157

                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    chrisadams
                    wrote on last edited by
                    #9

                    Populating a model in a separate thread is one of the main reasons that the WorkerScript type exists in QML.

                    See http://qt-project.org/doc/qt-5/qml-qtquick-workerscript.html and http://qt-project.org/doc/qt-5/qtquick-threading-example.html#threaded-listmodel for more information.

                    Cheers,
                    Chris.

                    1 Reply Last reply
                    0
                    • R Offline
                      R Offline
                      rafaelSorel
                      wrote on last edited by
                      #10

                      Thanks for your response. But worker script are only a .js script which means that there is no interaction with C++ components. It is here only to perform some local processing on the QtQuick context.

                      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