导入QSqlQueryModel类
QSqlQueryModel类为SQL结果集提供了一个只读数据模型,要使用这个类,头文件需要导入QSqlQueryModel库:
#include <QSqlQueryModel>
在qmake.pro文件中加入SQL数据库支持:
QT += sql
这个类提供了以下公共方法:
- QSqlQueryModel(QObject *parent = nullptr)
类的构造函数,用给定的父级创建一个空的QSqlQueryModel - virtual ~QSqlQueryModel()
析构函数,销毁对象并释放所有分配的资源 - virtual void clear()
清除模型并释放任何获取的资源 - QSqlError lastError() const QSqlQuery query()
返回数据库上发生的最后一个错误的信息 - QSqlQuery query() const
返回与此模型相关联的QSqlQuery - const QSqlRecord record(int row) const
返回包含当前查询字段信息的记录,如果row是有效行的索引,该记录将填充该行的值
如果模型没有初始化,将返回一个空记录。 - QSqlRecord record() const
这是一个重载函数,返回一个包含当前查询字段信息的空记录
如果模型没有初始化,将返回一个空记录。 - void setQuery(const QSqlQuery &query)
重置模型并将数据提供程序设置为给定的查询
请注意:该查询必须是活动的,并且不能是isForwardOnly()。如果设置查询时出现错误,lastError()可用于检索详细信息。
注意:调用setQuery()将删除任何插入的列 - void setQuery(const QString &query, const QSqlDatabase &db = QSqlDatabase())
对给定的数据库连接数据库执行查询,如果未指定数据库(或无效数据库),则使用默认连接
如果设置查询时出现错误,lastError()可用于检索详细信息
例如:
QSqlQueryModel model;
model.setQuery("select * from MyTable");
if (model.lastError().isValid())
qDebug() << model.lastError();
这个类提供了以下保护的方法:
- virtual QModelIndex indexInQuery(const QModelIndex &item) const
返回模型中给定项在数据库结果集中的值的索引,如果没有插入、移除或移动任何列或行,返回值与项相同 - virtual void queryChange()
每当查询发生变化时,都会调用该虚拟函数,默认实现什么也不做 - void setLastError(const QSqlError &error)
它允许派生类将数据库上发生的最后一个错误的值设置为error
重新实现了以下公共方法:
- virtual bool canFetchMore(const QModelIndex &parent = QModelIndex()) const override
重新实现: QAbstractItemModel::canFetchMore(const QModelIndex &parent) const
如果可以从数据库中读取更多的行,则返回true
父级应该始终是无效的QModelIndex
Qt 4.1中引入了这个功能。 - virtual int columnCount(const QModelIndex &index = QModelIndex()) const override
重新实现: QAbstractItemModel::columnCount(const QModelIndex &parent) const - virtual QVariant data(const QModelIndex &item, int role = Qt::DisplayRole) const override
重新实现: QAbstractItemModel::data(const QModelIndex &index, int role) const
返回指定项和角色的值,如果项目超出范围或出现错误,将返回无效的QVariant
QVariant MyModel::data(const QModelIndex &item, int role) const
{
if (item.column() == m_specialColumnNo) {
// 单独处理列
}
return QSqlQueryModel::data(item, role);
}
- virtual void fetchMore(const QModelIndex &parent = QModelIndex()) override
重新实现: QAbstractItemModel::fetchMore(const QModelIndex &parent)
从数据库中获取多行,要强制提取整个结果集,可以使用以下方法:
while (myModel->canFetchMore())
myModel->fetchMore();
-
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override
重新实现: QAbstractItemModel::headerData(int section, Qt::Orientation orientation, int role) const
在指定方向的标题部分中返回给定角色的标题数据 -
virtual bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override
重新实现: QAbstractItemModel::insertColumns(int column, int count, const QModelIndex &parent)
在column列索引处插入count列到模型中,如果列在边界内,则返回true否则返回false
默认情况下,插入的列为空,要用数据填充它们,请重新实现 data()并单独处理任何插入的列: -
virtual bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override
重新实现: QAbstractItemModel::removeColumns(int column, int count, const QModelIndex &parent)
从 column索引列开始从模型中移除count列,父参数必须始终是无效的QModelIndex,因为模型不支持父子关系,移除列有效地隐藏了它们,它不影响底层的QSqlQuery -
virtual QHash<int, QByteArray> roleNames() const override
重新实现: QAbstractItemModel::roleNames() const,返回模型的角色名称
Qt只为QSqlQueryModel定义了一个角色:
Qt Role: Qt::DisplayRole
QML Role Name:display -
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override
重新实现: QAbstractItemModel::rowCount(const QModelIndex &parent) const
如果数据库支持返回查询的大小,则返回当前查询的行数。否则,返回客户端上当前缓存的行数。 -
virtual bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override
重新实现: QAbstractItemModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
将value设置为指定角色的指定方向上的标题
如果方向为 Qt::Horizontal,并且该节引用了有效的节,则返回true否则返回false
请注意,此函数不能用于修改数据库中的值,因为模型是只读的
基本用法
QSqlQueryModel是一个高级接口,用于执行SQL语句和遍历结果集,它建立在较低级别的QSqlQuery之上,可用于向视图类(如QTableView)提供数据。例如:
QSqlQueryModel *model = new QSqlQueryModel;
model->setQuery("SELECT name, salary FROM employee");
model->setHeaderData(0, Qt::Horizontal, tr("Name"));
model->setHeaderData(1, Qt::Horizontal, tr("Salary"));
QTableView *view = new QTableView;
view->setModel(model);
view->show();
首先设置模型的查询,然后设置视图的行标签。
QSqlQueryModel也可用于以编程方式访问数据库,而无需将其绑定到视图:
QSqlQueryModel model;
model.setQuery("SELECT name, salary FROM employee");
int salary = model.record(4).value("salary").toInt();
上面的代码片段从SELECT查询的结果集中的记录4提取salary字段,由于工资是第二列(或列索引1),我们可以将最后一行改写如下:
int salary = model.data(model.index(4, 1)).toInt();
默认情况下,模型是只读的。要使它成为读写的,必须将其子类化,并重新实现setData()和flags()。另一个选择是使用QSqlTableModel,它提供了一个基于单个数据库表的读写模型。
QSqlTableModel实例用法
在示例中将展示如何使用QSqlQueryModel显示查询结果。还展示了如何子类化QSqlQueryModel以向用户展示之前定制数据的内容,以及如何创建基于QSqlQueryModel的读写模型
- 打开Qt Creator,按“Ctrl+N”快捷键,显示“新建文件或项目”对话框:
在【选择一个模板】中选择“Applicaton”,中间选择"Qt Widgets Application",点击"Choose…"按钮。 - 在【项目介绍和位置】的名称 输入:SqlQueryModelSample,并选择项目存放路径:
其它都为默认,直到完成。 - 双击mainwindow.ui,为主窗体添加四个QPushButton,分别双击按钮,把显示文本修改为“只读”,“可编辑”,“自定义”,“EXIT”
- 右击按钮,选择“转到槽”,为“只读”按钮槽函数
- 点击“clicked()",再点击”OK“
- 同样的操作,为其它三个按钮添加槽函数,完成之后,程序自动在mainwindow.h头文件中添加如下代码:
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
- 自动在mainwindow.cpp中添加实现函数:
void MainWindow::on_pushButton_clicked()
{
}
void MainWindow::