本文介绍: 【Qt之QSqlRelationalTableModel描述使用

描述

QSqlRelationalDelegate链接: https://blog.csdn.net/MrHHHHHH/article/details/134690139

QSqlRelationalTableModel类为单个数据库表提供了一个编辑数据模型,并支持外键
QSqlRelationalTableModel行为类似于QSqlTableModel,但允许将列设置为其他数据库表的外键

左边的屏幕截图显示了QTableView一个普通的QSqlTableModel外键(城市和国家)不能解析为人类可读的值。
右边的屏幕截图显示了一个QSqlRelationalTableModel外键解析为人类可读的文本字符串

下面的代码片段展示如何建立QSqlRelationalTableModel:在这里插入图片描述

	  model->setTable("employee");
      model->setRelation(2, QSqlRelation("city", "id", "name"));
      model->setRelation(3, QSqlRelation("country", "id", "name"));

setRelation()函数调用两个表之间建立关系。第一个调用指定employee中的第2列是一个外键,它映射city的字段id,并且视图应该用户显示城市名称字段第二个调用对列3执行类似的操作

如果使用读写QSqlRelationalTableModel,可能希望在视图上使用QSqlRelationalDelegate。与默认委托不同,QSqlRelationalDelegate为作为其他表的外键字段提供了一个组合框。要使用该类,只需在带有QSqlRelationalDelegate实例视图调用QAbstractItemView::setItemDelegate():

	  QTableView *view = new QTableView;
      view->setModel(model);
      view->setItemDelegate(new QSqlRelationalDelegate(view));

relationaltablemodel示例演示了如何将QSqlRelationalTableModelQSqlRelationalDelegate结合使用,为表提供外键支持
在这里插入图片描述
注意:

常用方法

  1. 枚举enum JoinMode
常量 描述 解释
QSqlRelationalTableModel::InnerJoin 0 – Inner join mode, return rows when there is at least one match in both tables. 内部连接模式,当两个表中至少有一个匹配返回行。
QSqlRelationalTableModel::InnerJoin 1 – Left join mode, returns all rows from the left table (table_name1), even if there are no matches in the right table (table_name2). — 左连接模式返回左表(table_name1)中的所有行,即使右表(table_name2)中没有匹配。
  1. void setJoinMode(QSqlRelationalTableModel::JoinMode joinMode)

设置SQL joinMode以显示或隐藏外键NULL的行。在InnerJoin模式(默认)中,这些行将不会显示:如果想显示它们,请使用LeftJoin模式

  1. QSqlRelation relation(int column) const

返回列的关系,如果没有设置关系,则返回无效关系。

  1. QSqlTableModel* relationModel(int column) const

返回一个QSqlTableModel对象用于访问列为外键的表,如果给定没有关系,则返回0。
返回的对象QSqlRelationalTableModel所有。

  1. void setRelation(int column, const QSqlRelation &relation)

指定的列是由关系指定的外索引
Ex:

    model->setTable("employee");
    model->setRelation(2, QSqlRelation("city", "id", "name"));

setRelation()调用指定employee表中的第2列是一个外键,它映射city字段id,并且视图应该用户显示城市名称字段
注意:表的主键不能包含与另一个表的关系。

  1. void clear()

重新实现QSqlQueryModel::clear()方法用于清除模型数据

  1. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const

索引引用的项返回存储给定角色下的数据。
注意:如果没有要返回的值,则返回无效的QVariant,而不是返回0`。

  1. bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex())

支持功能的模型上,从模型中删除parent给定列开始的计数列。
如果列已成功删除,则返回true;否则返回false
基类实现不做任何事情并返回false
如果实现了自己的模型,如果希望支持删除,则可以重新实现此函数。或者,可以提供自己的API来修改数据。

  1. bool select()

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

  1. bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)

QAbstractItemModel::setData()重新实现。
具有指定索引的项中角色的数据设置为给定的值。根据编辑策略的不同,值可以立即应用于数据库,也可以缓存在模型中。
如果值可以设置,则返回true,如果出现错误(例如,如果索引超出边界)则返回false
对于关系列value必须是索引,而不是显示值。索引也必须存在于被引用的表中,否则函数返回false

示例

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

#include <QtWidgets>
#include <QtSql>

#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
  1. // 创建表及插入数据
static bool createConnection()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    // 创建内存
    db.setDatabaseName(":memory:");
    if (!db.open()) {
        QMessageBox::critical(0, qApp->tr("Cannot open database"),
            qApp->tr("Unable to establish a database connection.n"
                     "This example needs SQLite support. Please read "
                     "the Qt SQL driver documentation for information how "
                     "to build it.nn"
                     "Click Cancel to exit."), QMessageBox::Cancel);
        return false;
    }

    // 使用SqlQuery进行表创建及数据添加
    QSqlQuery query;
    query.exec("create table person (id int primary key, "
               "firstname text, lastname int)");
    query.exec("insert into person values(0, '0', 0)");
    query.exec("insert into person values(1, '1', 1)");
    query.exec("insert into person values(4, '2', 2)");
    query.exec("insert into person values(3, '3', 3)");

    query.exec("create table itemF (id int primary key,"
                                             "firstName varchar(20))");
    query.exec("insert into itemF "
               "values(0, '小明')");
    query.exec("insert into itemF "
               "values(2, '小华')");
    query.exec("insert into itemF "
               "values(3, '小芳')");
    query.exec("insert into itemF "
               "values(1, '小诸葛')");

    query.exec("create table itemL (id int, lastName varchar(20))");
    query.exec("insert into itemL values(0, '赵')");
    query.exec("insert into itemL values(1, '钱')");
    query.exec("insert into itemL values(2, '孙')");
    query.exec("insert into itemL values(3, '李')");

    return true;
}
  1. // 初始化模型
void initializeModel(QSqlRelationalTableModel *model)
{
    // 设置表名
    model->setTable("person");
    // 手动提交
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    // 设置外键
    model->setRelation(1, QSqlRelation("itemF", "id", "firstName"));
    model->setRelation(2, QSqlRelation("itemL", "id", "lastName"));
    // 添加表头
    model->setHeaderData(0, Qt::Horizontal, QObject::tr("id"));
    model->setHeaderData(1, Qt::Horizontal, QObject::tr("firstName"));
    model->setHeaderData(2, Qt::Horizontal, QObject::tr("lastName"));
    // 刷新
    model->select();
}

上述代码

  • 创建了一个名为 person 的表,并添加了一些数据。
  • 创建两个名为 itemFitemL 的表,并添加了一些具有 idfirstNamelastName 属性的数据
  • 这些表和数据将用于后面的 QSqlRelationalTableModel 示例
  • 最后,该函数返回 true
  1. // 创建视图
QTableView *createView(const QString &amp;title, QSqlTableModel *model)
{
    QTableView *view = new QTableView;
    // 设置模型
    view->setModel(model);
    // 设置委托,这样可以下拉框显示
    view->setItemDelegate(new QSqlRelationalDelegate(view));
    view->setWindowTitle(title);
    return view;
}

上述代码

  1. // 调用
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    if (!createConnection())
        return 1;

    QSqlRelationalTableModel model;

    initializeModel(&amp;model);

    QTableView *view = createView(QObject::tr("Relational Table Model"), &amp;model);
    view->show();

    return app.exec();
}

结果

在这里插入图片描述

注意

结论

重剑无锋,大巧不工

原文地址:https://blog.csdn.net/MrHHHHHH/article/details/134686926

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_9499.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注