QT快速读取显示SQLite3数据库数据

(本文为本人原创,请尊重个人劳动成果。未经本人许可,严禁转载!)

SQLite3是一个轻量级的文件数据库,拥有其他数据库无可比拟的高效率,其自身的C语言API已经能够满足大多数应用。蛋似,想要将数据直接显示在类似DataGrid控件中,光靠他自带的API可能就会遇到麻烦了。因为当数据量过大的时候,直接将所有数据数据都读到内存中来是一种低效、不靠谱的方法。此时,支持Model/View的QT就能帮上忙,快速解决这个问题。

QT的SQL模块


QT SQL是QT中负责处理数据库的模块,处理数据库之前,我们先要获取数据库的连接。

1.获取数据库连接

我们可以从QT文档中找到相应的API介绍:

The QSqlDatabase class represents a connection to a database.

一个QSqlDatabase类的对象,就是对数据库的一个连接。

我们可以通过下面的代码获取PostgreSQL数据库的连接,并打开数据库:

1
2
3
4
5
6
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
db.setHostName("acidalia");
db.setDatabaseName("customdb");
db.setUserName("mojito");
db.setPassword("J0a1m8");
bool ok = db.open();

其中,”QPSQL”表示的就是PostgreSQL的驱动(Driver),下面就是官方文档给出的各个驱动对应的字符串:

Driver Type Description
QDB2 IBM DB2
QIBASE Borland InterBase
QMYSQL MySQL Driver
QODBC ODBC Driver (includes Microsoft SQL Server)
QPSQL PostgreSQL Driver
QSQLITE SQLite version 3 or above
QSQLITE2 SQLite version 2
QTDS Sybase Adaptive Server

SQLite3并不需要设置用户名密码,因此要获取SQLite3连接的话,就得使用:

1
2
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("hehe.db");//hehe.db就是SQLite的文件名

2.在QTableView中显示

模式是QT的一大亮点,在该模式下,界面与数据分开处理,同时也增强了代码的可移植性(有关Model/VIew结构的详细信息,参见 这篇文章 ),例如,对SQLite数据库处理的算法,可以很容易的移植到SQL Server里面。QT中显示格网数据的Widget是QTableView,而对应的Model类则是QSqlQueryModelQSqlRelationalTableModel,二者区别就是,前者是只读的Model,后者为可编辑的并且支持外码。

下面几句代码就可以简单的将db链接的数据库显示在QTableView中:

1
2
3
4
5
QTableView* widget = new QTableView();
QAbstractTableModel* model = new SqlRelationalTableModel(NULL,db);
model->setTable("table1");//"table1"为数据库中某一张表的名称
model->select();//执行SQL的select语句,将数据显示在QTableView中
widget->setModel(model);

一个Demo


这个demo展示一个使用QT读取SQLIte数据库的程序。这个程序中打开SQLite3数据库文件后,库内每一个表都会单独显示在一个Tab页里面。界面如图:

Demo

在QtCreator中,新建一个GUI项目,其他都选默认参数。在ui文件中,添加一个QTabWidget,并删除其中所有的tab页。同时菜单中新建一个QAction,用以选择打开文件,并设置click对应的槽函数。

mainwindow.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:
void on_actionOpenSQLite3File_triggered();
void ReadDB(const QString &fileName);
private:
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QtSql>
#include <QTableView>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::on_actionOpenSQLite3File_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this,tr("Open a SQLite3 File"),QString(),"DB (*.db);;All files(*.*)");
if (fileName.isEmpty())
return;
ReadDB(fileName);
}

void MainWindow::ReadDB(const QString &fileName)
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(fileName);
if (!db.open())
return;
ui->tabWidget->clear();
QSqlQuery query("Select tbl_name From sqlite_master");
QStringList tableList;
while (query.next()) {
tableList << query.value(0).toString();
}
foreach (QString tableName, tableList) {
QTableView* widget = new QTableView(ui->tabWidget);
QSqlRelationalTableModel* model = new QSqlRelationalTableModel(NULL,db);
model->setTable(tableName);
model->select();
widget->setModel(model);
ui->tabWidget->addTab(widget,tableName);
}
}

常见问题


1.

打开文件后,TableView没有显示,并且输出窗口输出以下字符串:
QSqlDatabase: QSQLITE driver not loaded
QSqlDatabase: available drivers: QPSQL7 QPSQL QODBC3 QODBC

这说明QT没有找到sqlite的插件,这个插件一般在QT_DIR/plugins/sqldrivers,windows系统下的debug与release版插件分别为:qsqlited4.dllqsqlite4.dll。原因有两个,一是qt本身并没有带这个插件,需要从源码编译;二是QT并未找到plugins所在目录,这需要设置QT_PLUGIN_PATH环境变量为插件目录(例如C:\OSGeo4W64\apps\Qt4\plugins)。

2.

打开文件后,TableView没有显示,并且没有输出上述字符串

QT的sqlite插件还依赖于sqlite3.dll(Windows系统下),可将该dll放到程序所在目录下,或者PATH路径下