当前位置: 首页 > 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;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...