当前位置: 首页 > news >正文

C++ Qt开发:SqlRelationalTable关联表组件

Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍SqlRelationalTable关联表组件的常用方法及灵活运用。

在上一篇文章中详细介绍了SqlTableModle组件是如何使用的,本篇文章将介绍SqlRelationalTable关联表组件,该该组件其实是SqlTableModle组件的扩展类,其提供了一个带关系的数据模型,用于处理数据库中的表与表之间的关系。通过这个类,你可以在一个表中使用外键关联到另一个表的数据上。例如将主表中的某个字段与附加表中的特定字段相关联起来,QSqlRelation(关联表名,关联ID,名称)就是用来实现多表之间快速关联的。

1.1 ComboBox

首先我们来实现一个简单的联动效果,数据库组件可以与ComboBox组件形成多级联动效果,在日常开发中多级联动效果应用非常广泛,例如当我们选择指定用户时,让其在另一个ComboBox组件中列举出该用户所维护的主机列表,又或者当用户选择省份时,自动列举出该省份下面的城市列表等。

在进行联动之前需要创建两张表,表结构内容介绍如下:

  • User(id,name)表:存储指定用户的ID号与用户名
  • UserAddressList(id,name,address)表:与User表中的用户名相关联,存储该用户所管理的主机列表信息

通过数据库组件实现的联动非常简单,初始化表结构得到了两张表,当程序运行时默认在MainWindow构造函数处填充第一个ComboBox组件,也就是执行一次数据库查询,并将结果通过addItem()放入到第一个组件内。

QSqlDatabase db;MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);InitMultipleSQL();db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("./database.db");if (!db.open()){std::cout << db.lastError().text().toStdString()<< std::endl;return;}QSqlQuery query;query.exec("select * from User;");QSqlRecord rec = query.record();while(query.next()){int index_name = rec.indexOf("name");QString data_name = query.value(index_name).toString();ui->comboBox_user->addItem(data_name);}
}

而当用户选中了第一个ComboBox组件时,则让其转到槽函数on_comboBox_activated(const QString &arg1)上面,如下图所示;

该槽函数需要一个传入参数,此参数代表组件选中的文本内容,通过利用该文本内容在数据库内执行二次查询并将查询结果填充之对应的第二个ComboBox组件内即可实现组件的联动选择效果,其槽函数代码如下所示;

void MainWindow::on_comboBox_user_activated(const QString &arg1)
{if(db.open()){QSqlQuery query;query.prepare("select * from UserAddressList where name = :x");query.bindValue(":x",arg1);query.exec();QSqlRecord rec = query.record();ui->comboBox_address->clear();while(query.next()){int index = rec.indexOf("address");QString data_ = query.value(index).toString();ui->comboBox_address->addItem(data_);}}
}

读者可自行运行案例中的SqlComboBox案例,运行后可自行选择不同的用户名,则此时会输出该用户名所对应的地址表,如下图所示;

1.2 TableView

接着,我们继续以TableView组件为例,简单介绍一下如何实现组件与数据的绑定,首先我们需要创建一个表并插入几条测试记录,运行如下代码实现建库建表.

创建一张新表,表结构内容介绍如下:

  • LyShark(name,age)表:存储指定用户名与用户年龄

在主构造函数中我们可以直接通过QSqlQueryModel来得到特定表中的记录,并通过setHeaderData将表中的数据关联到对应的数据模型内,最后通过setModel方法即可将对应的表数据关联到前端显示,其核心代码如下所示;

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);Init();QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("./database.db");if (!db.open()){std::cout << db.lastError().text().toStdString()<< std::endl;return;}// 查询数据表中记录qryModel=new QSqlQueryModel(this);qryModel->setQuery("SELECT * FROM LyShark ORDER BY id");if (qryModel->lastError().isValid()){return;}// 设置TableView表头数据qryModel->setHeaderData(0,Qt::Horizontal,"ID");qryModel->setHeaderData(1,Qt::Horizontal,"Name");qryModel->setHeaderData(2,Qt::Horizontal,"Age");// 将数据绑定到模型上theSelection=new QItemSelectionModel(qryModel);ui->tableView->setModel(qryModel);ui->tableView->setSelectionModel(theSelection);ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
}

运行代码后,程序会从数据库内取出结果并输出到tableView组件上,如下图所示;

1.3 SqlRelationalTable

在最开始我们也说过,SqlRelationalTable 并不是Qt中标准的类或方法。它仅仅只是QSqlTableModel的一个子类,其支持在关系数据库表之间建立关系,建立关联时我们只需要使用setRelation方法即可。

