Qt下使用Sqlite数据库实现图像的读写显示

news2024/12/26 11:43:00

系列文章目录

提示:这里是该系列文章的所有文章的目录
第一章: Qt连接Sqlite3并使用Qtableview实时显示数据,重写QSqlQueryModel实现文本居中
第二章: Qt下使用Sqlite数据库实现图片的读写显示


文章目录

  • 系列文章目录
  • 前言
  • 一、初始化数据库
  • 二、获取图像数据
  • 三、查找指定图像
  • 四、示例完整代码
  • 四、下载链接
  • 总结


前言

在本系列文章的上一篇文章中,有对在Qt中使用Sqlite3数据库的相关介绍及配置,使用起来也是比较方便的,详情可以点击目录链接查看。在Qt中使用Sqlite数据库可以保存很多类型的数据,其中还可以用来保存图像,这里对图像的保存和读取显示功能进行讲述,并将相关代码展现出来以便大家学习,如有错误之处,欢迎大家批评指正。

项目效果
请添加图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、初始化数据库

在构造函数内以当天日期为名称创建数据库并打开,同时创建名为imageTable的数据表,在表中添加了id、name(图像名)、data(图像数据)、timestamp(时间戳)四个数据,其中id会跟随插入的数据量自动递增,后面的查找功能也是通过查找id来实现的。

//以当天日期为名称创建数据库并打开
QString dbName = QDate::currentDate().toString("yyyyMMdd") + ".db";
m_db = QSqlDatabase::addDatabase("QSQLITE");
m_db.setDatabaseName(dbName);
if(!m_db.open())
{
    QMessageBox::information(this,"提示",m_db.lastError().text());
    return;
}

//创建名为imageTable的数据表
QSqlQuery query(m_db);
if(!query.exec("CREATE TABLE IF NOT EXISTS imageTable (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, data BLOB, timestamp TEXT)"))
{
    QMessageBox::information(this,"提示",query.lastError().text());
    return;
}

二、获取图像数据

这里使用了模拟添加图像的方式来获取图像数据,打开指定文件夹并选中其中的图像,将图像保存到数据库。

//从文件夹获取图像数据
void Widget::on_pb_getImage_clicked()
{
    //选择图像
    QString fileName = QFileDialog::getOpenFileName(this,"open file dialog","D:/QT/Project/my_Project/28_iamgeSqlite","jpg files(*.jpg)");
    if(fileName == "")
    {
        return;
    }

    //获取图像名
    m_imageName = QFileInfo(fileName).fileName();
    ui->lb_name->setText(m_imageName);

    //界面显示
    QImage image;
    image.load(fileName);
    ui->lb_image->setPixmap((QPixmap::fromImage(image)).scaled(ui->lb_image->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));

    //获取图像数据
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly))
    {
        QMessageBox::information(this,"提示",file.errorString());
        return;
    }
    m_imageData = file.readAll();
    file.close();
}

//保存图像到数据库
void Widget::on_pb_saveDb_clicked()
{
    QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    ui->lb_dateTime->setText(timestamp);

    //插入图像和时间戳
    QSqlQuery query(m_db);
    query.prepare("INSERT INTO imageTable (name, data, timestamp) VALUES (:name, :data, :timestamp)");
    query.bindValue(":name",m_imageName);
    query.bindValue(":data",m_imageData);
    query.bindValue(":timestamp",timestamp);
    if(!query.exec())
    {
        QMessageBox::information(this,"提示",query.lastError().text());
        return;
    }
    else
    {
        QMessageBox::information(this,"提示","保存成功!");
    }
}

三、查找指定图像

这里使用了SELECT查找语句,根据数据表中的id来进行指定图像的查找,获取图像数据及各参数并显示在界面上,更多SQL语句可以查看本系列上一篇文章中的参考文章,有详细的SQLite教程。

//根据id提取图像
void Widget::getImageData(int id)
{
    QSqlQuery query(m_db);
    if(!query.exec(QString("SELECT name, data, timestamp FROM imageTable WHERE id = %1").arg(id)))
    {
        QMessageBox::information(this,"提示",query.lastError().text());
        return;
    }
    if(query.next())
    {
        //图像名
        QString imageName = query.value(0).toString();
        ui->lb_name->setText(imageName);

        //显示图像
        QByteArray imageData = query.value(1).toByteArray();
        QPixmap pixmap;
        if(pixmap.loadFromData(imageData))
        {
            ui->lb_image->setPixmap(pixmap.scaled(ui->lb_image->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
        }

        //时间戳
        QString timestamp = query.value(2).toString();
        ui->lb_dateTime->setText(timestamp);
    }
}

四、示例完整代码

别忘记在Qt项目文件(.pro文件)中,加入SQL模块哦!(QT += sql)
1.widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QFile>
#include <QFileDialog>
#include <QDateTime>
#include <QMessageBox>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void initWidget();
    void getImageData(int id);

private slots:
    void on_pb_getImage_clicked();
    void on_pb_saveDb_clicked();
    void on_pb_find_clicked();
    void on_pb_last_clicked();
    void on_pb_next_clicked();

private:
    Ui::Widget *ui;

    QSqlDatabase m_db;        //数据库对象
    QString m_imageName;      //图像名
    QByteArray m_imageData;   //图像数据
};
#endif // WIDGET_H

2.widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->initWidget();
}

