I have a very large file with simple structured XML data (about 180,000 records). I need a dialog that will show a progress bar and parse the data to the database using another thread. One of the difficulties is that the database to which I need to write data is already in use by the main window.
What app does:
- MainWindow opens database and works with it.
- If action "Parse and write" is clicked then mainwindow: (our dialogue)
void MainWindow::on_act_parse_and_write()
{
// CLOSE DB
db->close();
delete db;
// EXEC DLG
update_omega_base * dlg = new update_omega_base(this);
dlg->exec();
// OPEN NEW CONNECTION
db = new QSqlDatabase();
*db = QSqlDatabase::addDatabase("QSQLITE");
db->setDatabaseName(DB_NAME);
if (!db->open()) {
QMessageBox::critical(nullptr, "Помилка", "Не можу п?дключити базу даних MAINWINDOW", QMessageBox::Ok);
exit(ERROR_CODE);
}
}
- My dlg creates a gui:
- If left button clicked then program creates a new thread and edits progressBar:
parse_and_writeToDB *worker = new parse_and_writeToDB();
worker->moveToThread(&workThread);
connect(&workThread, &QThread::finished, &workThread, &QObject::deleteLater);
connect(this, &update_omega_base::startWork, worker, &parse_and_writeToDB::doWork);
connect(worker, &parse_and_writeToDB::currentRowChanged, this, &update_omega_base::updateCurrentProgress);
connect(worker, &parse_and_writeToDB::errorDetected, this, &update_omega_base::handleError);
workThread.start();
- doWork() in "parse_and_writeToDB" class:
// CREATE CONNECTION TO DATABASE
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(DB_NAME);
if (!db.open()) {
emit errorDetected("Не можу в?дкрити базу даних");
exit(ERROR_CODE);
}
QSqlQuery qry;
// clear old Omega table
if(!qry.exec("DELETE FROM " + DB_TABLE_OMEGA))
{
emit errorDetected("Не виходить очистити БД перед записом");
exit(ERROR_CODE);
}
// ------- QXmlStreamParser PARSES EVERYTHING and qry ADDS ROWS -------
qry.clear();
db.close();
- After working for a while, the application crashes. Output:
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
QObject::~QObject: Timers cannot be stopped from another thread
UPDATE #1 - invodeMethod - is too slow and the work anyway is done using main thread. During writing to DB gui feels bad.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…