【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结合使用,为表提供外键支持。
在这里插入图片描述
注意:

  • 表必须声明主键。
  • 表的主键可能不包含对另一个表的关系。
  • 如果关系表包含引用引用表中不存在的行的键,则包含无效键的行将不通过模型公开。用户或数据库有责任维护引用完整性。
  • 如果关系的显示列名称也用作关系表中的列名称,或者如果它在多个关系中用作显示列名称,则会被别名。别名是关系的表名、显示列名和一个唯一的id,用下划线连接(例如tablename_columnname_id)。QSqlRecord::fieldName()将返回别名列名。当检测到重复时,所有重复显示列名的出现都会被别名,但不会对主表中的列名进行任何别名操作。别名对QSqlRelation没有影响,因此QSqlRelation::displayColumn()将返回原始显示列名。
  • 参考表名称被别名。别名是单词"relTblAl"和关联的列索引用下划线连接(例如,relTblAl_2)。别名可用于过滤表(例如,setFilter("relTblAl_2='Oslo' OR relTblAl_3='USA'"))。
  • 使用setData()时,角色应始终为Qt::EditRole,使用data()时,角色应始终为Qt::DisplayRole

常用方法

  1. 枚举:enum JoinMode
常量描述解释
QSqlRelationalTableModel::InnerJoin0- Inner join mode, return rows when there is at least one match in both tables.— 内部连接模式,当两个表中至少有一个匹配时返回行。
QSqlRelationalTableModel::InnerJoin1- 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.\n\n""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 &title, QSqlTableModel *model)
{QTableView *view = new QTableView;// 设置模型view->setModel(model);// 设置委托,这样可以下拉框显示view->setItemDelegate(new QSqlRelationalDelegate(view));view->setWindowTitle(title);return view;
}

上述代码:

  • 定义了一个名为 createView 的函数,函数用于创建一个新的 QTableView
  • 函数使用一个标题和一个 QSqlTableModel 对象作为参数,并使用传入的 QSqlTableModel 对象设置 view 的模型。
  • 使用 QSqlRelationalDelegate 设置 view 的委托,以便在需要显示下拉列表时使用。
  • 最后,函数设置 view 的窗口标题,并将 view 返回给调用者。
  1. // 调用
int main(int argc, char *argv[])
{QApplication app(argc, argv);if (!createConnection())return 1;QSqlRelationalTableModel model;initializeModel(&model);QTableView *view = createView(QObject::tr("Relational Table Model"), &model);view->show();return app.exec();
}

结果

在这里插入图片描述

注意

  • 表必须声明主键
  • 使用setRelation()方法时,关联的表和外键需存在,不然,错误的行不会加载到模型中,不会在视图中显示
  • 使用setItemDelegate(new QSqlRelationalDelegate(view))时,可以将单元格以下拉框方式显示

结论

重剑无锋,大巧不工

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/211598.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL根据binlog恢复数据

简介 本文介绍了使用mysqlbinlog导出数据&#xff0c;根据binlog恢复数据&#xff0c;和导出数据时报需要super权限的解决方法。 环境 MySQL: 5.7.40 说明 MySQL的binlog是数据库服务器在运行过程中产生的日志文件&#xff0c;记录了数据库增删改的操作&#xff0c;可用于恢复和…

【理解ARM架构】中断处理 | CPU模式

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《理解ARM架构》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 目录 &#x1f35c;中断&#x1f368;GPIO中断代码实现 &#x1f35c;CPU&#x1f368;CONTROL…

docker集群的详解以及超详细搭建

文章目录 一、问题引入1. 多容器位于同一主机2. 多容器位于不同主机 二、介绍三、特性四、概念1. 节点nodes2. 服务(service)和任务(task)3. 负载均衡 五、docker网络1. overlay网络 六、docker集群搭建1. 环境介绍2. 创建集群3. 集群网络4. 加入工作节点 七、部署可视化界面po…

MYSQL数据库中运行SQL文件报错

报错显示 当使用mysql数据库运行SQL文件报错时 [Err] 1273 - Unknown collation: utf8mb4_0900_ai_ci 报错原因 版本高低问题&#xff0c;一个是5.7版本&#xff0c;一个是8.0版本生成转储文件的数据库版本为8.0,要导入sql文件的数据库版本为5.7,因为是高版本导入到低版本&a…

ThermalLabel SDK for .NET 13.0.23.1113 Crack

ThermalLabel SDK for .NET 是一个 .NET 典型类库&#xff0c;它允许用户和开发人员创建非常创新的条码标签并将其发布在 zebra ZPL、EPL、EPSON ESC、POS 以及 Honeywell intermec 指纹中通过在 VB.NET 或 C# 上编写 .NET 纯代码来实现热敏打印机&#xff0c;以实现项目框架的…

通过仿真理解信道化接收机分析过程

概要 信道化从子信道带宽划分上可分为临界抽取和非临界抽取两种&#xff0c;从各子信道中心频率布局上可分为偶型排列和奇型排列&#xff0c;从处理流程上可分为信道化分析与信道化综合过程。本文主要通过仿真来理解偶型排列/临界抽取/信道化分析过程。 基本原理 常规的数字…

音频修复和增强软件iZotope RX 10 mac特点介绍

