qt QSqlRelationalTableModel 详解

news2024/9/21 1:58:24

背景知识:

Qt SQL的API分为不同层:

  1. 驱动层 

 驱动层  对于QT是基于C++来实现的框架,该层主要包括QSqlDriver、QSqlDriverCreator、QSqlDriverCreatorbase、QSqlDriverPlugin and QSqlResult。这一层提供了特定数据库和SQL API层之间的底层桥梁。

  1. SQL API层

SQL API层  对于SQL API 层提供了数据库的访问相关类,其中,QSqlDataBase类进行连接,QSqlQuery完成数据库的交互。除此之外,还有QSqlError、QSqlField、QSqlIndex and QSqlRecord类。

  1. 用户接口层

用户接口层  用户接口层的几个类实现将数据库中的数据链接到窗口部件上,这些类是使用模型/视图框架实现的,他们是更高层次的抽象,主要包括QSqlQureyModel,QSqlTableModel and QSqlRelationalTableModel。

用户接口层的类使用模型/视图框架实现了将数据库中的数据链接到窗口控件上

QTableView是常用的内容显示视图组件。数据模型类有:QSqlQueryModel 、QSqlTableModel 、QSqlRelationalTableModel 

QSqlQueryModel :通过设置SELECT语句查询获取内容,Model数据是只读的,不能进行编辑

QSqlTableModel : 直接设置一个数据表的名称,可以获取数据表的全部记录,结果是可编辑的。

QSqlRelationalTableModel: 编辑一个数据表,将代码字段通过关系与代码表关联,将代码字段的编辑转换为直观的内容选择编辑。

QSqlRelationalTableModel

QSqlRelationalTableModel为QSqlTableModel 的子类,为单张的数据库表提供了一个可编辑的数据模型,它支持外键

即将主表里的某个字段存储为代码型字段,而代码的具体意义存储在另外一个数据表里。

主表代码字段和关联数据表的关联通过setRelation函数实现。

//关联函数

virtual void setRelation(int columnconst QSqlRelation &relation);

QSqlRelation(const QString &aTableNameconst QString &indexCol,

               const QString &displayCol)

Column主表的代码字段的序号

QSqlRelation 

aTableName :代码表

indexCol代码字段名称

displayCol代码意义的字段名称

tabModel->setRelation(3,QSqlRelation("departments","departID","department")); //学院   tabModel->setRelation(4,QSqlRelation("majors","majorID","major"));//专业

例子

  1. 数据库使用SQLite数据库,格式为.db3
  2. 模型使用QSqlRelationalTableModel,视图使用QTableView
  3. 因为QSqlRelationalTableModel可编辑,可使用代理处理编辑操作。
  4. 除了关联字段特殊处理外,其他的和QSqlTableModel一样的操作。

打开数据库

void MainWindow::on_actOpenDB_triggered()
{

    QString aFile=QFileDialog::getOpenFileName(this,"选择数据库文件","",
                             "SQL Lite数据库(*.db *.db3)");

//    QString aFile= QFileDialog::getOpenFileName(this,"选择数据库文件","","SQL Lite数据库(*.db *.db3)");
    if (aFile.isEmpty())
       return;

//打开数据库
    DB=QSqlDatabase::addDatabase("QSQLITE"); //添加 SQL LITE数据库驱动
    DB.setDatabaseName(aFile); //设置数据库名称
//    DB.setHostName();
//    DB.setUserName();
//    DB.setPassword();
    if (!DB.open())   //打开数据库
    {
//        QMessageBox::warning(this, "错误", "打开数据库失败",QMessageBox::Ok,QMessageBox::NoButton);
        return;
    }

//打开数据表
    openTable();
}

打开数据表

void MainWindow::openTable()
{//打开数据表
    tabModel=new QSqlRelationalTableModel(this,DB);
    tabModel->setTable("studInfo"); //设置数据表
    tabModel->setEditStrategy(QSqlTableModel::OnManualSubmit);  //OnManualSubmit , OnRowChange
    tabModel->setSort(0,Qt::AscendingOrder);

    tabModel->setHeaderData(0,Qt::Horizontal,"学号");
    tabModel->setHeaderData(1,Qt::Horizontal,"姓名");
    tabModel->setHeaderData(2,Qt::Horizontal,"性别");
    tabModel->setHeaderData(3,Qt::Horizontal,"学院");
    tabModel->setHeaderData(4,Qt::Horizontal,"专业");

    //设置代码字段的查询关系数据表
    tabModel->setRelation(3,QSqlRelation("departments","departID","department")); //学院
    tabModel->setRelation(4,QSqlRelation("majors","majorID","major"));//专业

    theSelection=new QItemSelectionModel(tabModel);
    connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)),
            this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));

    ui->tableView->setModel(tabModel);
    ui->tableView->setSelectionModel(theSelection);
    ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView)); //为关系型字段设置缺省代理组件

    tabModel->select(); //打开数据表