setRelationQSqlRelationalTableModel 类中的一个方法,用于设置模型中某一列的关联关系。这个方法的目的是告诉模型某一列的值在另一个表中有关联,并提供相关的信息,以便在视图中显示更有意义的数据而不是外键的原始值。

以下是 setRelation 方法的简单说明:

void QSqlRelationalTableModel::setRelation(int column, const QSqlRelation &relation);
  • column: 要设置关联关系的列的索引。
  • relation: 包含关联信息的 QSqlRelation 对象。

QSqlRelation 的构造函数如下:

QSqlRelation::QSqlRelation(const QString &tableName, const QString &indexColumn, const QString &displayColumn);
  • tableName: 关联的表的名称。
  • indexColumn: 关联表中与当前表关联的列的名称,通常是外键列。
  • displayColumn: 关联表中要显示的列的名称,通常是与外键列相关的实际数据。

示例:

QSqlRelationalTableModel model;
model.setTable("orders");
model.setRelation(2, QSqlRelation("customers", "customer_id", "customer_name"));
model.select();

在这个例子中,第二列(索引为2的列)的数据将从名为 “customers” 的表中获取,该表的外键列为 “customer_id”,并且在视图中显示的是该关联表的 “customer_name” 列的值。使用 setRelation 方法可以使得在表格中更容易地显示和编辑关联数据,而不是直接显示外键的值。

在关联表之前,我们需要设置初始化数据,此处我们提供两个表结构,表Student用于存储学生名字以及学生课程号,另一张Departments则用于存储每个编号所对应的系名称,运行代码完成创建。

// 初始化数据表
void MainWindow::InitSQL()
{QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("./database.db");if (!db.open())return;// 执行SQL创建表db.exec("DROP TABLE Student");db.exec("CREATE TABLE Student (""id INTEGER PRIMARY KEY AUTOINCREMENT, ""name VARCHAR(40) NOT NULL, ""departID INTEGER NOT NULL)");// 逐条插入数据db.exec("INSERT INTO Student(name,departID) VALUES('zhangsan',10)");db.exec("INSERT INTO Student(name,departID) VALUES('lisi',20)");db.exec("INSERT INTO Student(name,departID) VALUES('wangwu',30)");db.exec("INSERT INTO Student(name,departID) VALUES('wangmazi',40)");db.exec("DROP TABLE Departments");db.exec("CREATE TABLE Departments(""departID INTEGER NOT NULL,""department VARCHAR(40) NOT NULL)");db.exec("INSERT INTO Departments(departID,department) VALUES (10,'数学学院')");db.exec("INSERT INTO Departments(departID,department) VALUES (20,'物理学院')");db.exec("INSERT INTO Departments(departID,department) VALUES (30,'计算机学院')");
}

接着我们来看下在MainWindow构造函数中是如何进行初始化和表关联的,以下是对代码的简要说明:

打开数据库连接

创建一个 SQLite 数据库连接,并指定了数据库文件的路径。如果数据库连接成功打开,就继续执行后面的代码。

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("./database.db");
if (!db.open())return;

设置主窗口的布局和属性

将主窗口的中央部件设置为一个 QTableView,同时对表格的选择行为和外观进行了设置。

this->setCentralWidget(ui->tableView);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView->setAlternatingRowColors(true);

打开数据表并设置模型

创建一个 QSqlRelationalTableModel 并设置了一些表格的属性,包括表名、编辑策略、排序等。

tabModel = new QSqlRelationalTableModel(this, db);
tabModel->setTable("Student");
tabModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
tabModel->setSort(0, Qt::AscendingOrder);tabModel->setHeaderData(0, Qt::Horizontal, "学号");
tabModel->setHeaderData(1, Qt::Horizontal, "姓名");
tabModel->setHeaderData(2, Qt::Horizontal, "学院");

设置查询关系数据表

设置关系型字段,将 “学院” 列与 “Departments” 表中的 “departID” 列关联起来,并在表格中显示 “department” 列的数据。

tabModel->setRelation(2, QSqlRelation("Departments", "departID", "department"));

设置表格的选择模型和代理

代码设置了表格的选择模型,并为表格设置了一个关系型代理(QSqlRelationalDelegate),以便在表格中显示关联表的数据而不是外键的值。

theSelection = new QItemSelectionModel(tabModel);
ui->tableView->setModel(tabModel);
ui->tableView->setSelectionModel(theSelection);
ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));

选择并显示数据表

最后,通过调用 select 方法来选择和显示数据表的内容。

tabModel->select();

