基本的流程如下:

QThread: 线程与Sqlite绑定

生成实例前先把与 sqlquery 信号与槽 建立好,然后就线程开始,等待信号:

  1. class SQLThread : public QObject
  2. {
  3. Q_OBJECT
  4. private:
  5. QThread workerThread;
  6. public:
  7. explicit SQLThread(QObject *parent = nullptr);
  8. ~SQLThread();
  9. private slots:
  10. void slot_res_select(int tid, bool res, QString msg, QList<QSqlRecord> data);
  11. signals:
  12. void sig_initDB(); // 接收上层调用信号,然后去调用下层 SQLQuery 的slot功能函数
  13. void sig_select(int tid, QString sql);
  14. void sig_res_select(int tid, bool res, QString msg, QList<QSqlRecord> data);
  1. SQLThread::SQLThread(QObject *parent) : QObject(parent)
  2. {
  3. SQLQuery *sq = new SQLQuery;
  4. sq->moveToThread(&workerThread);
  5. connect(&workerThread, &QThread::finished, sq, &QObject::deleteLater);
  6. // Select SQL
  7. connect(this, &SQLThread::sig_selectSql, sq, &SQLQuery::slot_selectSql);
  8. connect(sq, &SQLQuery::sig_res_selectSql, this, &SQLThread::slot_res_selectSql);
  9. qDebug() << "workThread.start";
  10. workerThread.start();
  11. }
  12. SQLThread::~SQLThread()
  13. {
  14. qDebug() << "workThread.quit and wait";
  15. workerThread.quit();
  16. workerThread.wait();
  17. }
  18. void SQLThread::slot_res_selectSql(int tid, bool res, QString msg, QList<QSqlRecord> data)
  19. {
  20. emit sig_res_select(tid, res, msg, data);
  21. }

SQLQuery: 正常的操作数据库:

  1. class SQLQuery : public QObject
  2. {
  3. Q_OBJECT
  4. public slots:
  5. void slot_select(int tid, QString sql); // select
  6. signals:
  7. void sig_res_select(int tid, bool res, QString msg, QList<QSqlRecord> data);
  8. };
  1. void SQLQuery::slot_select(int tid, QString sql)
  2. {
  3. QString msg;
  4. QList<QSqlRecord> data;
  5. QSqlDatabase mDB = QSqlDatabase::addDatabase("QSQLITE", "select"); // 添加数据库驱动
  6. mDB.setDatabaseName(mDBName);
  7. if (!mDB.open()) {
  8. qDebug("打开数据库失败");
  9. msg = "Open db file fail";
  10. emit sig_res_selectSql(tid, false, msg, data);
  11. return;
  12. }
  13. QSqlQuery query(mDB);
  14. if (!query.exec(sql)) {
  15. qDebug() << "insert sql fail:" << query.lastError().text();
  16. qDebug() << "sql: " << sql;
  17. msg = "insert fail, sql: " + sql;
  18. emit sig_res_selectSql(tid, false, msg, data);
  19. QSqlDatabase::removeDatabase(
  20. QSqlDatabase::database().connectionName()
  21. );
  22. return;
  23. }
  24. while (query.next()) {
  25. data.append(query.record());
  26. }
  27. qDebug() << "SQLQuery: select succ, count: " << data.count();
  28. emit sig_res_selectSql(tid, true, msg, data);
  29. QSqlDatabase::removeDatabase(QSqlDatabase::database().connectionName());
  30. return;
  31. }

MainWindow:

  1. class MainWindow : public QMainWindow
  2. {
  3. Q_OBJECT
  4. private slots:
  5. void slot_res_selectSql(int tid, bool res, QString msg, QList<QSqlRecord> data);
  6. private:
  7. SQLThread *st;
  8. }
  1. MainWindow::Select()
  2. {
  3. ...
  4. qRegisterMetaType<QList<QSqlRecord>>("QList<QSqlRecord>"); // 注册新类型
  5. st = new SQLThread;
  6. connect(st, &SQLThread::sig_res_select, this, &MainWindow::slot_res_select);
  7. QString sql = "SELECT * from accountTBL order by id asc";
  8. emit st->sig_selectSql(10001, sql);
  9. }
  10. void MainWindow::slot_res_select(int tid, bool res, QString msg, QList<QSqlRecord> data)
  11. {
  12. if (tid != 10001) { ... }
  13. else {
  14. if (res) {
  15. for (int i=0; i<data.count(); i++) {
  16. int uid = data.at(i).value("id").toInt();
  17. QString email = data.at(i).value("email").toString();
  18. }
  19. }
  20. }
  21. }