//    ui->tableView->resizeColumnsToContents();
//    ui->tableView->horizontalHeader()->setStretchLastSection(true);

    ui->actOpenDB->setEnabled(false);
    ui->actRecAppend->setEnabled(true);
    ui->actRecInsert->setEnabled(true);
    ui->actRecDelete->setEnabled(true);
    ui->actFields->setEnabled(true);
}

添加操作

void MainWindow::on_actRecAppend_triggered()
{//添加记录
    tabModel->insertRow(tabModel->rowCount(),QModelIndex()); //在末尾添加一个记录
    QModelIndex curIndex=tabModel->index(tabModel->rowCount()-1,1);//创建最后一行的ModelIndex
    theSelection->clearSelection();//清空选择项
  theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);/
}

删除

void MainWindow::on_actRecDelete_triggered()
{//删除当前记录
    tabModel->removeRow(theSelection->currentIndex().row());
    tabModel->submitAll(); //立即更新
}

保存

void MainWindow::on_actSubmit_triggered()
{//保存修改
    bool res=tabModel->submitAll();
    if (!res)
        QMessageBox::information(this, "消息", "数据保存错误,错误信息\n"+tabModel->lastError().text(),
                                 QMessageBox::Ok,QMessageBox::NoButton);
    else
    {
        ui->actSubmit->setEnabled(false);
        ui->actRevert->setEnabled(false);
    }
}

取消修改

void MainWindow::on_actRevert_triggered()
{//取消修改
    tabModel->revertAll();
    ui->actSubmit->setEnabled(false);
    ui->actRevert->setEnabled(false);
}

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

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

相关文章

Problem I Rank LED题解 - 2018年第一届GXCPC广西大学生程序设计大赛 正式赛

Problem I Rank LED题解 题目大意 ‘0’到‘9’的数字亮线依次为{6、2、5、5、4、5、6、3、7、6}。 Luras想修改每条光线的位置,使她的新等级尽可能小,同时新等级也是一个不带任何前导零的正整数。 另外,光线总数应与开始时相同。 官方题…

【AIGC】1、爆火的 AIGC 到底是什么 | 全面介绍

