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

Qt-链接数据库可视化操作

1. 概述

  • Qt 能够支持对常见数据库的操作,例如: MySQL、Oracle、SqlServer 等等。

  • Qt SQL模块中的API分为三层:驱动层、SQL接口层、用户接口层。

    • 驱动层为数据库和SQL接口层之间提供了底层的桥梁。

    • SQL接口层提供了对数据库的访问,包括 创建 / 删除库、表,执行增删改查的SQL语句。

    • 用户接口层提供了一种更加简便的方式将数据库中的数据链接到窗口部件上。

分层
驱动层QSqlDriver、QSqlDriverCreator、QSqlDriverCreatorBase、QSqlDriverPlugin和QSqlResult
SQL接口层QSqlDatabase、QSqlQuery、QSqlError、QSqlField、QSqlIndex和QSqlRecord
用户接口层QSqlQueryModel、QSqlTableModel、QSqlRelationalTableModel

2. 准备工作

  1. 创建项目,并在 .pro 文件中加入 sql 模块: QT += core gui sql

  2. 将 MySQL目录中的 libmysql.dll 和 libmysql.lib 文件复制到 Qt\5.12.3\mingw73_32\bin 目录下

如果不行,则去官网自己找 : MySQL :: Download MySQL Connector/C (Archived Versions)icon-default.png?t=O83Ahttps://downloads.mysql.com/archives/c-c/  

3. 链接数据库

  • Qt 默认支持一些驱动,可以通过 QSqlDatabase::drivers() 方法查看Qt支持的驱动类型。

  • 链接到数据库服务器需要使用 QSqlDatabase 类

  • 主要方法:

    • QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); // 链接MySQL服务器

    • db.setHostName("127.0.0.1"); // 设置服务器地址

    • db.setPort(3306); // 设置端口号,如果使用默认端口号可不调用该方法

    • db.setUserName("root"); // 设置用户名

    • db.setPassword("root"); // 设置密码

    • db.setDatabaseName("study"); // 设置要操作的数据库

    • db.open() // 打开数据库链接,返回值 bool

  • 其他方法

    • db.lastError(); // 获取上一次的错误信息, 返回一个 QSqlError 对象,调用 text() 方法转为字符串

#include <QSqlDatabase>
#include <QSqlError>
#include <QDebug>Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 打印支持的数据库驱动qDebug() << QSqlDatabase::drivers();QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");db.setHostName("127.0.0.1");db.setPort(3306);db.setUserName("root");db.setPassword("root");db.setDatabaseName("study");// 当数据库打开失败时,提示信息if(db.open()){qDebug() << "链接成功";}else{qDebug() << "链接失败" << db.lastError().text();}
}

4. 执行SQL语句

  • 执行 SQL 语句需要依靠 QSqlQuery 类

    • exec(QString sql) 方法用来执行sql语句

    • prepare() 方法执行预处理

    • execBatch() 执行预处理的SQL语句

1)创建库 (创建库)

Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 打印支持的数据库驱动qDebug() << QSqlDatabase::drivers();QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");db.setHostName("127.0.0.1");db.setPort(3306);db.setUserName("root");db.setPassword("root");// 当数据库打开失败时,提示信息if (!db.open()){QMessageBox::critical(this, "警告", db.lastError().text());return ;}// 创建 QSqlQuery 对象QSqlQuery query;query.exec("create database abc");      // 创建库}

 2)删除库

query.exec("drop database abc"); 

3)创建表

query.exec("create table student( \sno int(10) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, \sname varchar(30) not null unique, \sage  tinyint UNSIGNED, \sgender enum('男', '女') DEFAULT '男' \)ENGINE=MyISAM CHARSET=utf8"
);

4)删除表

query.exec("drop table student");

5)添加

// 添加单条数据
query.exec("insert into student values(1, '关羽', 30, '男')");
query.exec("insert into student values(null, '张飞', 28, '男')");// 批量添加 --- 方式1 
// ? 叫做占位符
query.prepare("insert into student(sname, sage, sgender) values(?,?,?)");QVariantList nameList;
nameList << "aaa" << "bbb" << "ccc";
QVariantList ageList;
ageList << 20 << 30 << 40;
QVariantList genderList;
genderList << "男" << "女" << "男";query.addBindValue(nameList);
query.addBindValue(ageList);
query.addBindValue(genderList);query.execBatch();// 批量添加 - 方式2
// :xxx : 数据名称
query.prepare("insert into student(sname, sage, sgender) values(:name, :age, :gender)");QVariantList nameList;
nameList << "小王" << "小张" << "小赵";
QVariantList ageList;
ageList << 20 << 30 << 40;
QVariantList genderList;
genderList << "男" << "女" << "男";query.bindValue(":name", nameList);
query.bindValue(":age", ageList);
query.bindValue(":gender", genderList);query.execBatch();

