【qt小系统】qt对sqlite数据库文件设置访问密码并以绑定QT表格视图的形式实现与数据库交互

在这里插入图片描述

QT对sqlite数据库进行加密读取,并通过QT提供的用于与数据库交互的模型类,操作QT表格,实现高效交互,摒弃掉,查询数据库,跟进字段再创建表格的每个单元格插入表格,直接通过模型类自动绑定进行交互。
文中源码文件【获取方式】:关注公众号:利哥AI实例探险
给公众号发送 “qt表格视图数据库交互” 获取下载方式,免费,无套路,关注即可。公众号上有我手写的各类项目源码,均是免费提供,希望对您有帮助。
注意发送的关键词不能错,否则匹配不到对应资源,由于本人能力有限,难免有疏漏之处。

原文地址:【qt小系统】qt对sqlite数据库文件设置访问密码并以绑定QT表格视图的形式实现与数据库交互示例

系统演示

qt加密sqlite并通过QSqlModel实现数据库操作

在这里插入图片描述

1. qt通过开源库QtCipherSqlitePlugin对sqlite加密

  1. 下载源码并使用QT进行编译,源码github地址:https://github.com/devbean/QtCipherSqlitePlugin
  2. 编译成功后会在QtCipherSqlitePlugin/sqlitecipher/plugins/sqldrivers 目录下生成 sqlitecipher.dll 文件
  3. 将 sqlitecipher.dll 文件,复制到qt安装目录的对应目录下,例如:C:\Qt5152\5.15.2\mingw81_64\plugins\sqldrivers 下
  4. 编写代码,实现对sqlite数据库的加密设置
  5. 使用SQLiteStudio工具,输入密码后可以操作加密后的数据库数据

以下为QtCipherSqlitePlugin编译目录示例:
在这里插入图片描述
以下是我的C:\Qt5152\5.15.2\mingw81_64\plugins\sqldrivers目录示例:
在这里插入图片描述
以下为QT代码对sqlite数据库加密设置示例:

QSqlDatabase m_db = QSqlDatabase(QSqlDatabase::addDatabase("SQLITECIPHER", "ldb"));
m_db.setDatabaseName("sql_cipher.db");
// 加密数据库,如果不存在就创建test.db并用123456作为密码
// 第一个参数可以为空,因为它没有用处,第二个为密码
m_dbOpen = m_db.open("test", "123456");
if (m_dbOpen) {
    m_sqlQuery = QSqlQuery(m_db);
    m_sqlQuery.exec("PRAGMA page_size;");
    if (m_sqlQuery.next()) { qDebug() << "使用的页大小:" << m_sqlQuery.value(0).toInt(); }
    m_sqlQuery.exec("PRAGMA kdf_iter;");
    if (m_sqlQuery.next()) { qDebug() << "KDF迭代次数:" << m_sqlQuery.value(0).toInt(); }
    m_sqlQuery.exec("PRAGMA hmac_algorithm;");
    if (m_sqlQuery.next()) { qDebug() << "HMAC算法:" << m_sqlQuery.value(0).toString(); }
    m_sqlQuery.exec("PRAGMA cipher;"); // Cipher mode: "chacha20"
    if (m_sqlQuery.next()) { qDebug() << "加密模式Cipher mode:" << m_sqlQuery.value(0).toString(); }
    create_db_table();
}

以下是使用SQLiteStudio工具输入密码查看示例:
在这里插入图片描述
在这里插入图片描述

2. 使用QT提供的数据库交互模型操作sqlite

QSqlTableModel与QSqlQueryModel都是Qt提供的用于与数据库交互的模型类,但用途和设计目的有所不同。

  • QSqlTableModel:是一个面向表格(Table-Oriented)的数据模型,主要用于直接操作数据库表。它提供了读写操作的完整支持,允许用户对表中的数据进行插入、更新、删除等操作,并将这些更改自动同步到数据库。
  • QSqlQueryModel:是一个更通用的查询模型(Query-Oriented Model),主要用于执行任意 SQL 查询,并将结果以只读的形式展示给用户。它的特点是灵活性高,但不能直接用于对数据的增删改操作。

