Qt-数据库开发-外键使用(4)

news2025/1/11 15:04:56

Qt-数据库开发-使用QSqlRelationalTableModel(关系表模型)来可视化数据库中[外键]

文章目录

  • Qt-数据库开发-使用QSqlRelationalTableModel(关系表模型)来可视化数据库中[外键]
    • 1、概述
    • 2、实现效果
    • 3、主要代码
    • 4、完整源代码

更多精彩内容
👉个人内容分类汇总 👈
👉数据库开发 👈

1、概述

  • 这是通过学习Qt官方Demo产生的一个示例;
  • 通过自己理解加入了一些更加详细便于学习的内容;
  • 添加了非常详细的注释信息,对于小白更加友好。

开发环境说明

  • 系统:Windows10、Ubuntu20.04
  • Qt版本:V5.12.5
  • 编译器:MSVC2017-64、GCC/G++64

2、实现效果

  1. 本示例展示了如何使用QSqlRelationalTableModel(关系表模型)来可视化数据库中[外键]的使用。
  2. 程序启动时自动创建一个数据库,并创建一个主表个两个从表,可选择创建文件数据还是内存数据库;
  3. 通过主表中的【外键】去关联子表中的数据;
  4. 只有一个main.cpp,十分简单便于学习。
  • 实现效果如下:

    在这里插入图片描述

3、主要代码

  • 啥也不说了,直接上代码,一切有注释

  • pro文件: Qt使用到数据库,上来什么都别管,先在pro文件添加上QT += sql widgets

  • main.cpp文件:程序第一次启动时在main函数中创建数据库并写入数据,并通过QTableView显示数据库内容;

    #include <QApplication>
    #include <QSqlRelationalDelegate>
    #include <QSqlRelationalTableModel>
    #include <qmessagebox.h>
    #include <qsqldatabase.h>
    #include <qsqlquery.h>
    #include <qtableview.h>
    
    /**
     * @brief  创建并打开一个QSqlite数据库,并创建一个主表、两个从表
     * @return
     */
    bool createConnection()
    {
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");  // 使用数据库驱动(Qsqlite)和默认连接名称(qt_sql_default_connection)添加一个数据库
    //    qDebug() << QSqlDatabase::defaultConnection;           // 打印默认数据库连接名称
    #if 1
        db.setDatabaseName("test.db");        // 使用文件数据库(可生成数据库文件,数据一直有效)
    #else
        db.setDatabaseName(":memory:");       // 使用内存数据库(不会生成数据库文件,所有数据都在内存中进行操作,性能强,程序退出后数据丢失)
    #endif
    
        if(!db.open())             // 打开数据库
        {
            QMessageBox::critical(nullptr, "Error", "打开数据库失败!");
            return false;
        }
    
        QSqlQuery query;          // 创建一个用于执行和操作Sql语句的对象
    
        // 创建一个主表person,包含id、name、grade、class四个字段
        query.exec("create table student ("
                   "id         int         primary key,"    // 索引
                   "name       varchar(20),"                // 姓名
                   "grade      int,"                        // 年级
                   "class      int )");                     // 班级
    
        query.exec("insert into student values(1, '大毛', 3, 2)");       // 插入学生数据(大毛、三年级2班)
        query.exec("insert into student values(2, '二毛', 3, 1)");
        query.exec("insert into student values(3, '三毛', 2, 3)");
        query.exec("insert into student values(4, '小毛', 1, 4)");
    
        query.exec("create table grade (id int, name varchar(20))");  // 创建年级从表
        query.exec("insert into grade values(1, '一年级')");
        query.exec("insert into grade values(2, '二年级')");
        query.exec("insert into grade values(3, '三年级')");
    
        query.exec("create table class (id int, name varchar(20))");  // 创建班级从表
        query.exec("insert into class values(1, '(1)班')");
        query.exec("insert into class values(2, '(2)班')");
        query.exec("insert into class values(3, '(3)班')");
        query.exec("insert into class values(4, '(4)班')");
    
        return true;
    }
    
    /**
     * @brief        初始化设置model
     * @param model
     */
    void initModel(QSqlRelationalTableModel* model)
    {
        model->setTable("student");
        model->setEditStrategy(QSqlTableModel::OnManualSubmit);      // 在界面修改后不立即保存到数据库
        model->setRelation(2, QSqlRelation("grade", "id", "name"));  // 将第2列数据通过外键关联到从表
        model->setRelation(3, QSqlRelation("class", "id", "name"));
        // 设置列标题
        model->setHeaderData(0, Qt::Horizontal, "ID");
        model->setHeaderData(1, Qt::Horizontal, "姓名");
        model->setHeaderData(2, Qt::Horizontal, "年级");
        model->setHeaderData(3, Qt::Horizontal, "班级");
    
        model->select();   // 查询数据库数据
    }
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        if(!createConnection()) return -1;         // 打开数据库并创建一个主表、两个子表
    
        QSqlRelationalTableModel model;            // 创建一个支持使用外键的model
        initModel(&model);
    
        QTableView* view = new QTableView;         // 创建一个表格视图,用于显示数据库数据
        view->resize(500, 300);
        view->setWindowTitle(QString("QSql-通过QSqlRelationalTableModel类使用外键Demo - V%1").arg(APP_VERSION));
        view->setModel(&model);
        view->setItemDelegate(new QSqlRelationalDelegate(view));  // 与默认委托不同,QSqlRelationalDelegate 为其他表的外键字段提供了一个组合框
        view->show();
    
        return a.exec();
    }
    
    

