Qt Version 5.14.0
QSqlQueryModel、QSqlTableModel、QSqlRelationalTableModel三个类可以用作Qt View相关显示类的数据源,比如QTableView、QListView和QTreeView。其中最常用的应该是QTableView,因为SQL语句的结果数据集必然是一个二维数据结构。
视图(Views)
视图的创建:新建一个视图,并给它设置一个数据源:
QTableView *view = new QTableView;
view->setModel(model);
iew->show();
设置视图不可编辑
view->setEditTriggers(QAbstractItemView::NoEditTriggers);
多个视图可以使用同一个数据模型(Model),当其中一个视图(View)中修改数据时,其它视图会立即刷新显示。
视图类在视图顶端显示标题栏(header),可以调用model的setHeaderData()函数来修改标题文本。以下代码将标题栏设为数据表的字段名称:
model->setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));
model->setHeaderData(0, Qt::Horizontal, QObject::tr("Name"));
model->setHeaderData(0, Qt::Horizontal, QObject::tr("City"));
model->setHeaderData(0, Qt::Horizontal, QObject::tr("Country"));
QTableView也有纵向标题栏,一般用于显示行号。使用QSqlTableModel::insertRows()插入新行时,新行对应的纵向标题栏显示“*”,直到修改被写入数据库,才会显示新行的行号。
同样的,当你调用removeRows()删除行时,修改被提交之前,标题栏对应行会显示“!”。
视图中的单元格显示的数据用委托(delegate)来完成渲染。默认的委托类是QItemDelegate,它能完成基本数据类型的渲染,如QString、int、QImage等等。当用户编辑视图中的某一项时,委托也负责提供编辑控件(editor widgets),比如一个comboBox。你可以通过继承QItemDelegate或QAbstractItemDelegate来实现自己的委托类。更多信息,详见Qt助手关键字Model/View Programming。
QSqlTableModel只能操作一个数据表,如果你需要一个可读写的模型,用它来操作任意结果数据集,那你可以继承QSqlQueryModle类,并重新实现flags()和setData()函数。以下函数使得query model的第一和第二个字段可读写:
Qt::ItemFlags EditableSqlModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags = QSqlQueryModel::flags(index);
if (index.column() == 1 || index.column() == 2)
flags |= Qt::ItemIsEditable;
return flags;
}
bool EditableSqlModel::setData(const QModelIndex &index, const QVariant &value, int )
{
if (index.column() < 1 || index.column() > 2)
return false;
QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(), 0);
int id = data(primaryKeyIndex).toInt();
clear();
bool ok;
if (index.column() == 1)
{
ok = setFirstName(id, value.toString());
}
else
{
ok = setLastName(id, value.toString());
}
refresh();
return ok;
}
bool EditableSqlModel::setFirstName(int personId, const QString &firstName)
{
QSqlQuery query;
query.prepare("update person set firstname = ? where id = ?");
query.addBindValue(firstName);
query.addBindValue(personId);
return query.exec();
}
一个自定义的模型还能实现许多功能,比如:设置背景颜色,设置编辑控件,提供toolTip,特别处理null值等等。
如果你想要外键显示成更人性化的字符串,可以使用QSqlRelationalTableModel类。而为了更好的显示效果,可以使用QSqlRelationalDelegate委托,它可以在你编辑外键值时提供下拉列表编辑控件。
详见Qt助手关键字:Relational Table Model。