Qt基于SQLite数据库的增删查改demo
一、效果展示

在Qt创建如图UI界面,主要包括“查询”、“添加”、“删除”、“更新”,四个功能模块。
查询:从数据库中查找所有数据的所有内容,并显示在左边的QListWidget控件上。
添加:在右边的QLineEdit标签上输入需要添加的内容,包含id,name,age三个字段,然后点击添加按钮,即可将数据添加至数据库。
删除:根据在id控件输入框中输入的id,删除数据库中指定那一行内容。
更新:根据输入的id号,对指定行数据的name字段内容进行修改。
如上四个功能来实现一个简单的增删查改demo。
二、基于数据库的操作
在qt中要使用数据库,需要在.pro文件中添加sql模块才能使用数据库的相关操作。

基本操作:
1.与数据库进行连接
QSqlDatabase db;
db = QSqlDatabase::addDatabase("QSQLITE"); // 指明数据库为SQLite
db.setDatabaseName("test.db"); // 连接的数据库名
2.打开数据库
db.open()
3.定义QSqlQuery
QSqlQuery query; // 用于执行对数据库的相关操作
QString sqlstr = QString("select * from user;"); // 定义sql语句
4.执行sql语句
query.exec(sqlstr)
1.连接数据库
QSqlDatabase db;
// 指明连接的是SQLite3数据库; 连接返回
db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("test.db"); // 连接的数据库文件,需要在打开数据库之前进行// 打开数据库
if(!db.open()){qDebug() << "Error failed to open" << db.lastError();
}
else{qDebug() << "open success";
}
db = QSqlDatabase::addDatabase("QSQLITE");指明使用的是SQLite数据库驱动。
db.setDatabaseName("test.db");与test.db数据库进行连接
db.open()打开数据库,返回值是bool类型,打开失败会返回false。在打开数据库之前,就需要指明连接的数据库。
db.lastError()该方法会打印数据库中最新的一条出错原因。
2.查询操作
void MainWindow::on_pushButton_find_clicked()
{ui->listWidget->clear(); // 清空之前的内容// 查询操作QSqlQuery query;QString sqlstr = QString("select * from user;");if(!query.exec(sqlstr)){qDebug() << "查询错误:" << query.lastError();return;}// 因为查询出的数据可能不止一条,所以需要循环打印while(query.next()){// 获取每一条记录的内容int id = query.value("id").toInt();QString name = query.value("name").toString();int age = query.value("age").toInt();// 将数据更新到控件界面上// 创建一条数据的条目itemFrom *userItem = new itemFrom;userItem->setUserInfo(id, name, age); // 设置该条记录内容QListWidgetItem *item = new QListWidgetItem(ui->listWidget);item->setSizeHint(QSize(442, 29));ui->listWidget->addItem(item);ui->listWidget->setItemWidget(item, userItem);}
}
QSqlQuery query;创建一个QSqlQuery对象,用于执行对数据库进行的一些操作。QString sqlstr = QString("select * from user;");定义一条查询语句,查询user表中所有的内容。query.exec(sqlstr)执行自定义的sql语句,执行失败会返回false。query.next()该函数会指向我们指向我们指向sql语句后,返回结果的第一条内容,每执行一次,就会指向下一条内容,如果没有内容了就会返回false。query.value("id")该函数会匹配查询出来的结果中,一条记录中对应“id”字段的内容,以字符串的形式返回。
3.添加操作
void MainWindow::on_pushButton_add_clicked()
{// 获取控件上的内容QString name = ui->lineEdit_name->text();QString age = ui->lineEdit_age->text();// 执行插入操作QSqlQuery query;// %表示占位符QString sqlstr = QString("insert into user(name, age) ""values('%1', %2)").arg(name).arg(age.toInt());if(!query.exec(sqlstr)){qDebug() << "插入错误:" << query.lastError();return;}
}
首先获取输入框中对应的内容;然后创建QSqlQuery对象执行sql语句。在user表中,id字段设置为自增,所以不需要输入id的内容来进行添加。
QString("insert into user(name, age) ""values('%1', %2)").arg(name).arg(age.toInt());
在字符串中,%1表示的是占位符,数字1表示序号。使用arg()方法将内容填充到对应的占位符中,顺序方式填充。
query.exec(sqlstr)函数执行sql语句。
4.删除操作
void MainWindow::on_pushButton_del_clicked()
{// 获取控件上的内容QString id = ui->lineEdit_id->text();// 执行删除操作QSqlQuery query;// %表示占位符QString sqlstr = QString("delete from user ""where id = %1").arg(id.toInt());if(!query.exec(sqlstr)){qDebug() << "删除错误:" << query.lastError();return;}// 同时更新控件上的显示ui->listWidget->takeItem(id.toInt()-1);
}
实现方式类似,需要根据需求自定义一条sql语句,然后调用执行。
5.修改操作
void MainWindow::on_pushButton_update_clicked()
{// 获取控件上的内容QString name = ui->lineEdit_name->text();QString id = ui->lineEdit_id->text();// 执行更新操作QSqlQuery query;// %表示占位符QString sqlstr = QString("update user set name = '%1' ""where id = %2 ;").arg(name).arg(id.toInt());if(!query.exec(sqlstr)){qDebug() << "更新错误:" << query.lastError();return;}
}
先获取输入框中的内容,然后进行编写修改的sql语句,使用%1表示占位符,使用arg()进行填充,最后执行sql语句。
完整代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "itemfrom.h"#include <QDebug>
#include <QSqlError> // 数据库操作错误信息
#include <QListWidgetItem>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 指明连接的是SQLite3数据库; 连接返回db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("test.db"); // 连接的数据库文件,需要在打开数据库之前进行// 打开数据库if(!db.open()){qDebug() << "Error failed to open" << db.lastError();}else{qDebug() << "open success";}
}MainWindow::~MainWindow()
{db.close();delete ui;
}// 添加
void MainWindow::on_pushButton_add_clicked()
{// 获取控件上的内容QString name = ui->lineEdit_name->text();QString age = ui->lineEdit_age->text();// 执行插入操作QSqlQuery query;// %表示占位符QString sqlstr = QString("insert into user(name, age) ""values('%1', %2)").arg(name).arg(age.toInt());if(!query.exec(sqlstr)){qDebug() << "插入错误:" << query.lastError();return;}
}
// 删除
void MainWindow::on_pushButton_del_clicked()
{// 获取控件上的内容QString id = ui->lineEdit_id->text();// 执行删除操作QSqlQuery query;// %表示占位符QString sqlstr = QString("delete from user ""where id = %1").arg(id.toInt());if(!query.exec(sqlstr)){qDebug() << "删除错误:" << query.lastError();return;}// 同时更新控件上的显示ui->listWidget->takeItem(id.toInt()-1);
}
// 更新
void MainWindow::on_pushButton_update_clicked()
{// 获取控件上的内容QString name = ui->lineEdit_name->text();QString id = ui->lineEdit_id->text();// 执行更新操作QSqlQuery query;// %表示占位符QString sqlstr = QString("update user set name = '%1' ""where id = %2 ;").arg(name).arg(id.toInt());if(!query.exec(sqlstr)){qDebug() << "更新错误:" << query.lastError();return;}
}
// 查询
void MainWindow::on_pushButton_find_clicked()
{ui->listWidget->clear(); // 清空之前的内容// 查询操作QSqlQuery query;QString sqlstr = QString("select * from user;");if(!query.exec(sqlstr)){qDebug() << "查询错误:" << query.lastError();return;}// 因为查询出的数据可能不止一条,所以需要循环打印while(query.next()){// 获取每一条记录的内容int id = query.value("id").toInt();QString name = query.value("name").toString();int age = query.value("age").toInt();// 更新到控件上// 创建一条数据的条目itemFrom *userItem = new itemFrom;userItem->setUserInfo(id, name, age); // 设置该条记录内容QListWidgetItem *item = new QListWidgetItem(ui->listWidget);item->setSizeHint(QSize(442, 29));ui->listWidget->addItem(item);ui->listWidget->setItemWidget(item, userItem);}
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QSqlDatabase> // 用于连接打开数据库
#include <QSqlQuery> // 用于访问操作数据库QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void on_pushButton_add_clicked();void on_pushButton_del_clicked();void on_pushButton_update_clicked();void on_pushButton_find_clicked();private:Ui::MainWindow *ui;QSqlDatabase db;
};
#endif // MAINWINDOW_H
QListWidget中每一条记录的显示,可以自定义一种显示方式,新建一个类itemfrom