4、完整源代码

  • github
  • gitee

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Swift学习笔记笔记(八) 日期选择和表现视图组件的使用

一、实验目的&#xff1a; 1.掌握DatePicker组件的使用 2.掌握TableView组件的使用 3.掌握代码设置属性的方法 二、实验原理&#xff1a; 1.属性面板设置属性的缺点 2.DatePicker中Moder属性的设置方法 3.DatePicker中Locale属性的设置方法 4.随机数函数的原型 5. 运动检测函…

Python-matplotlib画图要点【大总结】

文章目录一、x,y坐标图1、基本操作2、进阶操作&#xff08;1&#xff09;解决中文乱码情况&#xff08;2&#xff09;调整图像大小&#xff08;3&#xff09;加标题、坐标文字、坐标轴标签&#xff08;5&#xff09;去掉上边框二、柱状图1、柱状图画图原理2、三、颜色与标记形状…

运筹说 第83期丨我国网络计划奠基人——华罗庚

经过之前的学习&#xff0c;相信大家已经对运筹学的图论的内容有了一定的了解&#xff0c;接下来小编将带你学习新一章的内容&#xff0c;先来看看网络计划的起源发展&#xff0c;然后共同走近我国网络计划奠基人——华罗庚&#xff0c;去领略他不平凡的一生。 01 网络计划起源…

Pr:导出设置之管理显示色域体积及内容光线级别

视频 VIDEO设置因所选导出格式而异。每种格式都有独特的要求&#xff0c;这些要求决定了哪些设置可用。以导出 H.264 文件格式为例&#xff0c;下面给出 HDR 显示器及节目内容显示相关的选项及说明。管理显示色域体积Mastering Display Color Volume对内容进行分级时所使用的 H…

获取pdf中固定位置图片的二维码,然后解析

1、需要引入下面的pom坐标如下​​ ​2.完整代码如下import com.github.binarywang.utils.qrcode.BufferedImageLuminanceSource; import com.google.zxing.BinaryBitmap; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatReader; import com.goo…

itop3568开发板在Linux系统中使用NPU

下载rknpu2并拷贝虚拟机Ubuntu&#xff0c;如下图所示&#xff0c;RKNPU2提供了访问rk3568 芯片 NPU 的高级接口。 下载地址为“iTOP-3568 开发板\02_【iTOP-RK3568 开发板】开发资料\11_NPU 使用配套资料\01_rknpu2 工具” 对于 RK3568 来说&#xff0c;Linux 平台 RKNN SDK 库…

[Spring5.3.2] Servlet[springmvc]的Servlet.init()引发异常, 解析类文件失败

Spring / Spring MVC遇到问题 找了一本spring相关的教材,书上的代码拿过来就能运行,自己写就总报HTTP 500错误,反复检查没有任何一处写错,同一个错误卡了我三天,非常郁闷,今天终于解决了.特此记录. 问题表现: 图中提到的问题: 例外情况 javax.servlet.ServletException: Ser…

编码规约学习要点

工程结构应用分层 日志规约 编程规约 > 其它 【强制】日期格式化时&#xff0c;传入 pattern 中表示年份统一使用小写的 y。 说明&#xff1a;日期格式化时&#xff0c;yyyy 表示当天所在的年&#xff0c;而大写的 YYYY 代表是 week in which year&#xff08;JDK7 之后引…

第二证券|热门板块再次爆发,早盘主力抢筹超10亿元!