其实代码中最重要的部分就是setRelation,我们只要确保数据库文件正确,并且 Student 表和 Departments 表存在,并且在 Student 表中的 “学院” 列与 Departments 表中的 "departID" 列正确关联即可,其他的就交给组件来处理,如下图所示;

相关文章:

C++ Qt开发:SqlRelationalTable关联表组件

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍SqlRelationalTable关联表组件的常用方法及灵…...

【LeetCode】修炼之路-0001-Two Sum(两数之和)【python】【简单】

前言 计算机科学作为一门实践性极强的学科,代码能力的培养尤为重要。当前网络上有非常多优秀的前辈分享了LeetCode的最佳算法题解,这对于我们这些初学者来说提供了莫大的帮助,但对于我这种缺乏编程直觉的学习者而言,这往往难以消化吸收。&#xff08;为什么别人就能想出这么优雅…...

秋招复习篇之代码规范

目录 前言 1、变量命名 2、代码空格 1&#xff09;操作符左右一定有空格&#xff0c; 2&#xff09;分隔符&#xff08;, 和;&#xff09;前一位没有空格&#xff0c;后一位保持空格&#xff0c;例如&#xff1a; 3&#xff09;大括号和函数保持同一行&#xff0c;并有一个空格…...

Docker:登录私有仓库\退出私有仓库

一、登录仓库 docker login : 登录到一个Docker镜像仓库&#xff0c;如果未指定镜像仓库地址&#xff0c;默认为官方仓库 Docker Hub 语法: docker login [OPTIONS] [SERVER] docker login -u 用户名 -p 密码 仓库名称 # 登入私有仓库 [rootlocalhost ~]# docker login --…...

与擎创科技共建一体化“数智”运维体系,实现数字化转型

小窗滴滴小编获取最新版公司简介 前言&#xff1a; 哈喽大家好&#xff0c;最近分享的互联网IT热讯大家都挺喜欢&#xff0c;小编看着数据着实开心&#xff0c;感谢大家支持&#xff0c;小编会继续给大家推送。 新岁即将启封&#xff0c;我们一年一期的运维干货年末大讲也要…...

开放网络+私有云=?星融元的私有云承载网络解决方案实例

在全世界范围内的云服务市场上&#xff0c;开放网络一直是一个备受关注的话题。相比于传统供应商的网络设备&#xff0c;开放网络具备软硬件解耦、云原生、可选组件丰富等优势&#xff0c;对云服务商和超大型企业有足够的吸引力。 SONiC作为开源的网络操作系统&#xff0c;使得…...

【Linux学习笔记】Linux下nginx环境搭建