6)查询

// 执行查询
query.exec("select * from student");// 判断查询结果中是否有下一条数据
while (query.next()) {// value 方法用来设置列数据项,结果可以继续转为具体的数据类型qDebug() << query.value(0).toInt()<< query.value(1).toString()<< query.value("sage").toInt()<< query.value("sgender").toString();
}

7)更新

query.exec("update student set sage=35 where sno=1");// 注意事项: 字符串字段需要加引号
QString sql = QString("update student set sname='%1',sage=%2,sgender='%3' where sno=%4").arg("孙尚香").arg(20).arg("女").arg(1);
query.exec(sql);

8)删除

query.exec("delete from student where sno=2");// 批量删除
QString sql = QString("delete from student where sno in (%1)").arg("1,2,3");
query.exec(sql);

9)关闭数据库

db.close();

5. 可视化操作

  • Qt 提供了3个类来访问数据库,并且能够使用图形化方式来显示和操作数据

  • QSqlTableModel : 创建一个可编辑的表格式数据模型(注意:只能应用于单表)

  • QTableView :常见一个表格视图,可以将 QSqlTableModel 创建的模型自动填充到表格中

  • QSqlRelationalTableModel :创建关联数据类型的数据模型

5.1 准备工作

1.使用可视化操作时,也需要先进行数据库链接

// 链接数据库服务器
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("127.0.0.1");
db.setPort(3306);
db.setUserName("root");
db.setPassword("root");
db.setDatabaseName("study");if (!db.open())
{qDebug() << db.lastError().text();
}

2.设置ui界面

5.2 显示表格(R)

目标:查询 student 表中数据,并显示在表格中

实现步骤:

  1. 使用模型关联数据表

  2. 查询数据

  3. 关联模型和视图

// 实例化 Student 表模型
stuModel = new QSqlTableModel(this);// 1. 查询所有数据
// 设置stuModel模型关联的数据表
stuModel->setTable("student");
// 查询表中所有数据
stuModel->select();
// 将数据显示在视图中
ui->stuTableView->setModel(stuModel);

设置表头

// 设置表头
stuModel->setHeaderData(0, Qt::Horizontal, "学号");
stuModel->setHeaderData(1, Qt::Horizontal, "姓名");
stuModel->setHeaderData(2, Qt::Horizontal, "昵称");
stuModel->setHeaderData(3, Qt::Horizontal, "性别");
stuModel->setHeaderData(4, Qt::Horizontal, "年龄");
stuModel->setHeaderData(5, Qt::Horizontal, "入学时间");
stuModel->setHeaderData(6, Qt::Horizontal, "所属学院");

 设置表格修改方式为手动提交

// 设置表格隔行变色
ui->tableView->setAlternatingRowColors(true);// 设置表格宽度
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
// 设置单元格修改方式
stuModel->setEditStrategy(QSqlTableModel::OnManualSubmit);

5.3 添加

实现添加需要两步:

  1. 创建新行 QSqlRecord

  2. 点击 "提交" 按钮时将新数据提交到数据库

void Widget::on_addBtn_clicked()
{// 创建新数据记录QSqlRecord record = stuModel->record();// 获取数据行数int rowNum = stuModel->rowCount();// 添加一条新的空数据stuModel->insertRecord(rowNum, record);
}
void Widget::on_pushButton_4_clicked()
{stuModel->submitAll();
}

submitAll 方法:提交所有,包含本次添加,也可以包含同时修改的别的数据

5.4 删除

  • 实现思路:点击删除时,获取所有选中的行的行号,根据行号来执行删除

  • QItemSelectionModel: 能够获取所有选中的行(对象)

  • QModelIndexList : 能够从选中的行对象中 获取 对应的索引号

  • 有了索引号之后,就能循环从 stuModel 中进行删除

// 获取所有的选中行
QItemSelectionModel *selectedModel = ui->tableView->selectionModel();// 获取选中行的行号
QModelIndexList indexList = selectedModel->selectedRows();for (int i = 0; i < indexList.size(); i++)
{qDebug() << i << indexList[i].row();stuModel->removeRow(indexList[i].row());
}

5.5 撤销

void Widget::on_cancelModifyBtn_clicked()
{stuModel->revertAll();stuModel->submitAll();
}

5.6 排列

方案一: 使用 tableView 进行排列

方案二: 使用 stuModel 进行排列