文章目录 一、AIGC 的简要介绍二、AIGC 的发展历程三、AIGC 的基石3.1 基本模型3.2 基于人类反馈的强化学习3.3 算力支持 四、生成式 AI(Generative AI)4.1 单模态4.1.1 生成式语言模型(Generative Language Models,GLM&#xff0…

消息处理机制(AOSP4.4.2)

消息处理机制(AOSP4.4.2) Android 应用程序是通过消息来驱动的,系统为每一个应用程序维护一个消息队列,应用程序的主线程,不断地从这个消息队列中获取消息(Looper),然后对消息进行处…

STM32单片机(三)第二节:GPIO输出练习2(LED流水灯)

❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要…

3 分钟为英语学习神器 Anki 部署一个专属同步服务器

原文链接:https://icloudnative.io/posts/anki-sync-server/ Anki 介绍 Anki 是一个辅助记忆软件,其本质是一个卡片排序工具--即依据使用者对卡片上的自定义内容进行主动测试、自我评判后,其内部算法根据评判结果更改每张卡片下次测试时间的…

将win上的文件传输到Ubuntu虚拟机

首先获取Ubuntu系统的ip地址,在Ubuntu的Terminal中输入ifconfig,可以看到Ubuntu的ip地址 可以看到我电脑的ip地址是10.0.2.15。更改虚拟机的网络连接 这里以VirtualBox为例,打开VirtualBox设置,选择网络,将连接方式改…

React.JS实战项目(三):图书购物网站

React.JS实战项目(三):图书购物网站 1、菜单 首页图书新书购物车2、首页 首页视频预览 首页预览 首页主要展示了友情链接、图书分类、好书推荐、新书广场等等信息。 首页部分代码展示 <Row><Col

SpringSecurity整合ssm

SpringSecurity 1. SpringSecurity 框架简介 Spring 是非常流行和成功的 Java 应用开发框架&#xff0c;Spring Security 正是 Spring 家族中的成员。Spring Security 基于 Spring 框架&#xff0c;提供了一套 Web 应用安全性的完整解决方 案。 正如你可能知道的关于安全方面…

nexus 配置pypi代理

在研发环境中由于网络限制&#xff0c;无法访问外网&#xff0c;但经常使用npm、maven、pip等工具&#xff0c;这种场景中使用nexus 做代理是一个比较好的解决办法。 在配置pypi代理时&#xff0c;和配置npm、maven代理有所不同&#xff0c;在配置远程地址时&#xff0c;需要将…

我的IDEA插件

文章目录 前言一、.ignore二、Adapter for Eclipse Code Formatter三、Convert YAML and Properties File四、EasyCode五、Free MyBatis Tool六、Maven Helper七、Rainbow Brackets 前言 目前使用比较顺手的插件&#xff0c;具体使用方法自行查阅 一、.ignore git 忽略文件&…

【算法与数据结构】344、LeetCode反转字符串

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;关于变量交换有两种办法&#xff0c;一种是最常见的引入一个临时变量方法&#xff0c;另一种是使用位运…

【Java面试题】Java基础——集合

文章目录 集合的形式List和Set的区别ArrayList和LinkedList的区别ArrayList和数组的区别ArrayList的扩容机制是什么&#xff1f;ArrayList有哪些特点List和Map的区别如何让map存储有序数据如何创建Map?常用的Map有哪些?如何在HashMap中插入一个数据遍历一个 List 有哪些不同的…

高清音频文件如何压缩?分享轻松压缩音频文件的方法!

如何进行音频压缩&#xff1f;在我们日常生活中&#xff0c;音频文件扮演着重要的角色&#xff0c;我们可以通过它们享受音乐、收听播客或处理语音录音等。然而&#xff0c;有时候这些音频文件的大小可能会成为问题&#xff0c;特别是当我们需要在有限的存储空间中存储更多的文…

深入浅出设计模式 - 原型模式

博主介绍&#xff1a; ✌博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家✌ Java知识图谱点击链接&#xff1a;体系化学习Java&#xff08;Java面试专题&#xff09; &#x1f495;&#x1f495; 感兴趣的同学可以收…

STM32模拟I2C获取TCS34725光学颜色传感器数据

STM32模拟I2C获取TCS34725光学颜色传感器数据 TCS34725是RGB三色颜色传感器&#xff0c;和TCS34727都属于TCS3472系列&#xff0c;在电气特性上略有差别&#xff0c;TCS34727相比TCS34725在I2C总线的访问电平上可以更低&#xff0c;而在I2C软件访问地址方面则一致。 TCS3472内…

leetcode:1431. 拥有最多糖果的孩子(python3解法)

难度&#xff1a;简单 给你一个数组 candies 和一个整数 extraCandies &#xff0c;其中 candies[i] 代表第 i 个孩子拥有的糖果数目。 对每一个孩子&#xff0c;检查是否存在一种方案&#xff0c;将额外的 extraCandies 个糖果分配给孩子们之后&#xff0c;此孩子有 最多 的糖…

Spring Boot中的@RequestMapping注解,如何使用

Spring Boot中的RequestMapping注解 介绍 Spring Boot是一个流行的Java框架&#xff0c;它提供了许多方便的注解和工具&#xff0c;使得Web应用程序的开发变得更加容易。其中&#xff0c;RequestMapping注解是Spring Boot中最常用的注解之一&#xff0c;它可以帮助开发者定义…

django旅游推荐系统-计算机毕设 附源码82884

django旅游推荐系统 摘 要 随着社会的快速发展和人们生活水平的不断提高&#xff0c;旅游已逐渐成为人们生活的重要组成部分&#xff0c;用户能够获取旅游信息的渠道也随信息技术的广泛应用而增加。大量未经过滤的信息在展示给用户的同时&#xff0c;也淹没了用户真正感兴趣的信…

10个图像处理的Python库

在这篇文章中&#xff0c;我们将整理计算机视觉项目中常用的Python库&#xff0c;如果你想进入计算机视觉领域&#xff0c;可以先了解下本文介绍的库&#xff0c;这会对你的工作很有帮助。 1、PIL/Pillow Pillow是一个通用且用户友好的Python库&#xff0c;提供了丰富的函数集…

【MOOC 测验】第5章 链路层

1、局域网的协议结构一般不包括&#xff08; &#xff09; A. 数据链路层B. 网络层C. 物理层D. 介质访问控制层 逻辑链路控制子层、介质访问控制子层、物理层 2、下列关于二维奇偶校验的说法&#xff0c;正确的是&#xff08; &#xff09; A. 可以检测和纠正双比特差错B…