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));

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

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

相关文章

蓝桥杯【物联网】零基础到国奖之路:十六. 扩展模块之矩阵按键

蓝桥杯【物联网】零基础到国奖之路:十六. 扩展模块之矩阵按键 第一节 硬件解读第二节 CubeMX配置第三节 MDK代码 第一节 硬件解读 扩展模块和ADC模块是一摸一样的&#xff0c;插在主板上。 引脚对应关系&#xff1a; PB6-ROW1 PB7-ROW2 PB1-COLUMN1 PB0-COLUMN2 PA8-COLUMN3 …

SQL 注入漏洞 - 学习手册

0x01&#xff1a;SQL 注入前导知识 0x0101&#xff1a;SQL 注入 —— MySQL 数据库概述 知识速查&#xff1a;SQL 注入前导知识 SQL 注入 —— MySQL 数据库概述 获取数据库名 : select schema_name from information_schema.schemata;获取数据表名 : select table_name from …

adb安装教程(Windows10)

本章教程&#xff0c;主要介绍如何在Windows10操作系统上安装adb。 一、adb简介 ADB&#xff0c;全称为Android Debug Bridge&#xff0c;是Android开发中一个重要的命令行工具。它用于与Android设备进行通信&#xff0c;提供了多种功能来帮助开发者进行调试和应用管理。 二、下…

Qt第三课 ----------显示类的控件属性

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

Java中的状态机实现:使用Spring State Machine管理复杂状态流转

在软件开发中&#xff0c;我们经常会遇到需要处理各种状态以及状态之间转换的场景。这些状态转换有时会变得非常复杂&#xff0c;特别是当涉及到多个状态&#xff0c;并且每个状态都有多个可能的触发事件导致不同的状态变化时。手动编写这样的逻辑不仅容易出错&#xff0c;而且…

美团Java一面

美团Java一面 9.24一面&#xff0c;已经寄了 收到的第一个面试&#xff0c;表现很不好 spring bean生命周期 作用域&#xff08;忘完了&#xff09; 为什么用redis缓存 redis和数据库的缓存一致性问题 redis集群下缓存更新不一致问题 aop说一下 arraylist和linkedlist 数据库的…

kali(专业的渗透测试虚拟机)|kali下载链接地址 |kali安装 |kali部署指南

介绍 kali 是Debian开源linux系统体系下的子分支之一 Debian-kali 扩展&#xff1a;Ubuntu也是Debian开源linux系统体系下的子分支之一 Debian-ubuntu 安装kali 2023.03 稳定版 Index of /kali-images/kali-2023.1/ 安装可以参考他的教程&#xff0c; 写的很详细了…

软件工程系列(1)需求工程

需求工程需求工程是软件开发过程中的关键环节,旨在明确和管理用户需求。其主要步骤包括: 1. 需求获取 方法:访谈、问卷、观察和焦点小组等。目标:理解用户需求,收集功能和非功能需求。2. 需求分析 整理与分类:将收集到的需求进行整理,识别优先级和依赖关系。建模:使用…

C语言-数据结构 折半查找

在折半查找中&#xff0c;刚开始学可能会在下标处产生困惑&#xff0c;例如奇数个长度的数组怎么处理&#xff0c;偶数个长度的数组怎么处理&#xff0c;不需要修改代码吗&#xff1f;并且下标我从1开始算和0开始算影响代码吗&#xff1f;其实都可以用一样的代码&#xff0c;产…

nginx 资料整理(三)- web

nginx 资料整理&#xff08;三&#xff09; 1. web服务器1. 日志功能1. 访问日志2. 错误日志3. 实例演示 2. 网站功能列表1. autoindex2. autoindex_localtime 3. 认证功能1. auth_basic2. 实例演示 4. 访问控制功能1. allow & deny2. 局限性3. 实例演示 5. 状态模块1. stu…

论文阅读:Split-Aperture 2-in-1 Computational Cameras (二)