#ifndef ITEMFROM_H
#define ITEMFROM_H#include <QMainWindow>namespace Ui {
class itemFrom;
}class itemFrom : public QMainWindow
{Q_OBJECTpublic:explicit itemFrom(QWidget *parent = nullptr);~itemFrom();void setUserInfo(int id, QString name, int age);private:Ui::itemFrom *ui;
};#endif // ITEMFROM_H
#include "itemfrom.h"
#include "ui_itemfrom.h"itemFrom::itemFrom(QWidget *parent) :QMainWindow(parent),ui(new Ui::itemFrom)
{ui->setupUi(this);
}itemFrom::~itemFrom()
{delete ui;
}
// 将值设置在ui上
void itemFrom::setUserInfo(int id, QString name, int age)
{ui->label_id2->setText(QString::number(id));ui->label_age2->setText(QString::number(age));ui->label_name2->setText(name);
}相关文章:
Qt基于SQLite数据库的增删查改demo
一、效果展示 在Qt创建如图UI界面,主要包括“查询”、“添加”、“删除”、“更新”,四个功能模块。 查询:从数据库中查找所有数据的所有内容,并显示在左边的QListWidget控件上。 添加:在右边的QLineEdit标签上输入需…...
新书推荐:2.2.4 第11练:消息循环
/*------------------------------------------------------------------------ 011 编程达人win32 API每日一练 第11个例子GetMessage.c:消息循环 MSG结构 GetMessage函数 TranslateMessage函数:将虚拟键消息转换为字符消息 DispatchMessage函数…...
MASA:匹配一切、分割一切、跟踪一切
文章目录 摘要1、引言2、相关工作2.1、学习实例级关联2.2、Segment and Track Anything 模型 3、方法3.1、预备知识:SAM3.2、通过分割任何事物来匹配任何事物3.2.1、MASA流程3.2.2、MASA适配器3.2.3、推理 4、实验4.1、实验设置4.2、与最先进技术的比较4.3、消融研究…...
Websocket前端传参:深度解析与实战应用
Websocket前端传参:深度解析与实战应用 在现代Web开发中,Websocket作为一种双向通信协议,已经广泛应用于实时数据传输场景。前端传参作为Websocket通信的重要组成部分,其正确性和高效性直接影响到应用的性能和用户体验。本文将深…...
造假高手——faker
在测试写好的代码时通常需要用到一些测试数据,大量的真实数据有时候很难获取,如果手动制造测试数据又过于繁重无聊,显得不够优雅,今天我们介绍的faker这个轮子可以完美的解决这个问题。faker是一个用于生成各种类型假数据的库&…...
前端工程化工具系列(十二)—— PostCSS(v8.4.38):CSS 转换工具
PostCSS 是转换 CSS 语法的工具。它提供 API 来对 CSS 文件进行分析和修改它的规则。 PostCSS 本身并不能直接使用,主要是使用基于 PostCSS 编写的插件。 1 安装 pnpm add -D postcss-import postcss-nested postcss-preset-env cssnano2 配置 在项目根目录下创…...
Scanpy(3)单细胞数据分析常规流程
单细胞数据分析常规流程 面对高效快速的要求上,使用R分析数据越来越困难,转战Python分析,我们通过scanpy官网去学习如何分析单细胞下游常规分析。 数据3k PBMC来自健康的志愿者,可从10x Genomics免费获得。在linux系统上,可以取消注释并运行以下操作来下载和解压缩数据。…...
【Stable Diffusion】(基础篇二)—— Stable Diffusion图形界面介绍和基本使用流程
本系列笔记主要参考B站nenly同学的视频教程,传送门:B站第一套系统的AI绘画课!零基础学会Stable Diffusion,这绝对是你看过的最容易上手的AI绘画教程 | SD WebUI 保姆级攻略_哔哩哔哩_bilibili 在上一篇博客中,我们成功…...
OpenCv之简单的人脸识别项目(动态处理页面)
人脸识别 准备九、动态处理页面1.导入所需的包2.设置窗口2.1定义窗口外观和大小2.2设置窗口背景2.2.1设置背景图片2.2.2创建label控件 3.定义视频处理脚本4.定义相机抓取脚本5.定义关闭窗口的函数6.按钮设计6.1视频处理按钮6.2相机抓取按钮6.3返回按钮 7.定义关键函数8.动态处理…...
【Linux】进程间通信
目录 一、进程间通信概念 二、进程间通信的发展 三、进程间通信的分类 四、管道 4.1 什么是管道 4.2 匿名管道 4.2 基于匿名管道设计进程池 4.3 命名管道 4.4 用命名管道实现server&client通信 五、system V共享内存 5.1 system V共享内存的引入 5.2 共享内存的…...
UI与前端:揭秘两者的微妙差异
UI与前端:揭秘两者的微妙差异 在数字化时代的浪潮中,UI设计和前端开发已成为塑造用户体验的两大核心力量。然而,这两者之间究竟有何区别?本文将深入剖析UI设计与前端开发的四个方面、五个方面、六个方面和七个方面的差异…...
idea如何根据路径快速在项目中快速打卡该页面
在idea项目中使用快捷键shift根据路径快速找到该文件并打卡 双击shift(连续按两下shift) -粘贴文件路径-鼠标左键点击选中跳转的路径 自动进入该路径页面 例如:我的实例路径为src/views/user/govType.vue 输入src/views/user/govType或加vue后缀src/views/user/go…...
探索成功者的特质——俞敏洪的观点启示
在人生的舞台上,我们常常对成功者充满好奇与敬仰,试图探寻他们成功的奥秘。俞敏洪指出,成功者都具备七个特质,而这些特质与家庭背景和大学的好坏并无直接关系。让我们深入剖析这七个特质,或许能从中获得对我们自身成长…...
MCU的环形FIFO
fifo.h #ifndef __FIFO_H #define __FIFO_H#include "main.h"#define RINGBUFF_LEN (500) //定义最大接收字节数 500typedef struct {uint16_t Head; // 头指针 指向可读起始地址 每读一个,数字1uint16_t Tail; // 尾指针 指…...
使用proteus仿真51单片机的流水灯实现
proteus介绍: proteus是一个十分便捷的用于电路仿真的软件,可以用于实现电路的设计、仿真、调试等。并且可以在对应的代码编辑区域,使用代码实现电路功能的仿真。 汇编语言介绍: 百度百科介绍如下: 汇编语言是培养…...
【漏洞复现】Apache OFBiz 路径遍历导致RCE漏洞(CVE-2024-36104)
0x01 产品简介 Apache OFBiz是一个电子商务平台,用于构建大中型企业级、跨平台、跨数据库、跨应用服务器的多层、分布式电子商务类应用系统。是美国阿帕奇(Apache)基金会的一套企业资源计划(ERP)系统。该系统提供了一整套基于Java的Web应用程序组件和工具。 0x02 …...
数据库表中创建字段查询出来却为NULL?
起因: 今天新创建了一张表,其中一个字段命名为"word_num"带下划线,我在前端页面怎么也查询不出来word_num的值,后来在后端接口处打印了一下数据库查询出来的数据,发现这个字段一直为NULL,然后我就想到是不是…...
缓存方法返回值
1. 业务需求 前端用户查询数据时,数据查询缓慢耗费时间; 基于缓存中间件实现缓存方法返回值:实现流程用户第一次查询时在数据库查询,并将查询的返回值存储在缓存中间件中,在缓存有效期内前端用户再次查询时,从缓存中间件缓存获取 2. 基于Redis实现 参考1 2.1 简单实现 引入…...
【十大排序算法】快速排序
在乱序的世界中,快速排序如同一位智慧的园丁, 以轻盈的手法,将无序的花朵们重新安排, 在每一次比较中,沐浴着理性的阳光, 终使它们在有序的花园里,开出绚烂的芬芳。 文章目录 一、快速排序二、…...
linux系统ubuntu中在命令行中打开图形界面的文件夹
在命令行中打开当前路径,以文件管理器的形式打开: 命令 # 打开文件管理器 当前的路径 nautilus .nautilus 是一个与 GNOME 桌面环境集成的文件管理器的命令行启动程序。在 Linux 系统中,特别是使用 GNOME 作为桌面环境时,用户经…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
表单设计器拖拽对象时添加属性
背景:因为项目需要。自写设计器。遇到的坑在此记录 使用的拖拽组件时vuedraggable。下面放上局部示例截图。 坑1。draggable标签在拖拽时可以获取到被拖拽的对象属性定义 要使用 :clone, 而不是clone。我想应该是因为draggable标签比较特。另外在使用**:clone时要将…...