Widget::~Widget()
{
    delete ui;
}

//初始化界面
void Widget::initWidget()
{
    //初始化变量
    m_imageName = "";
    m_imageData = "";

    //以当天日期为名称创建数据库并打开
    QString dbName = QDate::currentDate().toString("yyyyMMdd") + ".db";
    m_db = QSqlDatabase::addDatabase("QSQLITE");
    m_db.setDatabaseName(dbName);
    if(!m_db.open())
    {
        QMessageBox::information(this,"提示",m_db.lastError().text());
        return;
    }

    //创建名为imageTable的数据表
    QSqlQuery query(m_db);
    if(!query.exec("CREATE TABLE IF NOT EXISTS imageTable (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, data BLOB, timestamp TEXT)"))
    {
        QMessageBox::information(this,"提示",query.lastError().text());
        return;
    }
}

//根据id提取图像
void Widget::getImageData(int id)
{
    QSqlQuery query(m_db);
    if(!query.exec(QString("SELECT name, data, timestamp FROM imageTable WHERE id = %1").arg(id)))
    {
        QMessageBox::information(this,"提示",query.lastError().text());
        return;
    }
    if(query.next())
    {
        //图像名
        QString imageName = query.value(0).toString();
        ui->lb_name->setText(imageName);

        //显示图像
        QByteArray imageData = query.value(1).toByteArray();
        QPixmap pixmap;
        if(pixmap.loadFromData(imageData))
        {
            ui->lb_image->setPixmap(pixmap.scaled(ui->lb_image->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
        }

        //时间戳
        QString timestamp = query.value(2).toString();
        ui->lb_dateTime->setText(timestamp);
    }
}

//从文件夹获取图像数据
void Widget::on_pb_getImage_clicked()
{
    //选择图像
    QString fileName = QFileDialog::getOpenFileName(this,"open file dialog","D:/QT/Project/my_Project/28_iamgeSqlite","jpg files(*.jpg)");
    if(fileName == "")
    {
        return;
    }

    //获取图像名
    m_imageName = QFileInfo(fileName).fileName();
    ui->lb_name->setText(m_imageName);

    //界面显示
    QImage image;
    image.load(fileName);
    ui->lb_image->setPixmap((QPixmap::fromImage(image)).scaled(ui->lb_image->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));

    //获取图像数据
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly))
    {
        QMessageBox::information(this,"提示",file.errorString());
        return;
    }
    m_imageData = file.readAll();
    file.close();
}

//保存图像到数据库
void Widget::on_pb_saveDb_clicked()
{
    QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    ui->lb_dateTime->setText(timestamp);

    //插入图像和时间戳
    QSqlQuery query(m_db);
    query.prepare("INSERT INTO imageTable (name, data, timestamp) VALUES (:name, :data, :timestamp)");
    query.bindValue(":name",m_imageName);
    query.bindValue(":data",m_imageData);
    query.bindValue(":timestamp",timestamp);
    if(!query.exec())
    {
        QMessageBox::information(this,"提示",query.lastError().text());
        return;
    }
    else
    {
        QMessageBox::information(this,"提示","保存成功!");
    }
}

//查找指定图像
void Widget::on_pb_find_clicked()
{
    //判断是否输入正确
    int id = ui->le_id->text().toInt();

    //获取图像数
    QSqlQuery query(m_db);
    query.exec("SELECT COUNT(id) FROM imageTable");
    query.next();
    int idMax = query.value(0).toInt();
    qDebug()<<idMax;

    if(id < 1)
    {
        getImageData(1);
        ui->le_id->setText(QString::number(1));
        QMessageBox::information(this,"提示","id超限!");
    }
    else if(id > idMax)
    {
        getImageData(idMax);
        ui->le_id->setText(QString::number(idMax));
        QMessageBox::information(this,"提示","id超限!");
    }
    else
    {
        getImageData(idMax);
    }
}

