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. How to prevent QTableView/QTreeView doing query/sorting multiple times?
Forum Update on Monday, May 27th 2025

How to prevent QTableView/QTreeView doing query/sorting multiple times?

Scheduled Pinned Locked Moved Unsolved General and Desktop
qtableviewqtreeviewsorting
11 Posts 4 Posters 6.3k Views
  • 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.
  • S Offline
    S Offline
    SGaist
    Lifetime Qt Champion
    wrote on 14 Sept 2017, 20:47 last edited by
    #2

    Hi,

    The only thing that comes to mind to try is to invert the setSortingEnabled and sortByColumn calls.

    In any case, there's no way for Qt to know that it should refrain from doing these queries. These methods might be call at any time thus requiring these updates.

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

    J 1 Reply Last reply 14 Sept 2017, 20:57
    0
    • S SGaist
      14 Sept 2017, 20:47

      Hi,

      The only thing that comes to mind to try is to invert the setSortingEnabled and sortByColumn calls.

      In any case, there's no way for Qt to know that it should refrain from doing these queries. These methods might be call at any time thus requiring these updates.

      J Offline
      J Offline
      JonB
      wrote on 14 Sept 2017, 20:57 last edited by JonB
      #3

      @SGaist said in How to prevent QTableView/QTreeView doing query/sorting multiple times?:

      Hi,

      The only thing that comes to mind to try is to invert the setSortingEnabled and sortByColumn calls.

      I already stated: "Reversing the order of the statements does not help: then the latter query with ORDER BY col DESC is simply executed twice in a row"

      In any case, there's no way for Qt to know that it should refrain from doing these queries.
      These methods might be call at any time thus requiring these updates.

      So you can't enable sorting and do an initial sort without fetching the data twice from the database. I wonder how many people are aware their code is doing that. That's simply wrong.

      1 Reply Last reply
      0
      • S Offline
        S Offline
        SGaist
        Lifetime Qt Champion
        wrote on 14 Sept 2017, 21:10 last edited by
        #4

        My bad, I misunderstood the "reversing the order" part.

        In any case, how would you propose that a generic component be aware of the fact that you are going to show data from a database but it should wait for you to both enable sorting as well as configure it before starting to fetch data ?

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

        J 1 Reply Last reply 14 Sept 2017, 21:24
        0
        • S SGaist
          14 Sept 2017, 21:10

          My bad, I misunderstood the "reversing the order" part.

          In any case, how would you propose that a generic component be aware of the fact that you are going to show data from a database but it should wait for you to both enable sorting as well as configure it before starting to fetch data ?

          J Offline
          J Offline
          JonB
          wrote on 14 Sept 2017, 21:24 last edited by JonB
          #5

          @SGaist
          I would simply like to present a grid to the user with columns he can click on to sort. And I'd like the grid to start out sorted by some column. Just what a QTableView is supposed to be for. Does that sound reasonable? It's what hundreds of applications do.

          OK, and I expect to achieve the above by having one SQL query like SELECT * FROM table ORDER BY col executed. Not two. That's all. Pretend my query takes 10 seconds to execute. How do I achieve that, please?

          The way I see it at present, with Qt that requires the data to be fetched twice? Either that is not the case, or it's wrong.

          [BTW, I haven't got the reference, but something like QSqlTableModel specifically has a call to let you set the sort attributes before the SELECT gets executed.]

          1 Reply Last reply
          0
          • S Offline
            S Offline
            SGaist
            Lifetime Qt Champion
            wrote on 14 Sept 2017, 21:45 last edited by
            #6

            What you want to do is clear. However, your expectations about how QTableView should be working are wrong. That's a generic component that should work with all possible implementations of a QAbstractTableModel. It's not particularly optimised for the SQL use case.

            What happens currently is basically:

            1. You set a model on the table view -> the table view loads the data so it can show something
            2. You modify the view to enable sorting -> the model should be sorted based on the default values
            3. You modify again the view by changing the sorting -> the model should again be sorted but with the new values

            You are likely referring to QSqlTableModel::setSort which requires a call to select for the update to happen.

            So what you would need is a variant of QTableView that would setup itself based on the sorting you did first on your QSqlTableModel when you set the model on that view.

            Note that QSortFilterProxyModel might also be of interest.

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

            J V 3 Replies Last reply 14 Sept 2017, 21:47
            2
            • S SGaist
              14 Sept 2017, 21:45

              What you want to do is clear. However, your expectations about how QTableView should be working are wrong. That's a generic component that should work with all possible implementations of a QAbstractTableModel. It's not particularly optimised for the SQL use case.

              What happens currently is basically:

              1. You set a model on the table view -> the table view loads the data so it can show something
              2. You modify the view to enable sorting -> the model should be sorted based on the default values
              3. You modify again the view by changing the sorting -> the model should again be sorted but with the new values

              You are likely referring to QSqlTableModel::setSort which requires a call to select for the update to happen.

              So what you would need is a variant of QTableView that would setup itself based on the sorting you did first on your QSqlTableModel when you set the model on that view.

              Note that QSortFilterProxyModel might also be of interest.

              J Offline
              J Offline
              JonB
              wrote on 14 Sept 2017, 21:47 last edited by
              #7

              @SGaist
              Thank you for your reply, it's late tonight here, I shall look into it tomorrow!

              1 Reply Last reply
              0
              • S SGaist
                14 Sept 2017, 21:45

                What you want to do is clear. However, your expectations about how QTableView should be working are wrong. That's a generic component that should work with all possible implementations of a QAbstractTableModel. It's not particularly optimised for the SQL use case.

                What happens currently is basically:

                1. You set a model on the table view -> the table view loads the data so it can show something
                2. You modify the view to enable sorting -> the model should be sorted based on the default values
                3. You modify again the view by changing the sorting -> the model should again be sorted but with the new values

                You are likely referring to QSqlTableModel::setSort which requires a call to select for the update to happen.

                So what you would need is a variant of QTableView that would setup itself based on the sorting you did first on your QSqlTableModel when you set the model on that view.

                Note that QSortFilterProxyModel might also be of interest.

                V Offline
                V Offline
                VRonin
                wrote on 15 Sept 2017, 07:36 last edited by
                #8

                @SGaist said in How to prevent QTableView/QTreeView doing query/sorting multiple times?:

                Note that QSortFilterProxyModel might also be of interest.

                Big up for this line. QSortFilterProxyModel is definitely what you need

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                1 Reply Last reply
                0
                • S SGaist
                  14 Sept 2017, 21:45

                  What you want to do is clear. However, your expectations about how QTableView should be working are wrong. That's a generic component that should work with all possible implementations of a QAbstractTableModel. It's not particularly optimised for the SQL use case.

                  What happens currently is basically:

                  1. You set a model on the table view -> the table view loads the data so it can show something
                  2. You modify the view to enable sorting -> the model should be sorted based on the default values
                  3. You modify again the view by changing the sorting -> the model should again be sorted but with the new values

                  You are likely referring to QSqlTableModel::setSort which requires a call to select for the update to happen.

                  So what you would need is a variant of QTableView that would setup itself based on the sorting you did first on your QSqlTableModel when you set the model on that view.

                  Note that QSortFilterProxyModel might also be of interest.

                  J Offline
                  J Offline
                  JonB
                  wrote on 15 Sept 2017, 08:18 last edited by
                  #9

                  @SGaist

                  Thank you for your clarification on the behaviour of QTableView.

                  Your description implies there should actually be 3 queries against the data, then. I only see 2. However, I admit I would need more time to be sure.

                  Let me see if I have understood the behaviour of setSortingEnabled() & sortByColumn():

                  • setSortingEnabled() is what makes the View show sort indicators on column headers and allow clicking. It also executes a data fetch query, passing whatever (if anything) is currently defined as the sort order (from sortByColumn()) into an ORDER BY.
                  • sortByColumn() determines the ORDER BY. It too executes a data fetch.

                  (Please correct me if I am wrong.) Now, after (just, i.e. no sortByColumn() yet) a setSortingEnabled() I will see the sort indicator in some direction on some column. I am guessing this would be Ascending on column #0 initially(?) However, the query it issues has no ORDER BY at all, so by definition the rows are in indeterminate order. This seems simply inconsistent to me.

                  What I would have expected/hoped is that setSortingEnabled() would have passed an ORDER BY col0 ASC if that is how the data is supposed to be sorted to correspond to the initial sort indicator state, and/or an optional parameter to allow specification of the initial sort order desired in the View and to be passed in the initial query --- in effect, combining the setSortingEnabled() with an initial sortByColumn(). Or even, as you say, an equivalent of QSqlTableModel.setSort(). As it stands it seems you must fetch the data twice simply to correspond to the View's initial state.

                  I have inherited 32K lines of code which uses every kind of Qt SQL/model/view architecture all over the place, it's a mess. I will indeed investigate QSortFilterProxyModel. I don't mind which code I use to achieve it, I just don't expect any necessity to fetch the data multiple times for the initial situation.

                  1 Reply Last reply
                  0
                  • MrBoltonM Offline
                    MrBoltonM Offline
                    MrBolton
                    wrote on 28 Sept 2018, 07:40 last edited by
                    #10

                    @JonB said in Default sort indicator order in QHeaderView:

                    @MrBolton
                    Thanks for replying.

                    Your solution is not what I am looking for, unfortunately. I do not even have a QSortFilterProxyModel. Specifically, I do not want sorting to happen at the client. I wish it to happen at the server with a ORDER BY.

                    Why do you want the sorting to happen on the server? This way, every time you change the sorting, a new query is executed to fetch the date from the server.
                    Doing the sorting with help of a QSortFilterProxyModel would be much more performant with bigger data sets since the data is only fetched once.

                    J 1 Reply Last reply 28 Sept 2018, 07:51
                    0
                    • MrBoltonM MrBolton
                      28 Sept 2018, 07:40

                      @JonB said in Default sort indicator order in QHeaderView:

                      @MrBolton
                      Thanks for replying.

                      Your solution is not what I am looking for, unfortunately. I do not even have a QSortFilterProxyModel. Specifically, I do not want sorting to happen at the client. I wish it to happen at the server with a ORDER BY.

                      Why do you want the sorting to happen on the server? This way, every time you change the sorting, a new query is executed to fetch the date from the server.
                      Doing the sorting with help of a QSortFilterProxyModel would be much more performant with bigger data sets since the data is only fetched once.

                      J Offline
                      J Offline
                      JonB
                      wrote on 28 Sept 2018, 07:51 last edited by JonB
                      #11

                      @MrBolton
                      Sorry, I really don't understand your comment. Precisely the point is that with "bigger data sets" you would have to fetch all the data, which is incredibly slow and may well exceed available memory. (OTOH, if the dataset is "small" the overhead of re-query compared to holding all the previous rows locally is also "small".) As a rule of thumb, one always wants as much work to be done at the server side as possible, not client side.

                      Let's say the table has a million rows and the query I want to pose is:

                      SELECT * FROM table
                      ORDER BY column
                      LIMIT 100
                      

                      Very approximately, pushing the ORDER BY to the server instead of into a QSortFilterProxyModel will run 10 thousand times faster and use one ten-thousandth of the client memory. That's why I would be very careful before advising people to use QSortFilterProxyModel without understanding the ramifications!

                      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