Split-Aperture 2-in-1 Computational Cameras (一) Coded Optics for High Dynamic Range Imaging 接下来&#xff0c;文章介绍了二合一相机在几种场景下的应用&#xff0c;首先是高动态范围成像&#xff0c;现有的快照高动态范围&#xff08;HDR&#xff09;成像工作已经证…

多种方式确定Linux是CentOS还是Ubuntu

目录 前言正文 前言 对应的基本知识比较少&#xff0c;以下只是记录总结 由于目前使用的是centos&#xff0c;后续找到linux会对应补充 正文 要确定Linux系统是CentOS还是Ubuntu&#xff0c;可以通过以下几种方式进行分析 一、查看发行版信息文件&#xff1a; CentOS&…

校园系统校园小程序 论坛校园圈系统失物招领、闲置二手、跑腿外卖等校园圈子系统应该具备有哪些功能

针对校园系统、校园小程序、论坛校园圈系统以及失物招领、闲置二手、跑腿外卖等具体功能&#xff0c;一个综合性的校园圈子系统应该具备以下主要功能&#xff1a; 前后端源码查看 一、基础功能 用户注册与登录 提供用户注册和登录功能&#xff0c;支持学生身份验证、手机号验…

chrome 阻止浏览器在表单输入框聚焦/输入时显示保存的密码和账号候选框(Google 密码管理工具)

参考: 完美解决 element-ui inputpassword 在浏览器会自动填充密码的问题 背景: 领导要求去掉登录页的账号密码表单的自动显示账号密码候选框 定位: chrome 版本 126.0.6478.127 , 现有表单用的是原生 input 元素, 之前已经加了 autocomplete"off" 和 readonly …

WireShark过滤器

文章目录 1. **捕获过滤器&#xff08;Capture Filter&#xff09;**语法格式&#xff1a;常见捕获过滤器示例&#xff1a; 2. **显示过滤器&#xff08;Display Filter&#xff09;**语法格式&#xff1a;常见比较运算符&#xff1a;常见显示过滤器示例&#xff1a;逻辑操作符…

Linux系统:apt-get update 和apt update区别

apt-get update 和apt update区别 ‌apt-get update和apt update的主要区别在于它们所属的命令集以及在现代Ubuntu系统中的使用推荐。‌ ‌所属命令集‌&#xff1a;apt-get update是apt-get命令的一部分&#xff0c;而apt update是apt命令的一部分。apt是apt-get的替代工具&am…

Java面经--从代码角度认识面向对象编程和面向过程编程

1. 思维方式和核心概念 面向过程编程&#xff1a;核心是过程&#xff08;procedure&#xff09;&#xff0c;即通过函数来组织和实现功能。程序被分为一系列的步骤或过程&#xff0c;数据和功能分离&#xff0c;代码通常是顺序执行的。 面向对象编程&#xff1a;核心是对象&am…

回归涉及的函数

当然可以&#xff01;以下是你学习笔记中涉及到的函数的详细讲解&#xff1a; 1. 导入必要的库 import: 用于导入所需的库和模块。例如&#xff0c;import numpy as np 导入 NumPy 库并简写为 np。 2. 读取数据 pd.read_csv(temps.csv): 读取指定路径的 CSV 文件&#xff0…

苹果秋季盛典:iPhone 16系列引领未来科技潮流

9月10日&#xff0c;苹果公司在众人瞩目中举办了2024年的秋季特别活动&#xff0c;发布了备受期待的iPhone 16系列。 尽管网络发布会已经持续了一整年&#xff0c;但熬夜观看的果粉们仍然热情不减&#xff0c;因为每一次苹果的新品发布都代表着科技界的一次重大飞跃。 iPhone …

使用C++的OpenSSL 库实现 AES 加密和解密文件

如果C不知道做什么项目&#xff0c;可以编写一个文件加密和解密工具&#xff0c;支持诸如 AES 和 RSA 等常见的加密算法。这样的项目可以帮助学习和理解现代加密技术&#xff0c;并为日常文件保护提供便利。以下是一个基本的设计思路和实现步骤&#xff1a; 1. 设计思路 a. 功…