Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Loading data into QTableView from QAbstractTableModel
Forum Updated to NodeBB v4.3 + New Features

Loading data into QTableView from QAbstractTableModel

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 6 Posters 373 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.
  • J Jo Jo

    @jsulm I think this is useful only when we add new rows. However, I can also change existing rows, including their order (sorting). Please correct me if I wrong

    SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote last edited by
    #4

    @Jo-Jo hi,

    How are the data getting pulled into your model ?
    Why would the sorting change when pulling it from the source ?

    Interested in AI ? www.idiap.ch
    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

    1 Reply Last reply
    1
    • J Offline
      J Offline
      Jo Jo
      wrote last edited by
      #5

      @SGaist hi,

      1. Data comes from SQL database
      2. Sorting can be changed because user can sort data in the table
      Christian EhrlicherC 1 Reply Last reply
      0
      • J Jo Jo

        @SGaist hi,

        1. Data comes from SQL database
        2. Sorting can be changed because user can sort data in the table
        Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote last edited by
        #6

        @Jo-Jo said in Loading data into QTableView from QAbstractTableModel:

        user can sort data in the table

        What has this to do with your model data?

        When you call begin/endResetModel then the view is updated completely with all things like selection or position. This is not a useful approach.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        1
        • J Offline
          J Offline
          Jo Jo
          wrote last edited by Jo Jo
          #7

          @Christian-Ehrlicher

          I think like this: if the user has selected sorting, then I need to re-sort the data on database level and store result in cache and force the view to pick up the new, but already sorted data from the cache, but only those that are currently visible on the screen, not all at once.

          I'll note that there is a lot of data in the table, hundreds of thousands. Sorting by columns and filtering are also needed.

          Do you have any other suggestions?

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote last edited by
            #8

            Why not use the combo QSqlTableModel / QSortFilterProxyModel ?
            If you really need to do querying then use QSqlQueryModel.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            1
            • J Offline
              J Offline
              Jo Jo
              wrote last edited by Jo Jo
              #9

              @SGaist I think it will be slow. As far as I know QSortFilterProxyModel filters data linearly. I need filtering/sorting at the DB level using indexes.

              JonBJ 1 Reply Last reply
              0
              • J Jo Jo

                @SGaist I think it will be slow. As far as I know QSortFilterProxyModel filters data linearly. I need filtering/sorting at the DB level using indexes.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote last edited by
                #10

                @Jo-Jo
                I don't know what your word "linearly" means here. However, I agree that (so far as I know) even with a QSqlTableModel a QSortFilterProxyModel imposed on top does not pass the sort (or filter) to the underlying SQL database. However, Googling I am unable to verify this, you should check the SQL SELECT statement generated before proceeding.

                Assuming that is the case, it also means that all of the rows must be read from database to memory for sorting to work, and rows which fail the filter are still read into the client (neither of which is the case if you sort/filter at the database) Which is slow/memory consuming, if your data is big.

                You can use QSqlQuery, QSqlQueryModel or QSqlTableModel with your own ORDER BY and/or WHERE as appropriate if they do not offer to pass that to the SQL backend.

                Going back to your original question. You write "data can be continuously coming into the model". What do you mean by that, given that the data is in a database, not e.g. arriving from a real time device?

                If you say that each time all the data rows are different, you can either delete all current rows and continue with the model as-is or you can call beginResetModel(). The latter will require it to get column definitions again on next fill call. My hunch is that these two will perform at about the same speed. QSqlQueryModel /QSqlTableModel have a clear() method to delete all rows. Might be preferable to resetting the model.

                J 1 Reply Last reply
                0
                • JonBJ JonB

                  @Jo-Jo
                  I don't know what your word "linearly" means here. However, I agree that (so far as I know) even with a QSqlTableModel a QSortFilterProxyModel imposed on top does not pass the sort (or filter) to the underlying SQL database. However, Googling I am unable to verify this, you should check the SQL SELECT statement generated before proceeding.

                  Assuming that is the case, it also means that all of the rows must be read from database to memory for sorting to work, and rows which fail the filter are still read into the client (neither of which is the case if you sort/filter at the database) Which is slow/memory consuming, if your data is big.

                  You can use QSqlQuery, QSqlQueryModel or QSqlTableModel with your own ORDER BY and/or WHERE as appropriate if they do not offer to pass that to the SQL backend.

                  Going back to your original question. You write "data can be continuously coming into the model". What do you mean by that, given that the data is in a database, not e.g. arriving from a real time device?

                  If you say that each time all the data rows are different, you can either delete all current rows and continue with the model as-is or you can call beginResetModel(). The latter will require it to get column definitions again on next fill call. My hunch is that these two will perform at about the same speed. QSqlQueryModel /QSqlTableModel have a clear() method to delete all rows. Might be preferable to resetting the model.

                  J Offline
                  J Offline
                  Jo Jo
                  wrote last edited by Jo Jo
                  #11

                  @JonB said in Loading data into QTableView from QAbstractTableModel:

                  I don't know what your word "linearly" means here.

                  "Linearly" means O(n) complexity. It's too expensive especially if we have a many rows.

                  @JonB said in Loading data into QTableView from QAbstractTableModel:

                  What do you mean by that, given that the data is in a database, not e.g. arriving from a real time device?

                  The database is frequently updated. All changes should be displayed in QTableView. In addition to updating the database, the user can also select their filters and sorting, table should work in real time.

                  1 Reply Last reply
                  0
                  • JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote last edited by JonB
                    #12

                    A SQL WHERE clause will also likely filter "linearly", it may well use primary key look up to avoid that depending on column, but don't assume that even if you have an index on a different column which is in the WHERE it will select that to avoid linear filter.

                    Anyway, I do not dispute that if you have a "large" number of rows and you want to be "efficient" (time and space) you may want to do your sorting & filtering at SQL side. Upon re-reading, QSqlTableModel at least has a setSort() which does get passed as ORDER BY to the SQL query. And equally it has a setFilter() for the WHERE. So instead of using those from QSortFilterProxyModel --- which I don't think will use these from QSqlTableModel --- use them explicitly yourself.

                    You also mention:

                    The database is frequently updated. All changes should be displayed in QTableView.

                    Be aware, if you are not already, that Qt SQL stuff knows nothing about the data being changed outside at the server. That is entirely up to you to code, you get no notifications that anything has changed, you will have to refresh on a timer.

                    In addition to updating the database

                    If other processes are updating between when you read records and when you update them, you might like to look at the SQL UPDATE statement generated. I am not sure it fully uses pessimistic locking --- UPDATE ... WHERE col1 = value_read_previously AND col2 = value_read_previously AND ... --- as MS ADO.NET SQL driver I used to use did, so you should be careful to see what it will update.

                    1 Reply Last reply
                    0
                    • J Offline
                      J Offline
                      Jo Jo
                      wrote last edited by Jo Jo
                      #13

                      @JonB

                      As far as I understand, setSort will sort and return all columns. This is not optimal.
                      I need to sort the list and get only row IDs as a result. Then use lazy loading to load rows by their ID.
                      Same for filtering.

                      JonBJ 1 Reply Last reply
                      0
                      • J Jo Jo

                        @JonB

                        As far as I understand, setSort will sort and return all columns. This is not optimal.
                        I need to sort the list and get only row IDs as a result. Then use lazy loading to load rows by their ID.
                        Same for filtering.

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote last edited by
                        #14

                        @Jo-Jo
                        I don't know what you mean. setSort() does not return any columns, it just sets what column to sort by which will be put into the SQL query. That is quite separate from which columns you want.

                        It's just an option in QSqlTableModel. You probably don't want that if all you want is "row IDs". Are you going to build some enormous WHERE id IN ( ... ) clause to load rows by a subset of IDs?? And why would you do that, why get IDs first and then use them to get rows when you could get the rows in the first place in sorted order?

                        Maybe you know what you are doing, I'm afraid I do not.

                        1 Reply Last reply
                        0
                        • S Offline
                          S Offline
                          SamiV123
                          wrote last edited by
                          #15

                          resetting the model is going to cause performance issues + the user is going to lose their selection and current cell/row/item

                          What you want to do is to use the beginInsertRows and endInsertRows instead.

                          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