Need help on QtConcurrent usage.
-
Hi to all,
I'm doing some heavy computing, like accessing a database, that blocks my UI. So, I'm implementing the QtConcurrent::run function to start some class methods. These methods retrieve data from database table to fill out a classic QComboBox. After the
@ui->setupUi(this);@in my form ctor I'm running these commands:
@
QFuture<void> f1 = QtConcurrent::run(this, &frmPractices_CRUD::populateComboSubjects);
QFuture<void> f2 = QtConcurrent::run(this, &frmPractices_CRUD::populateComboSellPoints);
f1.waitForFinished();
f2.waitForFinished();
@and the code is compiled but I get a Visual C++ Runtime Library errors!
Then I tried to debug the functions and maybe my debugging skill isn't so good yet. I get the program works without errors only making the following changes:@
QFuture<void> f1 = QtConcurrent::run(this, &frmPractices_CRUD::populateComboSubjects);
f1.waitForFinished();
QFuture<void> f2 = QtConcurrent::run(this, &frmPractices_CRUD::populateComboSellPoints);
f2.waitForFinished();
@And I don't think that's the right way to use QtConcurrent, my populateComboABCD functions contain the same code:
@
ui->cboSubject->clear();QSqlDatabase db = QSqlDatabase::database(); QString tSqlCommand = QString( "SELECT " "sog_id, " "concat_ws(' ', sog_cogn, sog_nome) AS names, " "concat_ws(' - ', sog_codf, sog_piva) AS fiscals " "FROM %1.subjects " "WHERE (sog_tipo = 1) OR (sog_tipo = 3) " "ORDER BY names" ).arg(MyQtUtility::instance()->schemaName()); QSqlQuery tSqlQuery(db); if (tSqlQuery.exec(tSqlCommand)) { while (tSqlQuery.next()) { QString tmpCboText; tmpCboText += tSqlQuery.value(1).toString().simplified(); if (!tSqlQuery.value(2).toString().simplified().isEmpty()) { tmpCboText += " / " + tSqlQuery.value(2).toString().simplified(); } ui->cboSubject->addItem(tmpCboText.trimmed(), tSqlQuery.value(0).toInt()); } } tSqlQuery.finish();
@
Thanks in advance,
Danilo -
@
QFuture<void> f1 = QtConcurrent::run(this, &frmPractices_CRUD::populateComboSubjects);
f1.waitForFinished();
QFuture<void> f2 = QtConcurrent::run(this, &frmPractices_CRUD::populateComboSellPoints);
f2.waitForFinished();
@
You're right. It's not good this way. This is a sequential code. It is the same as
@
populateComboSubjects();
populateComboSellPoints();
@
The problem is not with QtConcurrent. It's with the populate* methods. They run in separate threads and you can access UI only in the main thread, so calls to ui->cboSubject->clear() and ui->cboSubject->addItem() are not allowed there.You can run your sql queries in the worker threads but you need to signal the main thread to do the UI update.
-
Thanks Chris, but commenting the ui->cboSubject calls I get the same errors. I noted that the debug mode is stopping on MyQtUtility::instance()->schemaName() (it's a singleton class) command whithout breakpoint!! I don't know how strange it is but seems a wrong behavior.
-
Hi,
AFAIK, you need to at least create a different connection for each thread in order to access the database.