iZotope RX 10 mac是一款音频修复和增强软件&#xff0c;主要特点包括&#xff1a; 声音修复&#xff1a;iZotope RX 10可以去除不良噪音、杂音、吱吱声等&#xff0c;使音频变得更加清晰干净。 音频增强&#xff1a;iZotope RX 10支持对音频进行音量调节、均衡器、压缩器、限…

人工智能_机器学习053_支持向量机SVM目标函数推导_SVM条件_公式推导过程---人工智能工作笔记0093

然后我们再来看一下支持向量机SVM的公式推导情况 来看一下支持向量机是如何把现实问题转换成数学问题的. 首先我们来看这里的方程比如说,中间的黑线我们叫做l2 那么上边界线我们叫l1 下边界线叫做l3 如果我们假设l2的方程是上面这个方程WT.x+b = 0 那么这里 我们只要确定w和…

软考高项第四版五组十域表+ITTO背诵笔记及助记

基于第四版做的笔记&#xff0c;助记是自己编的 还是得靠理解记忆&#xff0c;下面是文档&#xff0c;也用anki制作了记忆卡片&#xff0c;需要的可以自行导入卡包

慎用!3个容易被打的Python恶搞脚本

Python 无限恶搞朋友电脑&#xff0c;别提有多爽了&#xff0c;哈哈&#xff0c;打造自己的壁纸修改器&#xff0c;电脑无限锁屏&#xff0c; 无线弹窗&#xff0c;都在这里&#xff01;&#xff01;&#xff01; 1、修改电脑桌面壁纸 工具使用 开发环境&#xff1a;python3…

线段树基础模板c++

线段树的基础模板代码 #include <bits/stdc.h> using namespace std; #define N 100005 #define int long long#define lc p << 1 // 2*i #define rc p << 1 | 1 // 2*i1int n, m; int w[N];struct node {int l, r, sum, add;} tr[N * 4]; // 构建线段树…

【Openstack Train安装】四、MariaDB/RabbitMQ 安装

本章介绍了MariaDB/RabbitMQ的安装步骤&#xff0c;MariaDB/RabbitMQ仅需要在控制节点安装。 在安装MariaDB/RabbitMQ前&#xff0c;请确保您按照以下教程进行了相关配置&#xff1a; 【Openstack Train安装】一、虚拟机创建 【Openstack Train安装】二、NTP安装 【Opensta…

分支和循环

通常来说&#xff0c;C语言是结构化的程序设计语言&#xff0c;这里的结构包括顺序结构、选择结构、循环结构&#xff0c;C语言能够实现这三种结构&#xff0c;如果我们仔细分析&#xff0c;我们日常生活中所见的事情都可以拆分为这三种结构或者它们的组合。 下面我会仔细讲解我…

Windows驱动中使用数字签名验证控制设备访问权限

1. 背景 在一般的驱动开发时&#xff0c;创建了符号链接后在应用层就可以访问打开我们的设备并进行通讯。 但我们有时候不希望非自己的进程访问我们的设备并进行交互&#xff0c;虽然可以使用 IoCreateDeviceSecure 来创建有安全描述符的设备&#xff0c;但大数的用户账户为了方…

基于Vue.js的厦门旅游电子商务预订系统的设计和实现

项目编号&#xff1a; S 030 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S030&#xff0c;文末获取源码。} 项目编号&#xff1a;S030&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 景点类型模块2.2 景点档案模块2.3 酒…

【Redis】redis 高性能--线程模型以及epoll网络框架

目录 一.前言 二.多线程的弊端 2.1 锁的开销问题 2.2 多线程上下文切换带来的额外开销 2.3 多线程占用内存成本增高 三.基本IO模型与epoll 模式 3.1 基本IO模型 3.2 单线程处理机制 四.总结 一.前言 我们经常讨论到&#xff0c;redis 是单线程&#xff0c;那为什么单线…

02、pytest环境准备

工具准备 下载Python——python官网下载&#xff1a;https://www.python.org/下载PyCharm——pycharm官网下载&#xff1a;https://www.jetbrains.com.cn/en-us/pycharm/参考文档——pytest官方文档&#xff1a;https://docs.pytest.org/en/7.4.x/一个方便好用的office库——p…

632. 最小区间

632. 最小区间 class Solution {public int[] smallestRange(List<List<Integer>> nums) {int size nums.size();Map<Integer, List<Integer>> indices new HashMap<Integer, List<Integer>>();int xMin Integer.MAX_VALUE, xMax Inte…

在线 SQL 模拟器SQL Fiddle使用简介

在线 SQL 模拟器SQL Fiddle使用简介 本文可作为“SQL语言与SQL在线实验工具的使用” https://blog.csdn.net/cnds123/article/details/115038700 一文的补充。 有时候&#xff0c;我们想去验证 SQL语句&#xff0c;却缺少数据库环境&#xff0c;那该怎么办呢&#xff1f; 这…

Flask使用线程异步执行耗时任务

1 问题说明 1.1 任务简述 在开发Flask应用中一定会遇到执行耗时任务&#xff0c;但是Flask是轻量级的同步框架&#xff0c;即在单个请求时服务会阻被塞&#xff0c;直到任务完成&#xff08;注意&#xff1a;当前请求被阻塞不会影响到其他请求&#xff09;。 解决异步问题有…