// 降序排列
void Widget::on_descBtn_clicked()
{
//    ui->stuTableView->sortByColumn(0, Qt::DescendingOrder);stuModel->sort(0, Qt::DescendingOrder);
}
// 升序排列
void Widget::on_ascBtn_clicked()
{
//    ui->stuTableView->sortByColumn(0, Qt::AscendingOrder);stuModel->sort(0, Qt::AscendingOrder);
}

5.7 搜索

核心方法:setFilter(搜索条件)

实现思路:

  1. 点击搜索按钮时,获取关键词

  2. 拼接模糊查找的条件,调用 setFilter 进行设置

  3. 重新调用 select 方法执行查询,就能将满足条件的数据显示在表格中

// 搜索
void Widget::on_searchBtn_clicked()
{// 获取搜索关键词QString str = ui->lineEdit->text();// 构建模糊查询QString filterStr = QString("sname like '%%1%'").arg(str);// 过滤stuModel->setFilter(filterStr);// 查询stuModel->select();
}

5.8 关联表设置

QSqlTableModel: 适合单表操作

QSqlRelationalTableModel: 适合多表关联操作

stuModel = new QSqlRelationalTableModel(this);
stuModel->setTable("student");// 设置 student 与 dept 的关联关系
stuModel->setRelation(6, QSqlRelation("dept", "dno", "dname"));
stuModel->select();// 设置学科列的可选项只能是 dept 表中的数据
ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));

相关文章:

Qt-链接数据库可视化操作

1. 概述 Qt 能够支持对常见数据库的操作&#xff0c;例如&#xff1a; MySQL、Oracle、SqlServer 等等。 Qt SQL模块中的API分为三层&#xff1a;驱动层、SQL接口层、用户接口层。 驱动层为数据库和SQL接口层之间提供了底层的桥梁。 SQL接口层提供了对数据库的访问&#xff0…...

萤火php端: 查询数据的时候报错: “message“: “Undefined index: pay_status“,

代码&#xff1a;getGoodsFromHistory <?php // ---------------------------------------------------------------------- // | 萤火商城系统 [ 致力于通过产品和服务&#xff0c;帮助商家高效化开拓市场 ] // -----------------------------------------------------…...

程序人生-2024我的个人总结

可能现在写个人总结比较早&#xff0c;但是眼看着还有三个月&#xff0c;今年就过去了&#xff0c;所以决定提前写写&#xff0c;今年对于我来说是不平凡的一年&#xff0c;先是加薪&#xff0c;之后求婚&#xff0c;以为快要走上人生巅峰的时候&#xff0c;被裁员&#xff0c;…...

SQL自学:什么是联结,如何编写使用联结的SELECT语句

在 SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;的世界里&#xff0c;联结&#xff08;JOIN&#xff09;是一个强大且至关重要的概念。它允许我们从多个表中检索数据&#xff0c;从而实现更复杂的查询和数据分析。本文将深入探讨联结的概念…...

【C++】函数重载+引用

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解C的函数重载和引用&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 一. 预处理、编译、汇编、链接二. 函数重载1 概念2 C支持函数重载的原理—名字修饰…...

华为S5735交换机console密码重置和恢复出厂设置

比较简单&#xff0c;简单说就是进入bootload清除密码&#xff0c;然后进入default mode下重置密码。 1.开机按CtrlB&#xff0c;进入启动加载菜单&#xff08;BootLoad menu&#xff09; 拨电源重启交换机&#xff0c;大约开机10多秒的时候会出现提示按CtrlB可以进入BootLoa…...

Spring Security无脑使用

步骤1&#xff1a;添加Spring Security依赖 在你的Spring Boot项目的pom.xml文件中&#xff0c;添加Spring Security的依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</art…...

学习 PostgreSQL + Spring Boot 3 +mybatisplus整合过程中的报错记录

今天计划学习 PostgreSQL&#xff0c;并顺便尝试使用 Spring Boot 3.x 框架&#xff0c;打算整合 Spring Boot 3、PostgreSQL 和 MyBatis-Plus。整合后一直出现以下报错&#xff1a; 去AI上面搜了讲的是sqlSessionFactory 或 sqlSessionTemplate 没有正确配置 初始分析&#…...

立仪光谱共焦传感器在玻璃测量技术上的突破

近年来&#xff0c;随着科技的不断发展&#xff0c;光谱共焦传感器逐渐成为了工业检测领域的重要工具。尤其是在玻璃这种透明材质的厚度测量中&#xff0c;光谱共焦传感器展现出了其独特的优势。立仪科技小编将围绕光谱共焦传感器在玻璃行业中的应用&#xff0c;从问题、分析到…...

