详细描述


QSqlTableModel 类为单个数据库表提供了一个可编辑的数据模型。


QSqlTableModel 是一个从单个表读取和写入数据库记录的高级接口。它构建在较低级别的QSqlQuery之上,并且可以用来提供数据给诸如QTableView的视图类(以查看数据)。


例子:


QSqlTableModel *model = new QSqlTableModel(parentObject, database);
    model->setTable("employee");  //指定模型要关联的表(employee)
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select();  //查询表格数据
    model->setHeaderData(0, Qt::Horizontal, tr("Name"));
    model->setHeaderData(1, Qt::Horizontal, tr("Salary"));

    QTableView *view = new QTableView;
    view->setModel(model);
    view->hideColumn(0); // don't show the ID
    view->show();

我们设置了SQL表的名称和编辑策略,然后设置了视图头中要显示的标签。该编辑策略指示用户在视图中所做的实际更改实际应用于数据库。可能的值是 

OnFieldChange,

OnRowChange, 和

OnManualSubmit 。


 


还可以使用 QSqlTableModel以编程方式访问数据库,而不用将其绑定到视图。


例子:


QSqlTableModel model;
      model.setTable("employee");
      model.select();
      int salary = model.record(4).value("salary").toInt();

上面的代码片段从查询SELECT * from employee 的结果集的记录4中提取 salary(工资)字段。


可以使用setFilter()设置过滤器,或者使用setSort()修改排序顺序。最后,你必须调用select()来给模型填充数据。



Table Model Example(可在Qt帮助中搜索)例子演示了如何使用 QSqlTableModel作为 QTableView 的数据源。



QSqlTableModel不提供对外键的直接支持。如果你想使用外键你可以使用 QSqlRelationalTableModel 和  QSqlRelationalDelegate 这两个类。



相关成员


enum QSqlTableModel::EditStrategy

这个enum(枚举)描述了在数据库编辑值时要选择哪种策略。


枚举常量


描述

QSqlTableModel::OnFieldChange

0

模型的任何更改将立即更新到数据库

QSqlTableModel::OnRowChange

1

当用户选择不同的行时,将应用对行(改动过的行)的更改

QSqlTableModel::OnManualSubmit

2

所有更改将在模型中缓存,直到submitAll() 或者 revertAll() 被调用。

注意:为了防止只有部分初始化的行插入到数据库中,OnFieldChange 将像新插入行的 OnRowChange 一样。



相关API


QSqlTableModel::QSqlTableModel(QObject *parent = Q_NULLPTR, QSqlDatabase db = QSqlDatabase())

创建一个空的 

QSqlTableModel ,将其父节点设置为参数parent,并将其数据库连接设置为参数db(数据库连接)。如果数据库连接参数db无效,将会使用默认的数据库连接。


OnRowChange



[virtual] QSqlTableModel::~QSqlTableModel()

销毁对象并释放已经分配的任何资源。



[signal] void QSqlTableModel::beforeDelete(int row)

这个信号是由

deleteRowFromTable() 在第row行被从当前活跃的数据库表中删除之前发射的。



[signal] void QSqlTableModel::beforeInsert(QSqlRecord &record)

这个信号是由insertRowIntoTable()在当前活跃的数据库表被插入一条新行(数据)之前发射的。将要插入的值存储在记录record中,且可以在插入之前修改它。



[signal] void QSqlTableModel::beforeUpdate(int row, QSqlRecord &record)

这个信号是由updateRowInTable()在当前活跃的数据库表第row行被来自参数record的值更新之前被发射。


注意只有被标记为已经生成的值才会被更新。生成标志可以通过QSqlRecord::setGenerated() 设置 并通过QSqlRecord::isGenerated() 校验。



[virtual] void QSqlTableModel::clear()

重新实现

QSqlQueryModel::clear()。



[virtual] QVariant QSqlTableModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const

重新实现

QAbstractItemModel::data()。



QSqlDatabase QSqlTableModel::database() const

返回模型的数据库连接。



[virtual protected] bool QSqlTableModel::deleteRowFromTable(int row)

从当前活跃的数据库表删除给定的行row。


这是一个直接在数据库上操作的底层方法,不应该直接调用。使用removeRow()或者removeRows()去删除值。模型将根据它的编辑侧率决定什么时候去修改数据库。


如果row行被删除则返回true,否则返回false。



EditStrategy QSqlTableModel::editStrategy() const

返回模型当前的编辑策略。



int QSqlTableModel::fieldIndex(const QString &fieldName) const

返回字段fieldName的索引,如果模型中没有相应的字段存在则返回-1。



QString QSqlTableModel::filter() const

返回当前设置的过滤器。



[virtual] Qt::ItemFlags QSqlTableModel::flags(const QModelIndex &index) const

重新实现

QAbstractItemModel::flags()。



[virtual] QVariant QSqlTableModel::headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const

重新实现

QAbstractItemModel::headerData()。



[virtual protected] QModelIndex QSqlTableModel::indexInQuery(const QModelIndex &item) const

重新实现

QSqlQueryModel::indexInQuery()。


返回模型中给定项的数据库结果集的值的索引。


如果没有列或行被插入,删除或者移动返回值和参数item是相等的。


如果item超过边界或者item没有指向结果集中的值则返回一个无效的模型索引。



bool QSqlTableModel::insertRecord(int row, const QSqlRecord &record)

在位置row(行)插入记录record。如果参数row是负数,记录record将会被添加到末尾。内部调用

insertRows() 和 

setRecord() 。


如果记录可以插入返回true,否则返回false。


对于 OnFieldChangeOnRowChange 更改将会立即提交。如果插入失败不会在模型中留下一个新行。