2.1 QSqlTableModel的用途

  • 数据的增删改:允许对数据库表中的记录进行增删改操作。
  • 自动提交:支持通过submitAll()提交对表数据的更改,或通过setEditStrategy()设置自动提交策略。
  • 绑定表格视图:适合直接绑定到 QTableView 或其他表格视图进行数据展示,并与数据库实时同步。

2.2 QSqlQueryModel的用途

  • 复杂查询:可以执行任意的 SQL 查询,包括多表联合查询、复杂的过滤条件、排序等。
  • 只读显示:适合用于显示查询结果,但不能直接用于修改数据库。
  • 灵活性:允许通过自定义 SQL 语句来获取数据,因此可以处理更复杂的数据库结构或需求。
    在这里插入图片描述

3. QSqlTableModel实现交互

在这里插入图片描述

3.1 表格初始化

表格初始化,tableview绑定数据库表,设置表头实现数据库字段与表格的对应关系,将不想显示字段隐藏掉。

ui->tableView_student->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView_student->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView_student->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
CustomStyleDelegate *centerDelegate = new CustomStyleDelegate(ui->tableView_student);
ui->tableView_student->setItemDelegate(centerDelegate);
ui->tableView_student->verticalHeader()->setVisible(false); // 隐藏行号
ui->tableView_student->setEditTriggers(QAbstractItemView::NoEditTriggers); // 完全禁用编辑触发器,包括双击、回车等

// 使用QSqlTableModel并与数据库连接
m_student_table_model = new QSqlTableModel(this, m_sql->m_db);
m_student_table_model->setTable("t_student");
m_student_table_model->select(); // 加载数据到tableView显示

ui->tableView_student->setModel(m_student_table_model);

m_student_table_model->setHeaderData(0, Qt::Horizontal, "数据库唯一标识Id");
m_student_table_model->setHeaderData(1, Qt::Horizontal, "学号");
m_student_table_model->setHeaderData(2, Qt::Horizontal, "学生姓名");
m_student_table_model->setHeaderData(3, Qt::Horizontal, "学生年龄");
m_student_table_model->setHeaderData(4, Qt::Horizontal, "教师ID");

ui->tableView_student->setColumnHidden(0, true);
ui->tableView_student->setColumnHidden(4, true);

// 允许输入范围 0-100
QIntValidator *validator = new QIntValidator(0, 100, ui->lineEdit_student_age);
ui->lineEdit_student_age->setValidator(validator);

3.2 数据添加

数据添加,关联table后,自动关联数据库的增加

QString sno = ui->lineEdit_student_sno->text();
QString name = ui->lineEdit_student_name->text();
int age = ui->lineEdit_student_age->text().toInt();

QSqlRecord record = m_student_table_model->record();
record.setValue("sno", sno);
record.setValue("name", name);
record.setValue("age", age);
m_student_table_model->insertRecord(-1, record); // 插入数据, -1表示在表末尾插入新纪录
m_student_table_model->submitAll(); // 提交更改

m_student_table_model->select();

3.3 数据修改

数据修改,关联model后,根据table的行号,自动关联表格及数据库的修改

QString sno = ui->lineEdit_student_sno->text();
QString name = ui->lineEdit_student_name->text();
int age = ui->lineEdit_student_age->text().toInt();
QSqlRecord record = m_student_table_model->record(m_stu_tableView_current_row);
record.setValue("sno", sno);
record.setValue("name", name);
record.setValue("age", age);
m_student_table_model->setRecord(m_stu_tableView_current_row, record);
if (!m_student_table_model->submitAll()) {
    qDebug() << "Failed to update record:" << m_student_table_model->lastError().text();
    return;
}
m_student_table_model->select();

3.4 数据删除

数据删除,关联model后,根据table的行号,自动关联表格及数据库的删除

if (!m_student_table_model->removeRow(m_stu_tableView_current_row)) {
    return;
}
m_student_table_model->submitAll();
m_student_table_model->select();

