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. QSqlQueryModel and TableView for dynamic data
Forum Update on Monday, May 27th 2025

QSqlQueryModel and TableView for dynamic data

Scheduled Pinned Locked Moved Solved QML and Qt Quick
24 Posts 4 Posters 6.4k 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 5 Jun 2018, 10:14 last edited by
    #7

    Hi,

    Just a side note, you're using QSqlDatabase wrongly. There's no need for that pointer.

    See the class documentation for how to handle it.

    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
    0
    • X Offline
      X Offline
      XDePedro
      wrote on 5 Jun 2018, 10:15 last edited by
      #8

      If the db has enough elements to get the scrollbar in the table, then just scrolling the table the new elements are populated....so I suppose I'm missing any kind of notification so that the TableView is updated...just can't figure out how.

      J 1 Reply Last reply 5 Jun 2018, 10:17
      0
      • X XDePedro
        5 Jun 2018, 10:15

        If the db has enough elements to get the scrollbar in the table, then just scrolling the table the new elements are populated....so I suppose I'm missing any kind of notification so that the TableView is updated...just can't figure out how.

        J Offline
        J Offline
        JonB
        wrote on 5 Jun 2018, 10:17 last edited by
        #9

        @XDePedro
        Not sure what you mean. Scrolling a table view does not fetch new elements via a new SQL query on the database....

        X 1 Reply Last reply 5 Jun 2018, 10:36
        0
        • J JonB
          5 Jun 2018, 10:17

          @XDePedro
          Not sure what you mean. Scrolling a table view does not fetch new elements via a new SQL query on the database....

          X Offline
          X Offline
          XDePedro
          wrote on 5 Jun 2018, 10:36 last edited by
          #10

          @JonB

          Is not the table view fetching for new elements. If I just resize it just to make it redraw...the new elements are also displayed.

          I am calling setQuery in the model everytime the database changes so I suppose the query is ok and the data is there....but just calling setQuery doesn't make the TableView to update.

          How can I force the table view to update from the model?

          J 1 Reply Last reply 5 Jun 2018, 10:47
          0
          • X XDePedro
            5 Jun 2018, 10:36

            @JonB

            Is not the table view fetching for new elements. If I just resize it just to make it redraw...the new elements are also displayed.

            I am calling setQuery in the model everytime the database changes so I suppose the query is ok and the data is there....but just calling setQuery doesn't make the TableView to update.

            How can I force the table view to update from the model?

            J Offline
            J Offline
            JonB
            wrote on 5 Jun 2018, 10:47 last edited by
            #11

            @XDePedro
            For the update, see posts like:

            • http://www.qtcentre.org/threads/58700-How-to-update-QTableView-from-SQL-database-after-adding-data-to-database
            • https://forum.qt.io/topic/1168/solved-the-best-way-to-programmatically-refresh-a-qsqlquerymodel-when-the-content-of-the-query-changes/13
            • https://stackoverflow.com/questions/45359569/how-to-update-qtableview-on-qabstracttablemodel-change

            However, I don't see how this addresses what I see as your issue, which is that you have "hundreds of thousands of rows" to display. You do not want to fetch all of them each time, you do not want to store them all in your model, nor in your view.... IMHO you only want to fetch some kind of "page" at a time of rows, or something along those lines.

            1 Reply Last reply
            0
            • X Offline
              X Offline
              XDePedro
              wrote on 5 Jun 2018, 12:39 last edited by
              #12

              I know maybe this not the right model but anyway I would like to make it work before looking for another solution.

              I notice that I'm getting this error message:

              QObject::connect: Cannot queue arguments of type 'QQmlChangeSet'
              (Make sure 'QQmlChangeSet' is registered using qRegisterMetaType().)

              can it be the root cause? Does naybody know why I'm getting this? Might it be related with the fact that is another thread who is calling the setQuery??

              1 Reply Last reply
              0
              • K Offline
                K Offline
                KillerSmath
                wrote on 5 Jun 2018, 12:43 last edited by
                #13

                @XDePedro

                Possible explation for your problem.

                @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
                0
                • K Offline
                  K Offline
                  KillerSmath
                  wrote on 5 Jun 2018, 13:06 last edited by
                  #14

                  Executing query in Main Thread after DB Changed

                   connect(populateWorker, &populateWorker::doneSignal, [this](){
                     QSqlQuery query(*database);
                     database->open();
                  
                     query->setQuery("SELECT * FROM Samples");
                     query->exec();
                     
                     model->setQuery(query);
                  
                     database->close();
                  });
                  

                  @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

                  X 1 Reply Last reply 5 Jun 2018, 13:49
                  0
                  • K KillerSmath
                    5 Jun 2018, 13:06

                    Executing query in Main Thread after DB Changed

                     connect(populateWorker, &populateWorker::doneSignal, [this](){
                       QSqlQuery query(*database);
                       database->open();
                    
                       query->setQuery("SELECT * FROM Samples");
                       query->exec();
                       
                       model->setQuery(query);
                    
                       database->close();
                    });
                    
                    X Offline
                    X Offline
                    XDePedro
                    wrote on 5 Jun 2018, 13:49 last edited by
                    #15

                    @KillerSmath
                    How is this different that I was doing?

                    You added the slot in a lambda but is still executed in the working thread, as far as I know, Or I am missing anything.

                    I tried and seems not to work.

                    1 Reply Last reply
                    0
                    • K Offline
                      K Offline
                      KillerSmath
                      wrote on 5 Jun 2018, 15:00 last edited by
                      #16

                      I am not expert with QThread but my suggest is create a class (DataManager) that will be the bridge between QML and C++ Model.

                      • You can create a QThread inside this class to move the worker object to this thread.

                      • Run your GenerateFakeData function from this worker and connect the doneSignal to setQuery Slot in DataManager

                      • Allow the acess to model by this class

                      @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
                      0
                      • X Offline
                        X Offline
                        XDePedro
                        wrote on 6 Jun 2018, 07:59 last edited by
                        #17

                        Ok. Now is working. It was a problem with the worker thread. I stopped the code in the code that updated the query (setQuery) in my previous implementation and was executed in the working thread. With current implementation the setQuery is executed in the UI thread.

                        In fact with current implementation the code is executed in one thread or the other just depending on how I made the signal/slot connection. So if I connect them this way:

                                connect(&insertWorker, SIGNAL(dbChanged()), this, SLOT(DBUpdated()));
                        
                        
                            void SampleListModel::DBUpdated()
                            {
                                QSqlQuery query;/
                                query.exec("SELECT * FROM Samples");
                                setQuery(query);
                            }
                        

                        Everything works and the setQuery is executed in the UI thread.

                        But if I do it this way:

                                connect(    &insertWorker,
                                            &DBWorker::dbChanged,
                                            [this]()
                                            {
                                                QSqlQuery query(GetDataBase());
                                                query.exec("SELECT * FROM Samples");
                                                setQuery(query);
                                            });
                        

                        Then the lambda code is executed in the worker thread and the real-time updates are not working.

                        As I said I am pretty new in Qt so I wonder whats the difference and if someone can recommend a good article explainning how the thread model works in Qt.

                        Thanks for all your help.

                        J 1 Reply Last reply 6 Jun 2018, 08:27
                        1
                        • K Offline
                          K Offline
                          KillerSmath
                          wrote on 6 Jun 2018, 08:11 last edited by
                          #18

                          You welcome.
                          I also had difficulty with threads when i was starting to coding in QT but as time goes on, you'll understand why threads are very limited because of their unpredictability.

                          @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
                          0
                          • X XDePedro
                            6 Jun 2018, 07:59

                            Ok. Now is working. It was a problem with the worker thread. I stopped the code in the code that updated the query (setQuery) in my previous implementation and was executed in the working thread. With current implementation the setQuery is executed in the UI thread.

                            In fact with current implementation the code is executed in one thread or the other just depending on how I made the signal/slot connection. So if I connect them this way:

                                    connect(&insertWorker, SIGNAL(dbChanged()), this, SLOT(DBUpdated()));
                            
                            
                                void SampleListModel::DBUpdated()
                                {
                                    QSqlQuery query;/
                                    query.exec("SELECT * FROM Samples");
                                    setQuery(query);
                                }
                            

                            Everything works and the setQuery is executed in the UI thread.

                            But if I do it this way:

                                    connect(    &insertWorker,
                                                &DBWorker::dbChanged,
                                                [this]()
                                                {
                                                    QSqlQuery query(GetDataBase());
                                                    query.exec("SELECT * FROM Samples");
                                                    setQuery(query);
                                                });
                            

                            Then the lambda code is executed in the worker thread and the real-time updates are not working.

                            As I said I am pretty new in Qt so I wonder whats the difference and if someone can recommend a good article explainning how the thread model works in Qt.

                            Thanks for all your help.

                            J Offline
                            J Offline
                            JonB
                            wrote on 6 Jun 2018, 08:27 last edited by
                            #19

                            @XDePedro
                            I can't get my head around each of your two code approaches, but it's important to understand that all database objects/operations are constructed/performed in the same thread as each other, not in/from different threads. Is that the situation you are in now/does that explain anything not working?

                            X 1 Reply Last reply 6 Jun 2018, 09:07
                            0
                            • J JonB
                              6 Jun 2018, 08:27

                              @XDePedro
                              I can't get my head around each of your two code approaches, but it's important to understand that all database objects/operations are constructed/performed in the same thread as each other, not in/from different threads. Is that the situation you are in now/does that explain anything not working?

                              X Offline
                              X Offline
                              XDePedro
                              wrote on 6 Jun 2018, 09:07 last edited by
                              #20

                              @JonB
                              Database insertions/write are done in the working thread.
                              Database queries/reads are done in the UI thread.

                              J 1 Reply Last reply 6 Jun 2018, 09:22
                              0
                              • X XDePedro
                                6 Jun 2018, 09:07

                                @JonB
                                Database insertions/write are done in the working thread.
                                Database queries/reads are done in the UI thread.

                                J Offline
                                J Offline
                                JonB
                                wrote on 6 Jun 2018, 09:22 last edited by
                                #21

                                @XDePedro
                                So as far as I understand you must not do that, as per what I wrote above....

                                X 1 Reply Last reply 6 Jun 2018, 09:42
                                0
                                • J JonB
                                  6 Jun 2018, 09:22

                                  @XDePedro
                                  So as far as I understand you must not do that, as per what I wrote above....

                                  X Offline
                                  X Offline
                                  XDePedro
                                  wrote on 6 Jun 2018, 09:42 last edited by
                                  #22

                                  @JonB
                                  Seems to work, but I will not do it this way...teh database here is just a fake database in order to be able to work in the model while the real db is yet not implemented.

                                  Thanks.

                                  Still wondering which model approach will feet better in what I ultimately have to implement. A lists of data that can have thousand of rows and can be updated by another thread (not user interaction). Any suggestions.

                                  J 1 Reply Last reply 6 Jun 2018, 09:47
                                  0
                                  • X XDePedro
                                    6 Jun 2018, 09:42

                                    @JonB
                                    Seems to work, but I will not do it this way...teh database here is just a fake database in order to be able to work in the model while the real db is yet not implemented.

                                    Thanks.

                                    Still wondering which model approach will feet better in what I ultimately have to implement. A lists of data that can have thousand of rows and can be updated by another thread (not user interaction). Any suggestions.

                                    J Offline
                                    J Offline
                                    JonB
                                    wrote on 6 Jun 2018, 09:47 last edited by JonB 6 Jun 2018, 09:51
                                    #23

                                    @XDePedro
                                    For the "updated by another thread (not user interaction)", my understanding is that you must not do that directly. If you need to, use signals & slots. You may get away without now, but supposedly not in the long run, under whatever circumstances.

                                    Read up on this, e.g. https://stackoverflow.com/questions/20793689/correctly-using-qsqldatabase-in-multi-threaded-programs, and many others.

                                    For the "model approach", I still think you need to answer my earlier question: do you fetch a brand new set of rows and those are the only ones to be shown in the table view, or do you "incrementally" fetch some additional new rows, and want those to be appended to what you already have in the model & the view?

                                    1 Reply Last reply
                                    0
                                    • X Offline
                                      X Offline
                                      XDePedro
                                      wrote on 6 Jun 2018, 12:24 last edited by
                                      #24

                                      Any help about which model should I use? Any help on how implement it?

                                      1 Reply Last reply
                                      0

                                      16/24

                                      5 Jun 2018, 15:00

                                      • Login

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