[virtual protected] bool QSqlTableModel::insertRowIntoTable(const QSqlRecord &values)

在当前活跃的数据库表中插入值values。


这是一个在数据库上直接操作的底层方法,不应该直接调用。使用insertRow()和setData插入数据。模型将会根据编辑策略决定什么时候去修改数据库。


如果值可以被插入返回true,否则返回false。可以通过lastError()检索错误信息。



[virtual] bool QSqlTableModel::insertRows(int row, int count, const QModelIndex &parent = QModelIndex())

重新实现

QAbstractItemModel::insertRows() 。


在位置row(行)插入count条空记录。注意参数parent必须是无效的,因为模型不支持父子关系。


对于编辑策略 OnFieldChangeOnRowChange,一次只能插入一条并且模型可能不包含其他缓存的更改。
将为每一个行行发射 primeInsert() 信号。如果你想要以默认值初始化新行就关联该信号。


不管是什么编辑策略都不要提交行。


如果参数超过边界或者row(行)不能插入返回false;否则返回true。



bool QSqlTableModel::isDirty(const QModelIndex &index) const

如果在索引index的值是脏的返回true,否则返回false。“脏值”指的是那些在模型中被修改的却没有被写入数据库的值。


如果索引index是无效的或者指向一个不存在的行,则返回false。



bool QSqlTableModel::isDirty() const

这是一个重载函数。


如果模型包含已经修改却没有提交给数据库的值(即“脏值”)则返回true,否则返回false。



[virtual protected] QString QSqlTableModel::orderByClause() const

根据当前设置的排序顺序返回一个SQL ORDER BY 子句。



QSqlIndex QSqlTableModel::primaryKey() const

返回当前库表的主键,或者如果该表没有设置或者没有主键则返回一个空的QSqlIndex。



[protected] QSqlRecord QSqlTableModel::primaryValues(int row) const

返回一个记录,其中包含主键中的字段,并将其(返回的记录)设置为row(行)的值。如果没有定义主键,返回的记录将会包含所有的字段。



[signal] void QSqlTableModel::primeInsert(int row, QSqlRecord &record)

这个信号是由insertRows()发射的,当在当前数据库表上给定行启动插入时。参数record可以被写入(因为它是一个引用),比如以默认值填充一些字段和设置字段的生成标志。不要在处理这个信号的时候尝试通过诸如setData()或者setRecord()等其它方法去编辑该记录record。


QSqlRecord QSqlTableModel::record() const

这是一个重载函数。


它返回一个空的记录,只包含字段名。这个函数可以用来检索记录的字段名。



QSqlRecord QSqlTableModel::record(int row) const

返回模型中在row(行)位置的记录。


如果参数row是一个有效行的索引,记录会被填充上该行的值。


如果模型未初始化,将会返回一条空记录。



[virtual] bool QSqlTableModel::removeColumns(int column, int count, const QModelIndex &parent = QModelIndex())

重新实现

QAbstractItemModel::removeColumns()。


从模型parent的索引column开始删除count列。


如果这些列成功被删除返回true,否则返回false。



[virtual] bool QSqlTableModel::removeRows(int row, int count, const QModelIndex &parent = QModelIndex())

重新实现

QAbstractItemModel::removeRows()。


删除从row(行)开始的count行。由于该模型不支持分层的结构,所以参数parent必须为一个无效的模型索引,


OnManualSubmit,从数据库删除的行将会延迟直到调用submitAll()。


对于 OnFieldChangeOnRowChange,一次只能删除一行,并且只能在其他行没有缓存的更改时才能删除。删除会马上被提交到数据库。
该模型保留了一个空白行用于成功删除行,直到调用select()重新刷新。


删除失败后,该操作不会在模型中恢复。应用可以重新提交或恢复。


插入但没有成功提交的行会立即从模型中删除。


在从数据库删除一行数据之前,发射beforeDelete()信号。


如果row < 0 或者 row + count > rowCount(),没有动作会被执行并返回false。如果所有行都可以被删除,返回true;否则返回false。可以使用lastError()检索详细的数据库错误信息。



[virtual slot] void QSqlTableModel::revert()

重新实现

QAbstractItemModel::revert()。


这个重新实现的槽函数当用户取消编辑当前行时由item的委托调用。


如果模型的编辑策略被设置为 OnRowChangeOnFieldChange  则取消更改。对于 OnManualSubmit策略什么也不做。


使用revertAll()恢复 OnManualSubmit 策略和  revertRow() 的挂起所有更改,以恢复特定的行。



[slot] void QSqlTableModel::revertAll()

恢复所有挂起的更改。



[virtual] void QSqlTableModel::revertRow(int row)

为特定行恢复所有的更改。



[virtual] int QSqlTableModel::rowCount(const QModelIndex &parent = QModelIndex()) const

重新实现

QAbstractItemModel::rowCount()。



[virtual slot] bool QSqlTableModel::select()

使用通过setTable()设置的表的数据填充模型,使用特定的过滤器和排序条件,如果成功返回true;否侧返回false。


注意:调用select()将会恢复所有未提交的更改和删除所有插入的列。




[virtual slot] bool QSqlTableModel::selectRow(int row)

刷新模型中的(row)行,其中的值来自与主键值匹配的数据库表的行。如果没有主键,所有列(字段)的值必须匹配。如果没有找到匹配的行,模型将会显示一个空行。


成功返回true;否则返回false。



[virtual protected] QString QSqlTableModel::selectStatement() const

返回内部使用的SQL SELECT语句来填充模型。该语句包含过滤器和ORDER BY子句。