//上一张
void Widget::on_pb_last_clicked()
{
    int id = ui->le_id->text().toInt();
    if(id <= 1)
    {
        getImageData(1);
        ui->le_id->setText(QString::number(1));
        QMessageBox::information(this,"提示","当前图像为第一张!");
        return;
    }
    int idLast = id-1;
    getImageData(idLast);
    ui->le_id->setText(QString::number(idLast));
}

//下一张
void Widget::on_pb_next_clicked()
{
    //获取图像数
    QSqlQuery query(m_db);
    query.exec("SELECT COUNT(id) FROM imageTable");
    query.next();
    int idMax = query.value(0).toInt();

    int id = ui->le_id->text().toInt();
    if(id >= idMax)
    {
        getImageData(idMax);
        ui->le_id->setText(QString::number(idMax));
        QMessageBox::information(this,"提示","当前图像为最后一张!");
        return;
    }
    int idNext = id+1;
    getImageData(idNext);
    ui->le_id->setText(QString::number(idNext));
}

3.widget.ui
请添加图片描述

四、下载链接

我的示例百度网盘链接:https://pan.baidu.com/s/1RmVG4FQFI9NIe9T4clTRVQ
提取码:xxcj


总结

本文实现了Qt下使用Sqlite数据库来进行图像的数据保存及读取,demo实现使用的sql语句也是比较简单的,实际项目的话会比较复杂,所以我们还是需要不断的学习,以此掌握更多SQLite的知识技能。


hello:
共同学习,共同进步,如果还有相关问题,可在评论区留言进行讨论。

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

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

相关文章

python3.10在centos下安装以及配置

python在centos下安装以及配置 1.背景 centos下默认的都是python2.7下载需要更换为3.x使用&#xff0c;目前大部分应用都是基于pyhton3了 具体步骤&#xff1a; 先按装openssh 不安装会报错 而且要安装高版本 要不然不兼容 报错如&#xff1a; WARNING: pip is configured …

chatgpt赋能python:Python创建程序的SEO指南

Python创建程序的SEO指南 Python是一种流行的高级编程语言&#xff0c;被广泛用于开发Web应用程序、人工智能、数据分析和科学计算等领域。在创建Python程序时&#xff0c;也要考虑SEO因素&#xff0c;以优化网页在搜索引擎结果中的排名。本文将介绍如何创建具有SEO友好性的Py…

软考A计划-电子商务设计师-电子商务系统开发知识

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

【深入浅出 Spring Security(四)】登录用户数据的获取,超详细的源码分析

登录用户数据的获取 一、SecurityContextHolder 源码分析ListeningSecurityContextHolderStrategy 使用案例SecurityContextPersistenceFilter 说明 二、登录用户数据的获取三、总结 在【深入浅出Spring Security&#xff08;一&#xff09;】Spring Security的整体架构 中叙述…

Gradle 介绍,根据 Gradle 官方文档整理

这部分内容主要根据 Gradle 官方文档整理&#xff0c;做了对应的删减&#xff0c;主要保留比较重要的部分&#xff0c;不涉及实战&#xff0c;主要是一些重要概念的介绍。 Gradle 这部分内容属于可选内容&#xff0c;可以根据自身需求决定是否学习&#xff0c;目前国内还是使用…

回调函数与钩子函数的区别,另QT中connect函数的实现,lambda的使用

1、钩子函数是回调函数的一种 广泛来说两者都是一样的 严格来说 钩子函数的函数名早已被定义好&#xff0c;只是函数内部需要用户在应用层来定义&#xff0c; 1&#xff09;可以完全通过宏来实现系统是否调用该函数&#xff08;底层不封闭&#xff0c;修改宏的参数实现是否编…

chatgpt赋能python:Python动态分配内存:了解它的工作原理

Python动态分配内存&#xff1a;了解它的工作原理 Python是一种高级编程语言&#xff0c;它在处理内存和垃圾回收方面具有独特的方式。在Python中&#xff0c;内存分配和释放是动态的&#xff0c;并且由解释器自动完成。这意味着&#xff0c;Python程序员无需手动管理内存&…

C/C++/Qt 文件操作 效率比较

C/C/Qt 文件操作 & 效率比较 1 介绍2 比较结果2.1 Linux平台上运行程序普遍比Windows上快&#xff1b;Windows下VC编译的程序一般运行比MINGW&#xff08;MINimal Gcc for Windows&#xff09;快2.2 二进制文件的操作要快于文本文件&#xff1b;写文件的操作要快于读文件&a…

chatgpt赋能python:Python剔除函数的使用介绍

