Solved QSqlQueryModel and TableView for dynamic data
-
-
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(); });
-
@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.
-
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
-
-
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.
-
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. -
@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? -
@JonB
Database insertions/write are done in the working thread.
Database queries/reads are done in the UI thread. -
@XDePedro
So as far as I understand you must not do that, as per what I wrote above.... -
@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.
-
@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?
-
Any help about which model should I use? Any help on how implement it?