基本的流程如下:
QThread: 线程与Sqlite绑定
生成实例前先把与 sqlquery 信号与槽 建立好,然后就线程开始,等待信号:
class SQLThread : public QObject
{
Q_OBJECT
private:
QThread workerThread;
public:
explicit SQLThread(QObject *parent = nullptr);
~SQLThread();
private slots:
void slot_res_select(int tid, bool res, QString msg, QList<QSqlRecord> data);
signals:
void sig_initDB(); // 接收上层调用信号,然后去调用下层 SQLQuery 的slot功能函数
void sig_select(int tid, QString sql);
void sig_res_select(int tid, bool res, QString msg, QList<QSqlRecord> data);
SQLThread::SQLThread(QObject *parent) : QObject(parent)
{
SQLQuery *sq = new SQLQuery;
sq->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, sq, &QObject::deleteLater);
// Select SQL
connect(this, &SQLThread::sig_selectSql, sq, &SQLQuery::slot_selectSql);
connect(sq, &SQLQuery::sig_res_selectSql, this, &SQLThread::slot_res_selectSql);
qDebug() << "workThread.start";
workerThread.start();
}
SQLThread::~SQLThread()
{
qDebug() << "workThread.quit and wait";
workerThread.quit();
workerThread.wait();
}
void SQLThread::slot_res_selectSql(int tid, bool res, QString msg, QList<QSqlRecord> data)
{
emit sig_res_select(tid, res, msg, data);
}
SQLQuery: 正常的操作数据库:
class SQLQuery : public QObject
{
Q_OBJECT
public slots:
void slot_select(int tid, QString sql); // select
signals:
void sig_res_select(int tid, bool res, QString msg, QList<QSqlRecord> data);
};
void SQLQuery::slot_select(int tid, QString sql)
{
QString msg;
QList<QSqlRecord> data;
QSqlDatabase mDB = QSqlDatabase::addDatabase("QSQLITE", "select"); // 添加数据库驱动
mDB.setDatabaseName(mDBName);
if (!mDB.open()) {
qDebug("打开数据库失败");
msg = "Open db file fail";
emit sig_res_selectSql(tid, false, msg, data);
return;
}
QSqlQuery query(mDB);
if (!query.exec(sql)) {
qDebug() << "insert sql fail:" << query.lastError().text();
qDebug() << "sql: " << sql;
msg = "insert fail, sql: " + sql;
emit sig_res_selectSql(tid, false, msg, data);
QSqlDatabase::removeDatabase(
QSqlDatabase::database().connectionName()
);
return;
}
while (query.next()) {
data.append(query.record());
}
qDebug() << "SQLQuery: select succ, count: " << data.count();
emit sig_res_selectSql(tid, true, msg, data);
QSqlDatabase::removeDatabase(QSqlDatabase::database().connectionName());
return;
}
MainWindow:
class MainWindow : public QMainWindow
{
Q_OBJECT
private slots:
void slot_res_selectSql(int tid, bool res, QString msg, QList<QSqlRecord> data);
private:
SQLThread *st;
}
MainWindow::Select()
{
...
qRegisterMetaType<QList<QSqlRecord>>("QList<QSqlRecord>"); // 注册新类型
st = new SQLThread;
connect(st, &SQLThread::sig_res_select, this, &MainWindow::slot_res_select);
QString sql = "SELECT * from accountTBL order by id asc";
emit st->sig_selectSql(10001, sql);
}
void MainWindow::slot_res_select(int tid, bool res, QString msg, QList<QSqlRecord> data)
{
if (tid != 10001) { ... }
else {
if (res) {
for (int i=0; i<data.count(); i++) {
int uid = data.at(i).value("id").toInt();
QString email = data.at(i).value("email").toString();
}
}
}
}