Python剔除函数的使用介绍 在Python编程中&#xff0c;剔除函数是非常有用的工具&#xff0c;它可以帮助程序员快速筛选出不符合条件的数据。本文将介绍剔除函数的概念和常见用法&#xff0c;以及如何有效使用剔除函数解决实际问题。 剔除函数的概念 剔除函数是指Python中的…

反射相关知识点

这里写目录标题 反射概述获取Class对象的三种方式总结具体代码演示 获取构造方法以及构造方法里的信息利用Class对象调用对应方法&#xff0c;以及用调取出来的Constructor&#xff08;构造器类&#xff09;创建对象具体代码 获取成员变量利用Class对象调用对应方法&#xff0c…

chatgpt赋能python:Python加速读取CSV文件的方法

Python加速读取CSV文件的方法 介绍 CSV文件是一种常见的数据格式&#xff0c;因为其简单和易于理解&#xff0c;被广泛应用于数据处理和数据分析。然而&#xff0c;在处理大型CSV文件时&#xff0c;读取速度会成为问题。Python作为一种高级编程语言&#xff0c;具有易学易用的…

AI+是企业管理软件的下一站和终点站

作为GPT综合症的表现&#xff0c;准备陆续写一点关于AI的文章。就从这一篇开始吧。 这篇文章原来是在2019年1月份我发在新浪微博和LinkedIn上的。刚搜了一下&#xff0c;全然不见了踪影。原因大家也都知道。但是&#xff0c;我想那个思想的小火花一定还在&#xff0c;在某处酝…

Jenkins概念及安装配置教程(三)

如何配置Jenkins&#xff1f; Jenkins 中的用户管理 要在 Jenkins 中管理用户&#xff0c;您应该导航到管理 Jenkins &#x1f86a; 配置全局安全。理想的选择是让 Jenkins 拥有自己的用户数据库。您可以创建一个只有读取权限的匿名用户。为您打算在下一步中添加的用户创建条…

【ARMv8 SIMD和浮点指令编程】NEON 加法指令——加法都能玩出花

向量加法包括常见的普通加指令&#xff0c;还包括长加、宽加、半加、饱和加、按对加、按对加并累加、选择高半部分结果加、全部元素加等。如果你和我一开始以为的只有一种普通加&#xff0c;那就太小看设计者了&#xff01;同时这么多加法指令的确会提升我们设计程序的效率&…

numpy包中的编码函数和解码函数numpy.char.encode() numpy.char.decode()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 numpy包中的编码函数和解码函数 numpy.char.encode() numpy.char.decode() [太阳]选择题 下列代码最后输出的结果是&#xff1f; import numpy as np x np.array([I, Love, Python]) print(…

Python jieba库

前言 Jieba库是优秀的中文分词第三方库&#xff0c;中文文本需要通过分词获得单个的词语。 Jieba库的分词原理&#xff1a;利用一个中文词库&#xff0c;确定汉字之间的关联概率&#xff0c;汉字间概率大的组成词组&#xff0c;形成分词结果。除了分词&#xff0c;用户还可以…

【数据库原理与应用 - 第八章】数据库的事务管理与并发控制

目录 一、事务管理 1、概念及特性 2、事务控制 &#xff08;1&#xff09;事务控制语句 显示事务举例 二、并发控制 1、问题引入 2、并发执行带来的问题 &#xff08;1&#xff09;丢失修改 &#xff08;2&#xff09;不可重复读 &#xff08;3&#xff09;读"…

[自学记录02|百人计划]纹理压缩

一、什么是纹理压缩 纹理压缩是为了解决内存、带宽问题&#xff0c;专为在计算机图形渲染系统中存储纹理而使用的图像压缩技术。 1.图片格式和纹理格式的区别 (1)图片格式 图片格式是图片文件的存储格式&#xff0c;通常在磁盘、内存中储存和传输文件时使用&#xff1b;例如…

单片机GD32F303RCT6 (Macos环境)开发 (三十三)—— 光照传感器 (BH1750)

GD32 光照传感器 BH1750的使用 1、GPIO模拟i2c配置 使用管脚为SCL PB10 SDA PB11&#xff0c;移植代码时可换自己的管脚。软件模拟i2c在十九章中讲过&#xff0c;与其不同的地方是&#xff0c;这里的us延时函数&#xff0c;换成了定时器3做us级的延时。 tim3的配置&#xf…

linux 找回root密码(CentOS7.6)

linux 找回root密码(CentOS7.6) 首先&#xff0c;启动系统&#xff0c;进入开机界面&#xff0c;在界面中按“e”进入编辑界面。如图 2. 进入编辑界面&#xff0c;使用键盘上的上下键把光标往下移动&#xff0c;找到以““Linux16”开头内容所在的行数”&#xff0c;在行的最后…