4. QSqlQueryModel实现交互

4.1 表格初始化

tableview绑定数据库表,设置表头实现数据库字段与表格的对应关系,将不想显示字段隐藏掉。

ui->tableView_teacher->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView_teacher->setSelectionBehavior(QAbstractItemView::SelectRows);
// 设置列可以自由伸缩并填满整个 QTableView
ui->tableView_teacher->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
// 设置每个单元格内容水平垂直居中对齐, 去掉Focus
CustomStyleDelegate *centerDelegate = new CustomStyleDelegate(ui->tableView_teacher);
ui->tableView_teacher->setItemDelegate(centerDelegate);
ui->tableView_teacher->verticalHeader()->setVisible(false);// 隐藏行号
ui->tableView_teacher->setEditTriggers(QAbstractItemView::NoEditTriggers);// 完全禁用编辑触发器,包括双击、回车等

// 创建视图,并将模型设置到视图中
ui->tableView_teacher->setModel(&m_teacher_query_model);

// 查询并刷新QTableView
m_teacher_query_model.setQuery("select * from t_teacher", m_sql->m_db);
// 使用setHeaderData()方法为表格的每一列设置自定义标题
m_teacher_query_model.setHeaderData(0, Qt::Horizontal, "数据库唯一标识Id");
m_teacher_query_model.setHeaderData(1, Qt::Horizontal, "工号");
m_teacher_query_model.setHeaderData(2, Qt::Horizontal, "教师姓名");
m_teacher_query_model.setHeaderData(3, Qt::Horizontal, "教师年龄");
m_teacher_query_model.setHeaderData(4, Qt::Horizontal, "职位");
// 隐藏不需要显示的列
ui->tableView_teacher->setColumnHidden(0, true);

4.2 数据添加