Llama系列上新多模态!3.2版本开源超闭源,还和Arm联手搞了手机优化版,Meta首款多模态Llama 3.2开源!1B羊驼宝宝,跑在手机上了

Llama系列上新多模态&#xff01;3.2版本开源超闭源&#xff0c;还和Arm联手搞了手机优化版&#xff0c;Meta首款多模态Llama 3.2开源&#xff01;1B羊驼宝宝&#xff0c;跑在手机上了&#xff01; 在多模态领域&#xff0c;开源模型也超闭源了&#xff01; 就在刚刚结束的Met…...

系统缺失mfc140.dll的修复方法,有效修复错误mfc140.dll详细步骤

mfc140.dll丢失原因分析 1 系统文件损坏或病毒感染 系统文件损坏或被病毒感染是导致mfc140.dll丢失的常见原因之一。根据用户反馈和安全研究报告&#xff0c;大约有30%的mfc140.dll丢失案例与系统文件损坏或病毒感染有关。病毒、木马或其他恶意软件可能会破坏或删除系统中的m…...

移动app的UI和接口自动化测试怎么进行?

标题&#xff1a;从0到1&#xff1a;移动App的UI和接口自动化测试 导语&#xff1a;移动App的快速发展使得UI和接口自动化测试成为了确保应用质量的重要环节。本文将从零开始介绍移动App的UI和接口自动化测试的基本概念以及如何进行测试。 第一部分&#xff1a;了解移动App自动…...

Unity实现自定义图集(二)

以下内容是根据Unity 2020.1.0f1版本进行编写的   实现一个自定义图集,该怎么入手呢。首先简单思考一下unity是怎么实现图集的。 因为unity的ui部分是开源的,所以我们可以看到UGUI的源代码,另外,Unity的内置Shader也是开源的,可以直接在官网下载(在下载的网页选择Built…...

智能码二维码zhinengma.cn的动态数据更新是如何实现的?

智能码二维码的动态数据更新功能是通过其背后的技术原理实现的&#xff0c;主要依赖于服务器和二维码的链接结构。以下是具体介绍&#xff1a; 动态数据更新的实现原理 链接嵌入&#xff1a;动态二维码中嵌入了一个链接&#xff0c;该链接指向服务器上的数据源。数据请求与更…...

uniapp view怎么按长度排列一行最多四个元素,并且换行后,每一行之间都有间隔

推荐学习文档 golang应用级os框架&#xff0c;欢迎stargolang应用级os框架使用案例&#xff0c;欢迎star案例&#xff1a;基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识&#xff0c;这里有免费的golang学习笔…...

Android列表组件api

目录 1.ListView控件 1&#xff09;android:divider 2&#xff09;android:dividerHeight 3&#xff09;android:entries 4&#xff09;android:footerDividersEnabled 5&#xff09;android:headerDividersEnabled 6&#xff09;android:listSelector 7&#xff09;android:sc…...

ToB项目身份认证AD集成(完):利用ldap.js实现与windows AD对接实现用户搜索、认证、密码修改等功能 - 以及针对中文转义问题的补丁方法介绍

在前面的两篇文章中&#xff0c;我详细的介绍了使用ldap与window AD服务集成&#xff0c;实现ToB项目中的身份认证集成方案&#xff0c;包括技术方案介绍、环境配置&#xff1a; ToB项目身份认证AD集成&#xff08;一&#xff09;&#xff1a;基于目录的用户管理、LDAP和Active…...

SpringBoot+SeetaFace6搭建人脸识别平台

前言 最近多个项目需要接入人脸识别功能&#xff0c;之前的方案是使用百度云api集成&#xff0c;但是后续部分项目是内网部署及使用&#xff0c;考虑到接入复杂程度及收费等多种因素&#xff0c;决定参考开源方案自己搭建&#xff0c;保证服务的稳定性与可靠性 项目地址&…...

MySQL-06.DDL-表结构操作-创建

一.DDL(表操作) create database db01;use db01;create table tb_user(id int comment ID&#xff0c;唯一标识,username varchar(20) comment 用户名,name varchar(10) comment 姓名,age int comment 年龄,gender char(1) comment 性别 ) comment 用户表; 此时并没有限制ID为…...

在Visual Studio中使用CMakeLists.txt集成EasyX库的详细指南

EasyX库是一款专为Windows平台设计的轻量级C图形库&#xff0c;适合初学者和教育领域使用。结合Visual Studio和CMake工具链&#xff0c;用户可以轻松创建C项目&#xff0c;并集成EasyX库&#xff0c;实现丰富的图形编程效果。本文将详细介绍如何在Visual Studio中通过CMakeLis…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...