【发布时间】:2021-04-13 01:24:46
【问题描述】:
我有一个非常大的文件,其中包含简单的结构化 XML 数据(大约 180,000 条记录)。我需要一个显示进度条并使用另一个线程将数据解析到数据库的对话框。困难之一是我需要写入数据的数据库已被主窗口使用。
应用做什么:
- MainWindow 打开数据库并使用它。
- 如果单击“解析并写入”操作,则主窗口:(我们的对话)
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);
}
}
- 我的 dlg 创建了一个 gui:
- 如果单击左键,则程序会创建一个新线程并编辑进度条:
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();
- “parse_and_writeToDB”类中的doWork():
// 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();
- 工作一段时间后,应用程序崩溃。输出:
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
QObject::~QObject: Timers cannot be stopped from another thread
UPDATE #1 - invodeMethod - 太慢了,无论如何工作都是使用主线程完成的。在写入 DB gui 的过程中感觉很糟糕。
【问题讨论】:
-
所以你真正的问题是“如何从多个线程访问数据库”,对吧?按照here 的说明,尝试重命名您的连接。
-
@JarMan 不,我真正的问题是“为什么我会出现这样的错误?我认为我做的一切都是正确的。”
标签: c++ multithreading sqlite qt