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. Model for a list of large data in QML
Forum Updated to NodeBB v4.3 + New Features

Model for a list of large data in QML

Scheduled Pinned Locked Moved Solved QML and Qt Quick
21 Posts 5 Posters 7.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.
  • dheerendraD dheerendra

    QAbstractListModel at the back with different role names to used. Best thing is not to load the entire model with 40K or 100K rows. You load number of elements which can be seen in the UI. May be you can implement some kind sliding window. Number of elements in View and Number elements in Model should be around 200 or 300. If any change in those values, you emit dataChanged(..). Otherwise don't worry. If the user scrolls or swipes, you refill the model by fetching the data from DB.
    In summary - Avoid loading the entire DB into model. It will be very slow. Load the model with required set of data.

    JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by
    #3

    @dheerendra
    OOI, why do you recommend QAbstractListModel and not one of the dedicated SQL ones, like say QSqlQueryModel, with an attached QTableView, or similar?

    sierdzioS 1 Reply Last reply
    0
    • KillerSmathK Offline
      KillerSmathK Offline
      KillerSmath
      wrote on last edited by KillerSmath
      #4

      Hi there, again.
      My suggestions:

      • You can implement a custom model inheriting fromQAbstractItemModeland implementing by yourself how the model should storage and recover the information.
      • You can implement a class working in anotherQthreadto check if any database row has been updated and case some update has needed, you can change (in ui main thread) the model data and it will change the view.
      • About expansive item, you can implement this funcionality on delegate of your table using Shape-Shifting Delegates.

      I gonna to dispose a good eBook about Qt and QML below this post, i believe it can agregate your knowledge.
      I wish a good coding.

      Read More:
      QAbstractItemModel
      Qt5 Cadaques Book

      @Computer Science Student - Brazil
      Web Developer and Researcher
      “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

      1 Reply Last reply
      2
      • JonBJ JonB

        @dheerendra
        OOI, why do you recommend QAbstractListModel and not one of the dedicated SQL ones, like say QSqlQueryModel, with an attached QTableView, or similar?

        sierdzioS Offline
        sierdzioS Offline
        sierdzio
        Moderators
        wrote on last edited by
        #5

        @JonB said in Model for a list of large data in QML:

        @dheerendra
        OOI, why do you recommend QAbstractListModel and not one of the dedicated SQL ones, like say QSqlQueryModel, with an attached QTableView, or similar?

        QTableView is a widget, and you are rather interested in QML components. And you mentioned you want to display a list, not a table.

        As for the model, I think QSqlQueryModel should also work OK.

        (Z(:^

        JonBJ 1 Reply Last reply
        0
        • sierdzioS sierdzio

          @JonB said in Model for a list of large data in QML:

          @dheerendra
          OOI, why do you recommend QAbstractListModel and not one of the dedicated SQL ones, like say QSqlQueryModel, with an attached QTableView, or similar?

          QTableView is a widget, and you are rather interested in QML components. And you mentioned you want to display a list, not a table.

          As for the model, I think QSqlQueryModel should also work OK.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #6

          @sierdzio

          And you mentioned you want to display a list, not a table.

          I am not the OP! And the OP actually wrote:

          to display a list/table of data in QML.

          Yes, sorry about the QTableView question, I forget I am not a QML-er!

          I really only meant about why not specifically QSqlQueryModel for all the SQL support, rather than a plain QAbstractListModel derivation, where the OP would have to write all the SQL support code?

          sierdzioS 1 Reply Last reply
          0
          • JonBJ JonB

            @sierdzio

            And you mentioned you want to display a list, not a table.

            I am not the OP! And the OP actually wrote:

            to display a list/table of data in QML.

            Yes, sorry about the QTableView question, I forget I am not a QML-er!

            I really only meant about why not specifically QSqlQueryModel for all the SQL support, rather than a plain QAbstractListModel derivation, where the OP would have to write all the SQL support code?

            sierdzioS Offline
            sierdzioS Offline
            sierdzio
            Moderators
            wrote on last edited by
            #7

            @JonB said in Model for a list of large data in QML:

            @sierdzio

            And you mentioned you want to display a list, not a table.

            I am not the OP!

            Whoops, sorry :-)

            (Z(:^

            1 Reply Last reply
            0
            • X Offline
              X Offline
              XDePedro
              wrote on last edited by
              #8

              Thank you all for your comments.

              I have not strict limitation about what kind of list or table to use. But I think a TableView will not let me to implement things like the expandable/collapsable details or adding "fancy" things. So I think I should go for a ListView instead of a TableView.

              I have actually implemented kind of a test app using QSqlQueryModel but when the data changes I call setQuery again...this I think is very slow and the control is re-filled so I lost the location where the user was in the list. Also with these approach I don't know how to keep data that is not coming from the DB...for instance the status of a row (expanded/collapsed).

              JonBJ 1 Reply Last reply
              0
              • X XDePedro

                Thank you all for your comments.

                I have not strict limitation about what kind of list or table to use. But I think a TableView will not let me to implement things like the expandable/collapsable details or adding "fancy" things. So I think I should go for a ListView instead of a TableView.

                I have actually implemented kind of a test app using QSqlQueryModel but when the data changes I call setQuery again...this I think is very slow and the control is re-filled so I lost the location where the user was in the list. Also with these approach I don't know how to keep data that is not coming from the DB...for instance the status of a row (expanded/collapsed).

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by
                #9

                @XDePedro said in Model for a list of large data in QML:

                I have actually implemented kind of a test app using QSqlQueryModel but when the data changes I call setQuery again...this I think is very slow and the control is re-filled

                Yes, this is a big problem for you to think through. With your data:

                a. Do you only want to re-fetch incrementally this values which have been added?
                b. When you do re-fetch, do you wish all the old, existing rows to still be in the model/view, or do you want those to be removed and only the new stuff now shown?

                so I lost the location where the user was in the list

                This one is a minor point: if necessary, note the position in the list (via something unique in the data, e.g. a primary key) and restore after re-populate.

                X 1 Reply Last reply
                0
                • sierdzioS Offline
                  sierdzioS Offline
                  sierdzio
                  Moderators
                  wrote on last edited by
                  #10

                  My - perhaps crazy - thought: use the QSql model to read your DB (side note: perhaps some other db would work better, like psql or mariadb. SQLite tends to be rather slower than others), preferably in a separate thread. When DB data changes, emit a signal to notify the upper layers. Then set up another model, like QAbstractListModel or model proxy which will:

                  • remember which list elements were expanded/ collapsed (btw. to display these list items, I'd recommend implementing some custom QML delegate). You can simply extend the data object you get from SQL model and add a boolean variable to mark which items were expanded
                  • present the "last read" info from your DB. So, while your SQL model will be busy reading new data (after some background data change), your proxy model will still hold and display old data. Once all is read, it will get the signal from SQL model and update itself

                  (Z(:^

                  JonBJ 1 Reply Last reply
                  2
                  • sierdzioS sierdzio

                    My - perhaps crazy - thought: use the QSql model to read your DB (side note: perhaps some other db would work better, like psql or mariadb. SQLite tends to be rather slower than others), preferably in a separate thread. When DB data changes, emit a signal to notify the upper layers. Then set up another model, like QAbstractListModel or model proxy which will:

                    • remember which list elements were expanded/ collapsed (btw. to display these list items, I'd recommend implementing some custom QML delegate). You can simply extend the data object you get from SQL model and add a boolean variable to mark which items were expanded
                    • present the "last read" info from your DB. So, while your SQL model will be busy reading new data (after some background data change), your proxy model will still hold and display old data. Once all is read, it will get the signal from SQL model and update itself
                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #11

                    @sierdzio
                    This sounds reasonable to me.
                    The only thing is: given the OP's "crazy" ( ;-) ) requirement to have "at least 100k" items in his lists, it sounds like the approach will require yet another copy of all the data rows! :(

                    sierdzioS X 2 Replies Last reply
                    0
                    • JonBJ JonB

                      @sierdzio
                      This sounds reasonable to me.
                      The only thing is: given the OP's "crazy" ( ;-) ) requirement to have "at least 100k" items in his lists, it sounds like the approach will require yet another copy of all the data rows! :(

                      sierdzioS Offline
                      sierdzioS Offline
                      sierdzio
                      Moderators
                      wrote on last edited by
                      #12

                      @JonB said in Model for a list of large data in QML:

                      @sierdzio
                      This sounds reasonable to me.
                      The only thing is: given the OP's "crazy" ( ;-) ) requirement to have "at least 100k" items in his lists, it sounds like the approach will require yet another copy of all the data rows! :(

                      That's why it will be crucial to implement @dheerendra's idea of windowed view. Or at the very least use lazy initialization (canFetchMore() and fetchMore()).

                      (Z(:^

                      JonBJ 1 Reply Last reply
                      0
                      • sierdzioS sierdzio

                        @JonB said in Model for a list of large data in QML:

                        @sierdzio
                        This sounds reasonable to me.
                        The only thing is: given the OP's "crazy" ( ;-) ) requirement to have "at least 100k" items in his lists, it sounds like the approach will require yet another copy of all the data rows! :(

                        That's why it will be crucial to implement @dheerendra's idea of windowed view. Or at the very least use lazy initialization (canFetchMore() and fetchMore()).

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by
                        #13

                        @sierdzio
                        Yes, but independent of whether lazy reading is involved, my comment was that OP will have one ("large") list of rows in his QSqlQueryModel and another ("large", potentially very similar) list in his new QAbstractListModel. It may be inevitable, but it was just an observation.

                        1 Reply Last reply
                        0
                        • sierdzioS Offline
                          sierdzioS Offline
                          sierdzio
                          Moderators
                          wrote on last edited by
                          #14

                          Oh, right, that's true.

                          (Z(:^

                          1 Reply Last reply
                          0
                          • JonBJ JonB

                            @XDePedro said in Model for a list of large data in QML:

                            I have actually implemented kind of a test app using QSqlQueryModel but when the data changes I call setQuery again...this I think is very slow and the control is re-filled

                            Yes, this is a big problem for you to think through. With your data:

                            a. Do you only want to re-fetch incrementally this values which have been added?
                            b. When you do re-fetch, do you wish all the old, existing rows to still be in the model/view, or do you want those to be removed and only the new stuff now shown?

                            so I lost the location where the user was in the list

                            This one is a minor point: if necessary, note the position in the list (via something unique in the data, e.g. a primary key) and restore after re-populate.

                            X Offline
                            X Offline
                            XDePedro
                            wrote on last edited by
                            #15

                            @JonB
                            It might be a minor problem but I am still trying to solve it. I have to signals: beginDBChange and endDBChange. I use the first one to store the index of the selected item and then the second one to set it as a current item index. It works but I still have some annoying scrollings to set the item at the beginning or the end of the table. I would like this to be completely transparent to the user.

                            JonBJ 1 Reply Last reply
                            0
                            • JonBJ JonB

                              @sierdzio
                              This sounds reasonable to me.
                              The only thing is: given the OP's "crazy" ( ;-) ) requirement to have "at least 100k" items in his lists, it sounds like the approach will require yet another copy of all the data rows! :(

                              X Offline
                              X Offline
                              XDePedro
                              wrote on last edited by
                              #16

                              @JonB

                              Sounds crazy :P but I think I'll give it a try.

                              Does someone know if the QSqlQuery use any kind of lazy initialization? or when you execute a query the data is being loaded regardless nobody ask for it??

                              sierdzioS 1 Reply Last reply
                              0
                              • X XDePedro

                                @JonB
                                It might be a minor problem but I am still trying to solve it. I have to signals: beginDBChange and endDBChange. I use the first one to store the index of the selected item and then the second one to set it as a current item index. It works but I still have some annoying scrollings to set the item at the beginning or the end of the table. I would like this to be completely transparent to the user.

                                JonBJ Offline
                                JonBJ Offline
                                JonB
                                wrote on last edited by
                                #17

                                @XDePedro
                                Not an area I know about; can only make possible suggestion:

                                If you really cannot solve that by (somehow) pre-scrolling before new list is shown --- because list is being completely repopulated from new data --- ISTM you will have to come up with whatever solution to only append new rows to visual list without complete reset/redraw, whatever that might involve.

                                1 Reply Last reply
                                0
                                • X XDePedro

                                  @JonB

                                  Sounds crazy :P but I think I'll give it a try.

                                  Does someone know if the QSqlQuery use any kind of lazy initialization? or when you execute a query the data is being loaded regardless nobody ask for it??

                                  sierdzioS Offline
                                  sierdzioS Offline
                                  sierdzio
                                  Moderators
                                  wrote on last edited by
                                  #18

                                  @XDePedro said in Model for a list of large data in QML:

                                  Does someone know if the QSqlQuery use any kind of lazy initialization?

                                  Like all Q*Model classes, there is canFetchMore() and fetchMore().

                                  Whether any further laziness is implemented in the actual loading - I don't know.

                                  (Z(:^

                                  JonBJ 1 Reply Last reply
                                  0
                                  • sierdzioS sierdzio

                                    @XDePedro said in Model for a list of large data in QML:

                                    Does someone know if the QSqlQuery use any kind of lazy initialization?

                                    Like all Q*Model classes, there is canFetchMore() and fetchMore().

                                    Whether any further laziness is implemented in the actual loading - I don't know.

                                    JonBJ Offline
                                    JonBJ Offline
                                    JonB
                                    wrote on last edited by JonB
                                    #19

                                    @sierdzio
                                    I have been wondering about just this for QSqlQueryModel etc. for a while now!

                                    Do we know how the "fetchMore" is actually implemented? I presume this is a driver implementation (QMYSQL)? For example, does it actually use a SQL CURSOR on a still on-going query (I hope not! but maybe it does), does it simply mean it fetches another packet from some complete SQL resultset, or what??

                                    This makes a huge difference to how I might implement efficiency in my SQL code....

                                    1 Reply Last reply
                                    0
                                    • sierdzioS Offline
                                      sierdzioS Offline
                                      sierdzio
                                      Moderators
                                      wrote on last edited by
                                      #20

                                      Feel free to analyze the code here.

                                      (Z(:^

                                      JonBJ 1 Reply Last reply
                                      2
                                      • sierdzioS sierdzio

                                        Feel free to analyze the code here.

                                        JonBJ Offline
                                        JonBJ Offline
                                        JonB
                                        wrote on last edited by JonB
                                        #21

                                        @sierdzio
                                        Thanks for that!

                                        Unfortunately for me, I do all my work in PyQt. That means I can't step through the code in debugger to follow everything, as I would if I used C++ and had the sources.

                                        Although the page's hyperlinks are good, they're not nearly nearly the same as following through stepping.

                                        A brief look doesn't tell me much. Though:

                                        QSqlQueryModel::fetchMore()
                                        Fetches more rows from a database.
                                        This only affects databases that don't report back the size of a query
                                        (see QSqlDriver::hasFeature()).

                                        At a guess MySQL will return "size of a query" (perhaps SQLite does not), so it may be all irrelevant in my situation?

                                        In any case, as you'll see I don't think the implementation will be in QSql.... That will rely on the abstraction level of the driver it's using, QMYSQL, and I'm thinking that is where what I would like to know is buried...

                                        But thanks anyway.

                                        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