1、下载nginx 安装rpm命令: rpm ivh nginx-release.rpm。(直接使用linux命令下载wget http://nginx.org/packages/rhel/6/noarch/RPMS/nginx-release-rhel-6-0.el6.ngx.noarch.rpm 2、设置nginx开机启动 chkconfig nginx on 3、开启nginx服务 方法一&#xff1a;service nginx…...

Python打包

将 Python 脚本打包成可执行的 .exe 文件,通常可以使用 PyInstaller 这个库来实现。PyInstaller 是一个流行的工具,它可以将 Python 程序和所有相关的依赖打包成一个独立的可执行文件,适用于 Windows、Linux 和 macOS 系统。安装 PyInstaller 首先,需要安装 PyInstaller。…...

2023启示录丨自动驾驶这一年

图片&#xff5c;《老人与海》插图 过去的20年&#xff0c;都没有2023年如此动荡。 大模型犹如一颗原子弹投入科技圈&#xff0c;卷起万里尘沙&#xff0c;传统模式瞬间被夷为平地&#xff0c;在耀眼的白光和巨大的轰鸣声之下&#xff0c;大公司、创业者、投资人甚至是每一位观…...

node实现对git仓库的管理

一、项目背景 一份代码&#xff0c;发布多个小程序。想让技术支持部通过脚本自己获取代码&#xff0c;并通过脚本自动提交到客户的小程序后台。他们自行发布。 现已注册第三方平台&#xff0c;开发人员通过“开发小程序”上传模板。开发人员把代码上传到模板&#xff0c;支持…...

『JavaScript』全面解析JavaScript中的防抖与节流技术及其应用场景

&#x1f4e3;读完这篇文章里你能收获到 理解防抖&#xff08;Debouncing&#xff09;和节流&#xff08;Throttling&#xff09;的概念&#xff1a;了解这两种性能优化技术如何帮助我们更有效地处理频繁触发的事件掌握防抖与节流的实现方法&#xff1a;学习如何在JavaScript中…...

智能优化算法应用:基于袋獾算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于袋獾算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于袋獾算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.袋獾算法4.实验参数设定5.算法结果6.参考文献7.MA…...

Ubuntu20.04-查看GPU的使用情况及输出详解

1. 查看GPU的使用情况 1.1 nvidia-smi # 直接在终端得到显卡的使用情况 # 不会自动刷新 nvidia-smi# 重定向到文件中 nvidia-smi > nvidia_smi_output.txt# 如果输出的内容部分是以省略号表示的&#xff0c;可以-q nvidia-smi -q 1.2 nvidia-smi -l # 会自动刷新&#x…...

Python中的数据序列

Python中的数据序列 一、作业回顾 1、求幸运数字6 幸运数字6(只要是6的倍数):输入任意数字,如数字8,生成nums列表,元素值为1~8,从中选取幸运数字移动到新列表lucky,打印nums与lucky。 # 第一步:定义二个空列表 nums = [] lucky = [] # 第二步:提示用户输入数字 n…...

带您了解目前AI在测试领域能够解决的那些问题

AI在测试领域主要应用场景 话不多说&#xff0c;直接给结论&#xff1a; 接口测试脚本的自动生成和校验&#xff08;依赖研发ai工具&#xff09;测试用例的自动生成UI自动化测试脚本的自动生成和校验测试文档的自动生成快速了解初涉的业务领域 关于ai对研发和测试的整体影响…...

Jmeter学习总结(2)——时间参数化time

13位的时间戳精确都毫秒级别。 常用的时间定义格式如下&#xff1a; log.info("${__time(,ts)}"); log.info("${ts}"); log.info(vars.get("ts")); //136232232232log.info("${__time(yyyy-MM-dd,)}"); //当前年月日2023-12-2…...

Leetcode 746 使用最小花费爬楼梯

题意理解&#xff1a; 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。 一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯 目标&#xff1a;使用最小的花…...

2023/12/21作业

思维导图 代码 .text .global _start _start: 灯1 gpio时钟使能 [4]->1 0x5000A28 LDR R0,0x50000A28 指定寄存器地址 LDR R1,[R0]将寄存器取出放到R1 ORR R1,R1,#(0x1<<4)将第四位设置为1 STR R1,[R0]读取R0寄存器到R1 PE…...

Python 数据类型 (2)

1 集合类型&#xff1a;一维数组的集合 List列表是一个有序且可变的集合。允许重复成员。 turple元组是一个有序且不可更改的集合。允许重复成员。 Set集合是一个无序且无索引的集合。没有重复的成员。 dict字典是一个有序*且可变的集合。没有重复的成员。 &#xff01;&#x…...

【教程】自动检测和安装Python脚本依赖的第三方库

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 背景说明 对于新python环境&#xff0c;要运行某个脚本&#xff0c;可能需要安装很多库&#xff0c;一般可以通过提供的requirements.txt来自动安装。但如果没有这个txt&#xff0c;那就得手动一个一个安装&#…...

0开始配置Cartographer建图和导航定位

0开始配置Cartographer 日期&#xff1a;12-19 硬件&#xff1a;激光雷达IMU 小车的tf变换&#xff1a; 建图配置 lua文件配置&#xff1a;my_robot.lua include "map_builder.lua" include "trajectory_builder.lua"options {map_builder MAP_BUILDE…...

Python中使用SQLite数据库的方法2-2

3.3.2 创建表单及字段 通过“3.2 创建Cursor类的对象”中创建的Cursor类的对象cur创建表单及字段&#xff0c;代码如图5所示。 图5 创建表单及字段 从图5中可以看出&#xff0c;通过Cursor类的对象cur调用了Cursor类的execute()方法来执行SQL语句。该方法的参数即为要指定的S…...

零代码也能玩出花:Mugeda在H5设计中的魔法力量

文章目录 一、Mugeda零代码可视化H5设计工具简介二、Mugeda零代码可视化H5设计实战案例1. 注册并登录Mugeda账号2. 选择模板3. 编辑页面内容4. 添加动画效果5. 预览和发布 三、Mugeda零代码可视化H5设计的优势《Mugeda零代码可视化H5设计实战》内容简介作者简介目录前言/序言 随…...

分布式、CAP 和 BASE 理论

在计算机科学领域&#xff0c;分布式系统是一门极具挑战性的研究方向&#xff0c;也是互联网应用中必不可少的优化实践&#xff0c;而 CAP 理论和 BASE 理论则是分布式系统中的两个关键的概念。 什么是分布式系统 首先&#xff0c;让我们来谈谈分布式系统。你可以将分布式系统…...

django之drf框架(两个视图基类、5个扩展视图类、9个视图子类)

两个视图基类 APIView和GenericAPIView drf提供的最顶层的父类就是APIView&#xff0c;以后所有的类都继承自他 GenericAPIView继承自APIView&#xff0c;他里面封装了一些工能 基于APIViewModelSerializerResposne写5个接口 子路由&#xff1a;app01>>>urls.py …...

23种设计模式学习

设计模式的分类 总体来说设计模式分为三大类&#xff1a; 创建型模式&#xff0c;共五种&#xff1a;工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式&#xff0c;共七种&#xff1a;适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合…...

php 8.4 xdebug扩展编译安装方法

最新版php8.4 xdebug扩展只能通过编译方式安装, pecl是安装不了的, 编译方法如下 下载最新版xdebug git clone https://github.com/xdebug/xdebug.git 却换入xdebug目录执行编译安装xdebug cd xdebug phpize./configure --enable-xdebugmakemake install3. 配置启用xdebug 这…...

66biolinks v42.0.0 已注册 – 生物短链接、URL 缩短器、QR 码和 Web 工具 (SAAS) 源码

66biolinks v42.0.0&#xff1a;全能生物短链接与网络工具平台 一、开篇介绍 66biolinks v42.0.0是一款集生物链接、URL缩短器、二维码和网络工具于一体的综合性软件解决方案。作为社交生物链接平台的佼佼者&#xff0c;66biolinks提供了全方位的功能&#xff0c;旨在满足用户…...

《Vue2.X 进阶知识点》- 防 ElementUI Divider 分割线

前言 使用 el-divider 背景为白色是没问题的。 但当背景换成其它颜色&#xff0c;问题就出现了&#xff01;&#xff01; 仔细看原来是两层&#xff0c;默认背景色是白色。 想着把背景色改为透明应该能用&#xff0c;结果发现背面是一条实线&#xff0c;难怪要用白色遮挡…不符…...

【第十二课】KMP算法(acwing-831 / c++代码 / 思路 / 视频+博客讲解推荐)

目录 暴力做法 代码如下 KMP算法 不同的next求法-----视频讲解/博客推荐 视频推荐 博客推荐 课本上的方法- prefix的方法- 求next数组思路---next数组存放前缀表的方式 s和p匹配思路 代码如下 暴力做法 遍历s主串中每一个元素&#xff0c;如果该元素等于模板串p中…...

新建网站解析域名/全球外贸采购网

目录 1.安装item2 2.安装brew 3.安装lrzsz 4.安装脚本到mac目录 4.1先下载脚本 4.2保存 iterm2-send-zmodem.sh 和 iterm2-recv-zmodem.sh 到mac的 /usr/local/bin/ 路径下 4.3添加脚本可执行权限: 5.在item2中配置 6.使用 7.可能遇到的问题 新版mac系统里没有/usr/…...

个人网站创建平台要多少钱/如何添加百度指数

转自&#xff1a;http://ir.hit.edu.cn/~car/programming/rup/toolment/vqtfy/tm_vqtfy.htm#Step1 目的 本工具向导概括说明了如何使用 Rational Quantify 快速地查明 Visual C/C、Visual Basic、和 Java 程序中的性能瓶颈。要了解 Quantify 的详细信息&#xff0c;包括如何设计…...

网址制作网站/聚名网域名注册

链接&#xff1a;https://yq.aliyun.com/ziliao/313915...

博山专业网站优化哪家好/sem和seo是什么

如果我要去11-20的Account表的数据 Select * From Account Limit 9 Offset 10; 以上语句表示从Account表获取数据&#xff0c;跳过10行&#xff0c;取9行 嗯&#xff0c;我觉得这个特性足够让很多的web中型网站使用这个了。 也可以这样写 select * from account limit10,9和上面…...

建设网站的准备/各大网址收录查询

问题描述此问题源于道路养护决策&#xff0c;采用数学的0-1规划&#xff0c;决策需要养护的路段。其数学描述如下&#xff1a;problem.png-401kB目标函数&#xff1a;obj 1486 X3 495 X5 260 X6 2760 X8 120 X9 120 X10 2070 X11 2070 X12 90 X15 750约束s.t.:X3 X5…...

龙华网站建设招聘/网站推广策划思路的内容

在2019腾讯全球数字生态大会新闻发布会上&#xff0c;腾讯云联合腾讯研究院&#xff0c;共同发布了行业重磅报告&#xff1a;《产业互联网——构建智能时代数字生态新图景》。报告首次阐述了产业互联网的战略框架和实践方法论。报告指出&#xff0c;产业互联网的实现&#xff0…...