QSqlTableModel submit/select in QThread separated
-
Good afternoon at all,
I have a little trouble. I have a big sqltablemodel that blocks the MainWindow during submit and select operations, so I thought to make them in separate thread thus to create a QProgressDialog that indicates the progress.
Unfortunately the application crashes, maybe because two threads (the main and the one i created) share the same resources.
Is the physically copy of the QSqlTableModel the only way to realize my idea or do you have any other suggestion?
Thank you so much!
Alessio -
@Alessio-V.
I've never had a big enough database that I had to spawn another thread, so this is not the voice of experience.If you read the manual section on threads though, it will tell you that sql connections can only be used on the thread that they're created on. You can have different connections to the same database on different threads, they just have to be created on the thread they run on.
I wouldn't expect Models to be cross-thread either.
HTH
Mike
-
@Alessio-V. said in QSqlTableModel submit/select in QThread separated:
maybe because two threads (the main and the one i created) share the same resources
This would do it. But why do you need to share resources in the first place?
@Alessio-V. said in QSqlTableModel submit/select in QThread separated:
Is the physically copy of the QSqlTableModel the only way to realize my idea or do you have any other suggestion?
Eh, you don't need to copy the model. Move it to the worker thread and that should work out of the box (unless there's a direct call from the view to the model, but there shouldn't be). For example:
QSqlTableModel * model; //< That's your model QThread * thread = new QThread(); thread->start(); QObject::connect(qApp, &QCoreApplication::aboutToQuit, thread, &QThread::quit); QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater); QObject::connect(thread, &QThread::finished, model, &QObject::deleteLater); model->moveToThread(thread);
@mjsurette said in QSqlTableModel submit/select in QThread separated:
sql connections can only be used on the thread that they're created on
That is true, but only if the SQL driver is reentrant, which you're supposed to check for each one that you intend to use. If the driver isn't reentrant, you can't use SQL connections from different threads at all, unless you manually serialize the calls.
-
Hi guys,
thank you so much for your replies!
I discovered my problem and was not the SqlTableModel. In fact the little trouble was that in the worker class I constructed the QProgressDialog and it is not possible because the widget must be construct only in the main thread.
Yes @kshegunov the sqlconnection must be used only in the thread where it's created on but if you use only the pointer I noted that the commit is made anyway!
Thanks for your suggestions! -
I always thought that modifying the model from a non GUI thread (when the model is connected to a view) is not feasible as the view will directly call the model. see http://stackoverflow.com/questions/9485339/design-pattern-qt-model-view-and-multiple-threads
-
@Alessio-V. said in QSqlTableModel submit/select in QThread separated:
Yes @kshegunov the sqlconnection must be used only in the thread where it's created on but if you use only the pointer I noted that the commit is made anyway!
An SQL driver may not be reentrant, just like the widgets, and may require you to stick to a single thread, just like the widgets. That's what I meant.
@VRonin said in QSqlTableModel submit/select in QThread separated:
I always thought that modifying the model from a non GUI thread (when the model is connected to a view) is not feasible as the view will directly call the model. see http://stackoverflow.com/questions/9485339/design-pattern-qt-model-view-and-multiple-threads
You're probably right. I haven't tried that at all, it was just an idea ... and in hindsight, sounds more like wishful thinking.