【Qt之QSqlTableModel】介绍及使用

【Qt之QSqlTableModel】介绍及使用

描述

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

QSqlTableModel是一个高级接口,用于从单个表中读写数据库记录。
它建立在较低级别的QSqlQuery之上,可用于向QTableView等视图类提供数据。
例如:

   QSqlTableModel *model = new QSqlTableModel(parentObject, database);
   // 设置表
   model->setTable("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 name
   view->show();

以上代码:

  • 设置SQL表的名称和编辑策略
  • 然后设置视图头中显示的标签
  • 编辑策略指示用户在视图中所做的更改何时实际应用于数据库,取值为OnFieldChange、OnRowChange、OnManualSubmit。

QSqlTableModel也可以用编程方式访问数据库,而不需要绑定到视图:

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

以上代码:

  • 代码片段从employee查询SELECT *的结果集中的记录4中提取工资字段
  • 可以使用setFilter()设置过滤器,或者使用setSort()修改排序顺序
  • 最后,必须调用select()来用数据填充模型。

表模型示例说明了如何使用QSqlTableModel作为QTableView的数据源。

QSqlTableModel不直接支持外键。
如果要解析外键,请使用QSqlRelationalTableModelQSqlRelationalDelegate

常用方法

  1. 枚举:QSqlTableModel::EditStrategy
    此枚举类型描述在编辑数据库中的值时选择的策略。
常量描述解释
QSqlTableModel::OnFieldChange0All changes to the model will be applied immediately to the database.对模型的所有更改将立即应用于数据库。
QSqlTableModel::OnRowChange1Changes to a row will be applied when the user selects a different row.当用户选择另一行时,将应用对一行的更改。
QSqlTableModel::OnManualSubmit2All changes will be cached in the model until either submitAll() or revertAll() is called.在调用submitAll()或revertAll()之前,所有更改都将缓存在模型中。

注意:为了防止只将部分初始化的行插入数据库,OnFieldChange的行为将像OnRowChange一样用于新插入的行。
因此,一般设置为手动刷新:

   pTableModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
  1. QSqlDatabase database() const
    获取模型连接的数据库对象。

  2. EditStrategy editStrategy() const
    返回当前的编辑策略。

  3. int fieldIndex(const QString &fieldName) const
    返回字段的索引,返回-1表示此模型内没有该字段。

    qDebug().noquote() << "当前字段索引 :" << pTableModel->fieldIndex("name");
  1. QString filter() const
    获取当前设置的过滤。

  2. bool insertRecord(int row, const QSqlRecord &record)
    在位置行插入记录。如果row为负数,则将该记录追加到末尾。内部调用insertRows()setRecord()
    如果记录可以插入,则返回true,否则返回false
    更改立即提交OnFieldChangeOnRowChange。失败不会在模型中留下新行。

    QSqlRecord record = pTableModel->record();
    qDebug().noquote() << "获取字段 :" << record.fieldName(0) << record.fieldName(1) << record.fieldName(2) << record.fieldName(3);
    record.setValue("field0", "666");
    record.setValue("field1", "666");
    record.setValue("field2", 666);
    record.setValue("field3", "666");
    
    // 插入记录
     // -1 表示在表的末尾插入新记录
    qDebug().noquote() << "插入 :" << pTableModel->insertRecord(pTableModel->rowCount(), record);
  1. bool isDirty(const QModelIndex &index) const
    如果索引index处的值是被改的,则返回true,否则返回false。脏值是在模型中被修改但尚未写入数据库的值。
    如果index无效或指向不存在的行,则返回false。
    此函数还有重载:bool isDirty() const
    意思就是:
    这是一个重载函数。
    如果模型包含未提交给数据库的修改值,则返回true,否则返回false。

  2. QSqlIndex primaryKey() const
    返回当前表的主键,如果表未设置或没有主键,则返回空QSqlIndex

  3. QSqlRecord record(int row) const
    返回模型中第一行的记录。
    如果row是有效行的索引,则将使用该行的值填充记录。
    如果模型没有初始化,将返回一个空记录。
    此函数还有重载:QSqlRecord record() const
    意思就是:
    这是一个重载函数。
    返回一个空记录,只有字段名称;此函数可用于检索记录的字段名。

  4. void revertRow(int row)
    恢复指定行的所有改变。

  5. void setFilter(const QString &filter)
    将当前过滤器设置为filter
    过滤器是一个不带关键字WHERESQL WHERE子句(例如,name='Josephine')。
    如果已经用数据库中的数据填充了模型,则模型将使用新的过滤器重新选择它。否则,过滤器将在下次调用select()时应用。

    QSqlTableModel* pTableModel = new QSqlTableModel(ui->tableView, db);
    pTableModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
    pTableModel->setTable("\"tableTest\"");
    // 未选择
    pTableModel->setFilter("name = '666'");
    // 执行setFilter操作
    pTableModel->select();
    if (pTableModel->lastError().isValid()) {
        qDebug() << "Error:" << pTableModel->lastError();
    }
    ui->tableView->setModel(pTableModel);


    // 当前字段索引
    qDebug().noquote() << "当前字段索引 :" << pTableModel->fieldIndex("name");
    // 重新选择
    pTableModel->setFilter("name = '22'"); 
  1. bool setRecord(int row, const QSqlRecord &values)
    将值应用于模型中的行。源字段和目标字段按字段名映射,而不是按记录中的位置映射。
    请注意,将保留值中生成的标志,并确定在将更改提交给数据库时是否使用相应的字段。调用者应该记得将数据库提供值的字段(比如自动增加的ID)的生成标志设置为FALSE。
    对于编辑策略OnFieldChangeOnRowChange,只有当其他行没有缓存更改时,一行才可能接收到更改。更改会立即提交。提交的更改在失败时不会恢复。
    如果所有值都可以设置,则返回true;否则返回false

  2. void setSort(int column, Qt::SortOrder order)
    将列的排序顺序设置为order。这不会影响当前数据,要使用新的排序顺序刷新数据,请调用select()。

  3. void setTable(const QString &tableName)
    将模型操作的数据库表设置为tableName。不从表中选择数据,但获取其字段信息。
    要用表的数据填充模型,请调用select()
    可以使用lastError()检索错误信息。

    pTableModel->setTable("\"tableTest\"");
  1. QString tableName() const
    获取当前选择的表名

槽函数

  1. bool submit()
    QAbstractItemModel::submit()重新实现。
    当用户停止编辑当前行时,项委托调用这个重新实现的槽。
    如果模型的策略设置为OnRowChangeOnFieldChange,则提交当前编辑的行。对OnManualSubmit策略不做任何操作。
    使用submitAll()OnManualSubmit策略提交所有挂起的更改。
    成功时返回true;否则返回false。使用lastError()查询详细的错误信息。
    不会自动重新填充模型。提交的行在成功时从数据库中刷新。

  2. bool submitAll()
    提交所有挂起的更改,并在成功时返回true。错误时返回false,详细的错误信息可以通过lastError()获得。
    OnManualSubmit中,一旦成功,模型将被重新填充。任何呈现它的视图都将失去其选择。
    注意:在OnManualSubmit模式下,当submitAll()失败时,已经提交的更改不会从缓存中清除。这允许事务回滚并重新提交,而不会丢失数据。

  3. void revert()
    QAbstractItemModel::revert()重新实现。
    当用户取消编辑当前行时,项目委托调用这个重新实现的槽。
    如果模型的策略设置为OnRowChangeOnFieldChange,则恢复更改。对OnManualSubmit策略不做任何操作。 使用revertAll()来恢复OnManualSubmit策略的所有挂起的更改,或者使用revertRow()`来恢复特定的行。

  4. void revertAll()
    重置所有缓存操作。

  5. bool select()
    使用通过setTable()设置的表中的数据填充模型,使用指定的筛选和排序条件,如果成功则返回true;否则返回false。
    注意:调用select()将恢复所有未提交的更改并删除所有插入的列。

  6. bool selectRow(int row)
    使用与主键值匹配的数据库表行中的值刷新模型中的行。如果没有主键,所有列值必须匹配。如果没有找到匹配的行,模型将显示空行。
    如果成功返回true;否则返回false。

信号

  1. void beforeDelete(int row)
    该信号由deleteRowFromTable()在从当前活动的数据库表中删除行之前发出。
  2. void beforeInsert(QSqlRecord &record)
    该信号由insertRowIntoTable()在将新行插入当前活动的数据库表之前发出。要插入的值存储在记录中,可以在插入之前进行修改。
  3. void beforeUpdate(int row, QSqlRecord &record)
    在使用record中的值更新当前活动数据库表中的行之前,updateRowInTable()会发出这个信号。
    注意,只有标记为生成的值才会被更新。生成标志可以用QSqlRecord::setGenerated()设置,用QSqlRecord::isGenerated()检查。
  4. void primeInsert(int row, QSqlRecord &record)
    当在当前活动的数据库表的给定行中发起插入时,该信号由insertRows()发出。record参数可以写入(因为它是一个引用),例如用默认值填充一些字段,并设置字段的生成标志。在处理此信号时,不要尝试通过setData()或setRecord()等其他方法编辑记录。

示例

在.pro中添加QT += sql
包含头文件

        #include <QDebug>
        #include <QSqlTableModel>
        #include <QSqlDatabase>
        #include <QSqlRecord>
        #include <QSqlError>

初始化

            QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
            db.setDatabaseName("xxx/xxx/xxx.db");
            bool ok = db.open();
        
            QSqlTableModel* pTableModel = new QSqlTableModel(ui->tableView, db);
            pTableModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
            pTableModel->setTable("\"tableTest\"");
            pTableModel->setFilter("name = '666'");
        
            pTableModel->select();
            if (pTableModel->lastError().isValid()) {
                qDebug() << "Error:" << pTableModel->lastError();
            }
            ui->tableView->setModel(pTableModel);
        
        
            // 当前字段索引
            qDebug().noquote() << "当前字段索引 :" << pTableModel->fieldIndex("name");
            pTableModel->setFilter("name = '666'");         

插入

            QSqlTableModel* pTableModel = (QSqlTableModel*)ui->tableView->model();
            // 实现以下代码,插入空行后进行数据插入,会插入失败。
            //pTableModel->insertRow(pTableModel->rowCount());
          
            QSqlRecord record = pTableModel->record();
            qDebug().noquote() << "获取字段 :" << record.fieldName(0) << record.fieldName(1) << record.fieldName(2) << record.fieldName(3);
            record.setValue("field0", "66");
            record.setValue("field1", "66");
            record.setValue("field2", 66);
            record.setValue("field3", "66");
          
            // 插入记录
            qDebug().noquote() << "插入 :" << pTableModel->insertRecord(pTableModel->rowCount(), record); // -1 表示在表的末尾插入新记录
                        

提交

            QSqlTableModel* pTableModel = (QSqlTableModel*)ui->tableView->model();
            pTableModel->submitAll();                   
  • 31
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 【QT数据库实战之qsqltablemodel模型.rar是一份实用的资料,它详细介绍了如何利用QT框架中的QSqlTableModel模型来操作数据库,并且提供了完整的代码示例和演示视频,为学习者提供了更加直观、全面的学习体验。 其中,资料着重介绍了QSqlTableModel模型的使用方法和常见操作,包括如何建立数据源、如何进行数据查询、修改和删除等。此外,它还提供了丰富的实例程序,通过这些程序,学习者可以深入了解不同的应用场景下如何使用QSqlTableModel模型来完成数据处理的操作。 在实际学习中,这份资料可以作为一个很好的参考教材。它清晰地展示了QT框架的优势和便捷性,帮助学习者快速了解QSqlTableModel模型的使用方法和注意事项,提高了学习效率。 总的来说,【QT数据库实战之qsqltablemodel模型.rar是一份很有价值的学习资料,对于想深入学习QT数据库编程的开发者来说,是一份不可多得的资料。 ### 回答2: 【qt数据库实战之qsqltablemodel模型.rar 是一个实战教程,主要讲解 qsqltablemodel 模型在 Qt 数据库编程中的应用。该教程适合于想要学习 Qt 数据库编程的开发者,熟悉 C++ 语言以及 Qt 编程基础的开发者更容易理解和掌握其中的内容。 该教程主要分为三个部分:Qt 数据库连接的建立、qsqltablemodel 模型的使用以及 qsqlquerymodel 模型的使用。通过阅读该教程,开发者可以学习到如何运用 Qt 自带的数据库模块进行数据库编程,如何使用 qsqltablemodel 模型操作数据库,并且能够理解 qsqlquerymodel 模型的用处和优劣势。 在该教程中,开发者将会联系到一个实际的案例,即利用 qsqltablemodel 模型开发一个图书管理系统。通过对该案例的开发实践,开发者可以更好地理解 qsqltablemodel 模型的实际使用,掌握 qsqltablemodel 模型在数据库编程中的应用。 总之,【qt数据库实战之qsqltablemodel模型.rar 是一份非常实用的 Qt 数据库编程教程,可以帮助开发者对 Qt 数据库编程有更深入的了解和掌握。 ### 回答3: qt 数据库实战之 qsqltablemodel 模型.rar 是一个用于学习 qt 数据库编程的资源文件。qsqltablemodelqt 框架中的一个模型类,可以用于对数据库进行增删改查操作,并在 qt 的相关控件中显示查询结果。 该资源文件包含了一个完整的 qt 项目,其中包含了对 qsqltablemodel 类的使用示例,可以通过该示例快速入门 qt 数据库编程,掌握 qsqltablemodel 类的使用方法。该示例包含了对 sqlite 数据库的连接和操作,可以让你了解 sqlite 数据库的基本用法。 此外,该资源文件还包含了一个使用 qsqltablemodel 类和 qt 控件实现的简单的学生管理系统,可以让你更深入地了解 qsqltablemodel 类的使用qt 数据库编程的实战应用。通过学习和实践,你可以在实际应用中运用到这些知识,提高自己的编程水平和实践能力。 总之,qt 数据库实战之 qsqltablemodel 模型.rar 是一份非常有价值的 qt 数据库编程资源,适合想要学习和掌握 qt 数据库编程的开发人员使用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FreeLikeTheWind.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值