QString wkno = ui->lineEdit_teacher_sno->text();
QString name = ui->lineEdit_teacher_name->text();
int age = ui->lineEdit_teacher_age->text().toInt();
QString job = ui->lineEdit_teacher_job->text();
QSqlQuery query(m_sql->m_db);
query.prepare(QString(R"(
                insert into %1 (wkno, name, age, JobTitle)
                    values (:wkno, :tea_name, :tea_age, :JobTitle)
                )").arg("t_teacher"));
query.bindValue(":wkno", wkno);
query.bindValue(":tea_name", name);
query.bindValue(":tea_age", age);
query.bindValue(":JobTitle", job);
if (!query.exec()) {
    qDebug() << "error=" << query.lastError().text();
    return;
}
m_teacher_query_model.setQuery("select * from t_teacher", m_sql->m_db);

4.3 数据修改

int id = ui->label_teacher_id->text().toInt();
QString wkno = ui->lineEdit_teacher_sno->text();
QString name = ui->lineEdit_teacher_name->text();
int age = ui->lineEdit_teacher_age->text().toInt();
QString job = ui->lineEdit_teacher_job->text();
QSqlQuery query(m_sql->m_db);
query.prepare("update t_teacher set wkno = :wkno, name = :tea_name, "
              "age = :tea_age, JobTitle = :JobTitle "
              "where id=:id");
query.bindValue(":id", id);
query.bindValue(":wkno", wkno);
query.bindValue(":tea_name", name);
query.bindValue(":tea_age", age);
query.bindValue(":JobTitle", job);
if (!query.exec()) {
    qDebug() << "error=" << query.lastError().text();
    return;
}
m_teacher_query_model.setQuery("select * from t_teacher", m_sql->m_db);

4.4 数据删除


int id = ui->label_teacher_id->text().toInt();
QSqlQuery query(m_sql->m_db);
query.prepare("delete from t_teacher where id=:id");
query.bindValue(":id", id);
if (!query.exec()) {
    qDebug() << "error=" << query.lastError().text();
    return;
}
m_teacher_query_model.setQuery("select * from t_teacher", m_sql->m_db);

5. 使用QSqlQueryModel联合查询及自定义表头

ui->tableView_tea_stu->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView_tea_stu->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView_tea_stu->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
CustomStyleDelegate *centerDelegate = new CustomStyleDelegate(ui->tableView_tea_stu);
ui->tableView_tea_stu->setItemDelegate(centerDelegate);
ui->tableView_tea_stu->verticalHeader()->setVisible(false);
ui->tableView_tea_stu->setEditTriggers(QAbstractItemView::NoEditTriggers);

// 设置查询模型
m_tea_stu_table_model = new QSqlQueryModel();
ui->tableView_tea_stu->setModel(m_tea_stu_table_model);

m_tea_stu_table_model->setQuery(R"(
    SELECT
        tea.wkno,
        tea.name,
        tea.age,
        tea.JobTitle,
        stu.name
    FROM
        t_teacher tea
    JOIN
        t_student stu
    ON
        tea.wkno = stu.teacherId
)", m_sql->m_db);

m_tea_stu_table_model->setHeaderData(0, Qt::Horizontal, "教师工号");
m_tea_stu_table_model->setHeaderData(1, Qt::Horizontal, "教师姓名");
m_tea_stu_table_model->setHeaderData(2, Qt::Horizontal, "教师年龄");
m_tea_stu_table_model->setHeaderData(3, Qt::Horizontal, "职称");
m_tea_stu_table_model->setHeaderData(4, Qt::Horizontal, "教授的学生姓名");

结束语

由于本人能力有限,难免有疏漏之处!

文中源码文件【获取方式】:关注公众号:利哥AI实例探险

给公众号发送 “qt表格视图数据库交互” 获取下载方式,免费,无套路,关注即可!!!

往期文章回顾

【深度学习】物体检测/实例分割/物体追踪/姿态估计/定向边框/图像分类检测演示系统【含源码】【深度学习】YOLOV8数据标注及模型训练方法整体流程介绍及演示
【深度学习】行人跌倒行为检测软件系统【深度学习】火灾检测软件系统
【深度学习】吸烟行为检测软件系统【深度学习】数竹签演示软件系统
【深度学习】菜品目标检测软件系统QT5集成FTP实现文件及文件夹的下载
QT集成开源日志库示例python源码加密之Cython方案简单示例
【python源码加密】Cython针对python工程多层级目录处理办法http服务网络请求如何确保数据安全(含python示例源码)
http请求数据传输时确保完整性和保密性方案(含源码)QT集成百度在线地图JS API实现交互及特定效果
【qt小游戏】小老鼠闯迷宫小游戏(附源码)【qt小系统】传感器云平台3D散点图(附源码)
【qt小系统】通过qt折线图实现论文内容-快餐店排队效能分析【qt小系统】使用qt实现透明的3D魔方效果
【qt小系统】qt对sqlite数据库文件设置访问密码并以绑定QT表格视图的形式实现与数据库交互示例

结束语

由于本人能力有限,难免有疏漏之处!
文中源码文件【获取方式】:关注公众号:利哥AI实例探险
给公众号发送 qt表格视图数据库交互 获取下载方式,免费,无套路,关注即可!!!

原文地址:【qt小系统】qt对sqlite数据库文件设置访问密码并以绑定QT表格视图的形式实现与数据库交互示例

这是我工作了一天的成果,压缩包内包括Qt sqlite加密驱动所有的代码,以及一个调用例程,还有一个sqlite3shell.exe工具,用于加密数据库命令行下的分析。 使用这个加密驱动很简单,只需以下3步: 1. 将驱动的代码复制到你的app文件夹(共2个文件夹) 2. 在app的pro文件中加入 include(wxsqlite3/wxsqlite3.pri) include(zsqlitecipherdriver/zsqlitecipherdriver.pri) 3. 在需要的地方加入#include "zsqlitecipherdriver.h",这样就可以使用ZSQLiteCipherDriver类了,这个类是继承自QSqlDriver。所以可以传递给 QSqlDatabase::addDatabase。 详细的可以查看压缩包内源码。之后,main函数就可以这么使用sqlite的加密驱动: ZSQLiteCipherDriver *driver = new ZSQLiteCipherDriver(); QSqlDatabase db = QSqlDatabase::addDatabase(driver); db.setDatabaseName("test.db"); db.setPassword("123"); db.open(); ... 加密驱动的稳定性没有问题,是我从Qt的开源代码中,找到Sqlite没加密的驱动部分,然后修改的。修改的内容不多,最重要的是在数据库的open时,加入了sqlite3_key的调用,实现加密。 底层的加密实现,是来自wxsqlite3-3.0.6。这个我修改了一个宏定义,让其加密方式采用了AES256,而不是原来的AES128。 例程中包括了3个实用的函数,分别用来以某一密码打开或创建一个数据库,判断数据库是否处于解密状态,以及修改数据库密码sqlite3shell.exe跟官方提供的sqlite3.exe使用方法一样。只不过对于加密数据库,需要在对数据库进行任何操作前,先执行“PRAGMA key=xxx;”。通过这种方式输入数据库密码。检验之前的密码是否正确可以在命令行中键入“.databases”,如果没有错误提示,那就是解密成功了;如果密码错误,只能关闭sqlite3shell.exe,从头尝试了。 虽然这个资源,要的分数确实有点多,不过评价之后就能返还的。我相信这个资源值这个价值!下载后在Qt5上可以直接编译。不需要任何修改。Qt4上没试过,不承诺一定可用,但是应该没问题。
在使用Qt的TableView显示数据库数据时,需要使用Model-View架构来实现。具体步骤如下: 1.创建数据库连接 需要使用Qt自带的QSqlDatabase类来创建数据库连接,并且需要指定数据库类型、主机地址、数据库名、用户名和密码等信息。 2.创建数据模型 使用Qt自带的QSqlTableModel类来创建数据模型,并且需要指定数据表名和数据库连接等信息。 3.设置TableView 使用Qt自带的QTableView类来显示数据,并且需要设置数据模型、列宽、列标题等信息。 4.使用委托 使用Qt自带的QItemDelegate类来创建委托,并且需要重写委托的paint()和createEditor()等函数来实现自定义的数据显示和编辑功能。 5.保存数据 在数据发生变化时,需要使用数据模型的submitAll()函数来保存数据到数据库中。 完整代码如下: ``` #include <QtWidgets> #include <QtSql> class MyDelegate : public QItemDelegate { public: MyDelegate(QObject *parent = nullptr): QItemDelegate(parent) {} void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override { // 自定义绘制函数,显示数据时添加单位 QString text = index.data().toString() + " kg"; drawDisplay(painter, option, option.rect, text); } QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override { // 自定义编辑函数,编辑时去掉单位 QLineEdit *editor = new QLineEdit(parent); QString text = index.data().toString(); editor->setText(text.left(text.indexOf(" "))); return editor; } void setEditorData(QWidget *editor, const QModelIndex &index) const override { QString text = index.data().toString(); QLineEdit *lineEdit = static_cast<QLineEdit*>(editor); lineEdit->setText(text.left(text.indexOf(" "))); } void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override { QLineEdit *lineEdit = static_cast<QLineEdit*>(editor); QString text = lineEdit->text() + " kg"; model->setData(index, text, Qt::EditRole); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); // 创建数据库连接 QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("test.db"); if (!db.open()) { qDebug() << "Failed to connect to database!"; return -1; } // 创建数据模型 QSqlTableModel model; model.setTable("weight"); model.select(); // 设置TableView QTableView tableView; tableView.setModel(&model); tableView.setItemDelegate(new MyDelegate); tableView.setColumnWidth(0, 150); tableView.setColumnWidth(1, 100); tableView.setHorizontalHeaderLabels(QStringList() << "Name" << "Weight"); // 保存数据 QPushButton saveButton("Save"); QObject::connect(&saveButton, &QPushButton::clicked, [&model]() { model.submitAll(); }); // 显示窗口 QVBoxLayout layout; layout.addWidget(&tableView); layout.addWidget(&saveButton); QWidget window; window.setLayout(&layout); window.show(); return app.exec(); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

利哥AI实例探险

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值