抗原检测、房地产概念股团体冲高&#xff0c;板块热度居高不下。 抗原检测概念股团体上涨 12月9日早盘&#xff0c;新冠抗原检测概念股团体上涨&#xff0c;概念指数涨4.74%&#xff0c;明德生物涨停&#xff0c;九安医疗、万孚生物、热景生物涨幅居前&#xff0c;分别上涨8.4…

【Window环境下使用MSYS2搭建CMake + MinGW环境】

目录标题安装CMakecmake 测试MSYS2下载MSYS2安装MSYS2修改软件下载源MSYS2下安装MinGW配置MinGW配置到环境变量hello world测试安装CMake Cmake下载地址:https://cmake.org/download/,下一个windows压缩包就好了&#xff0c;因为我比较喜欢自己来配置&#xff0c;免得不知道安…

嵌入式软件开发知识点总结-uboot文件系统

【推荐阅读】 浅析linux 系统进程冻结&#xff08;freezing of task&#xff09; 30分钟了解linux操作系统内核总结 深入linux内核架构--进程&线程 需要多久才能看完linux内核源码&#xff1f; 概述Linux内核驱动之GPIO子系统API接口 Uboot 什么是bootloader&#xff1f; …

Linux操作系统~进程崩溃的原理是什么?信号的产生方式有哪些?

目录 1.信号的概念 2.signal函数的使用 kill -l 自定义信号处理函数signal函数 3.进程异常/崩溃的原理 &#xff08;1&#xff09;.进程为什么会崩溃&#xff1f; &#xff08;2&#xff09;.如何知道进程崩溃/异常的原因 &#xff08;3&#xff09;.core dump的作用—…

C++类设计和实现的十大最佳实践

C代码提供了足够的灵活性&#xff0c;因此对于大部分工程师来说都很难把握。本文介绍了写好C代码需要遵循的10个最佳实践&#xff0c;并在最后提供了一个工具可以帮助我们分析C代码的健壮度。原文&#xff1a;10 Best practices to design and implement a C class 1. 尽可能尝…

Word处理控件Aspose.Words功能演示:使用 C# 将 Word 文档转换为 HTML

在各种情况下&#xff0c;您需要在 Web 或桌面应用程序中显示 Word 文档的内容。在这种情况下&#xff0c;合适的选项之一是将 Word 文档转换为HTML。为了在 .NET 应用程序中实现这一点&#xff0c;本文介绍了如何使用 C# 将 Word DOCX或DOC文件转换为 HTML。此外&#xff0c;您…

搅拌釜反应器全自动真空压力(正负压)控制解决方案

摘要&#xff1a;针对双层玻璃反应釜中存在的无法进行真空压力自动和准确控制等问题&#xff0c;本文提出了完整和成熟的解决方案&#xff0c;即采用卫生级电动调节阀和高精度双通道PID控制器&#xff0c;结合不同量程的真空计&#xff0c;与反应器、真空泵和正压气源构成闭环控…

ARP协议与ARP欺骗

一、ARP协议&#xff08;地址解析协议&#xff09; 所谓“地址解析”就是主机在发送帧前将目标IP地址转换成目标MAC地址的过程,ARP协议的基本功能就是通过目标设备的IP地址&#xff0c;查询目标设备的MAC地址&#xff0c;以保证通信的顺利进行。 将一个已知的IP地址解析为MAC…

169. 基于Django-RESTFramework的节流的使用

1.节流概述 节流又称限流&#xff0c;限制访问。 就是一个用户多次发送一个请求&#xff08;页面或者链接&#xff09;的时候&#xff0c;单位时间允许访问次数限制&#xff0c;超过限制就会出现访问受限&#xff0c;提示譬如&#xff1a;离下一场访问还有多久之类等的字样。 …

基于SSM的学生考勤管理系统的设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

【学习笔记】顺序容器的表格方式总结 C++

目录顺序容器及其特点顺序容器操作向顺序容器添加元素insertemplace参考更新中… 顺序容器及其特点 名字访问元素插入&#xff0c;删除元素vector&#xff08;可变大小数组&#xff09;支持快速随机访问在尾部之外的位置插入或删除元素可能很慢deque&#xff08;双端队列&…

SpringBoot实战:整合MapStruct实现数据类型转化

MapStruct 是一个代码生成器&#xff0c;它基于约定优于配置方法极大地简化了 Java bean 类型之间映射的实现。自动生成的映射转换代码只使用简单的方法调用&#xff0c;因此速度快、类型安全而且易于理解阅读&#xff1b;本篇就是实现 SpringBoot 整合 MapStruct 实现数据类型…