当前位置: 首页 > news >正文

QT 使用QSqlTableModel对数据库进行创建,插入,显示

文章目录

      • 效果图
      • 概述
      • 功能点
      • 代码分析
        • 初始数据
        • 插入数据
        • 数据显示
      • 总结

效果图

请添加图片描述

概述

  • 本案例用于对数据库中的数据进行显示等其他操作,其他表格筛选,过滤等功能可看此博客

  • 框架:数据模型使用QSqlTableModel,视图使用QTableView,表格的一些字体或者控件之类的使用QStyledItemDelegate实现。
    导航栏的变化实时的传回给表格,所有的数据库表都实现继承一个表格类,根据表格本身的特性可以设置自己的委托。数据库使用一个单列类进行管理,包括数据库的读取 ,创建,数据插入,以及对模型的映射等。

  • 使用的数据库类型为QPSQL

功能点

  1. 初始化数据
  2. 插入数据
  3. 数据显示

代码分析

初始数据
  • 初始化数据库及表
    void LogManagement::initDB()
    {dataPtr->db = QSqlDatabase::addDatabase("QPSQL", "dabao_pouring__db_connection");dataPtr->db.setHostName("localhost");dataPtr->db.setDatabaseName("dabao_pouring_db");dataPtr->db.setUserName("postgres");dataPtr->db.setPassword("dj");if (!dataPtr->db.open()){qCritical() << "无法打开数据库:" << dataPtr->db.lastError().text();return;}initOperationLog();initErrorLog();
    }void LogManagement::initOperationLog()
    {QScopedPointer<QSqlQuery> query(new QSqlQuery(dataPtr->db));if (!query->exec("SELECT 1 FROM operationlog LIMIT 1")){QString createTableQuery = R"(CREATE TABLE IF NOT EXISTS operationlog (id SERIAL PRIMARY KEY,time TIMESTAMP NOT NULL,result VARCHAR(10) NOT NULL,content TEXT NOT NULL,error TEXT  NULL,operation VARCHAR(10) NULL))";if (!query->exec(createTableQuery)){qCritical() << "创建表失败:" << query->lastError().text();return;}}dataPtr->operationLogModel = new QSqlTableModel(this, dataPtr->db);dataPtr->operationLogModel->setTable("operationlog");                        // 设置要操作的表名dataPtr->operationLogModel->setEditStrategy(QSqlTableModel::OnManualSubmit); // 设置编辑策略if (!(dataPtr->operationLogModel->select()))                                 // 查询数据{qCritical() << "打开数据表失败:" << dataPtr->operationLogModel->lastError().text();return;}dataPtr->operationLogModel->setHeaderData(dataPtr->operationLogModel->fieldIndex("time"), Qt::Horizontal, "时间");dataPtr->operationLogModel->setHeaderData(dataPtr->operationLogModel->fieldIndex("result"), Qt::Horizontal, "操作情况");dataPtr->operationLogModel->setHeaderData(dataPtr->operationLogModel->fieldIndex("content"), Qt::Horizontal, "操作内容");dataPtr->operationLogModel->setHeaderData(dataPtr->operationLogModel->fieldIndex("error"), Qt::Horizontal, "异常");dataPtr->operationLogModel->setHeaderData(dataPtr->operationLogModel->fieldIndex("operation"), Qt::Horizontal, "操作");
    }
    
插入数据

void LogManagement::appendErrorLogData(const QString &time, const QString &type, const QString &content)
{if (!dataPtr->errorLogModel)return;int newRow = dataPtr->errorLogModel->rowCount();      // 获取当前行数,这将是新行的索引bool res = dataPtr->errorLogModel->insertRow(newRow); // 插入新行if (!res){qCritical() << "无法添加新记录";return;}// 设置新记录的值res = dataPtr->errorLogModel->setData(dataPtr->errorLogModel->index(newRow, dataPtr->errorLogModel->fieldIndex("type")), type);if (!res){return;}res = dataPtr->errorLogModel->setData(dataPtr->errorLogModel->index(newRow, dataPtr->errorLogModel->fieldIndex("time")), QDateTime::fromString(time, "yyyy-MM-dd hh:mm:ss"));if (!res){return;}res = dataPtr->errorLogModel->setData(dataPtr->errorLogModel->index(newRow, dataPtr->errorLogModel->fieldIndex("content")), content);if (!res){return;}// 提交新记录res = dataPtr->errorLogModel->submitAll();if (!res){qCritical() << "保存记录失败: " << dataPtr->errorLogModel->lastError().text();dataPtr->errorLogModel->revertAll(); // 如果提交失败,回滚所有更改}
}
数据显示
  • 使用的是model-view的设计模式,对于一些特殊的数据显示,比较字体颜色,或者加入删除按钮之类,由于数据都来源于model,所以设置操作按钮之类的并不好直接实现,我想到的一个办法就是,在数据库表的最后一列插入一个空列,用于放置操作按钮,比如删除。
    void GeneralDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
    {QStyledItemDelegate::initStyleOption(option, index);QVariant data = index.model()->data(index, Qt::EditRole);if (data.type() == QVariant::DateTime){QDateTime dateTime = data.toDateTime();option->displayAlignment = Qt::AlignCenter;option->text = dateTime.toString("yyyy-MM-dd hh:mm:ss");}else if (data.type() == QVariant::Int){option->displayAlignment = Qt::AlignRight;option->text = QString::number(data.toInt());}else{option->displayAlignment = Qt::AlignLeft;option->text = data.toString();}
    }void GeneralDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {int currentColumn = index.column();int columnCount = index.model()->columnCount();// 判断是否为最后一列bool isLastColumn = (currentColumn == columnCount - 1);if (isLastColumn){QRect buttonRect = option.rect.adjusted(2, 2, -2, -2); // 调整按钮位置和大小QStyleOptionButton buttonOption;buttonOption.rect = buttonRect;buttonOption.state |= QStyle::State_Enabled;buttonOption.state |= QStyle::State_MouseOver;buttonOption.palette.setBrush(QPalette::Button, QColor(Qt::red));buttonOption.text = "删除";painter->save();painter->setClipRect(buttonRect);QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);painter->restore();}else{QStyleOptionViewItem options = option;initStyleOption(&options, index);options.displayAlignment = Qt::AlignCenter; // 居中QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &options, painter);}
    }bool GeneralDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
    {int currentColumn = index.column();int columnCount = index.model()->columnCount();// 判断是否为最后一列bool isLastColumn = (currentColumn == columnCount - 1);if (event->type() == QEvent::MouseButtonRelease && isLastColumn){QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);QRect buttonRect = option.rect.adjusted(2, 2, -2, -2);if (buttonRect.contains(mouseEvent->pos())){// 触发删除操作emit deleteRequested(index);return true;}}return QStyledItemDelegate::editorEvent(event, model, option, index);
    }
    

总结

  • 知识理应共享,源码在此

相关文章:

QT 使用QSqlTableModel对数据库进行创建,插入,显示

文章目录 效果图概述功能点代码分析初始数据插入数据数据显示 总结 效果图 概述 本案例用于对数据库中的数据进行显示等其他操作&#xff0c;其他表格筛选&#xff0c;过滤等功能可看此博客 框架&#xff1a;数据模型使用QSqlTableModel&#xff0c;视图使用QTableView&#x…...

如何学习Transformer架构

Transformer架构自提出以来&#xff0c;在自然语言处理领域引发了革命性的变化。作为一种基于注意力机制的模型&#xff0c;Transformer解决了传统序列模型在并行化和长距离依赖方面的局限性。本文将探讨Transformer论文《Attention is All You Need》与Hugging Face Transform…...

浅谈云计算22 | Kubernetes容器编排引擎

Kubernetes容器编排引擎 一、Kubernetes管理对象1.1 Kubernetes组件和架构1.2 主要管理对象类型 二、Kubernetes 服务2.1 服务的作用与原理2.2 服务类型 三、Kubernetes网络管理3.1 网络模型与目标3.2 网络组件3.2.1 kube-proxy3.2.2 网络插件 3.3 网络通信流程 四、Kubernetes…...

计算 SAMOut V3 在将词汇表从1万 增加到6千万的情况下能够减少多少参数

当我们将词汇表从 60,000,000&#xff08;六千万&#xff09;减少到 10,000 时&#xff0c;实际上是在缩小模型的词嵌入层及其共享的语言模型头&#xff08;LM Head&#xff09;的规模。这将导致参数量显著减少。我们可以通过以下步骤来计算具体的参数减少量。 参数量减少计算…...

03.选择排序

一、题目思路 选择排序是一种简单直观的排序算法。它的工作原理是&#xff1a;首先在未排序序列中找到最小&#xff08;或最大&#xff09;元素&#xff0c;存放到排序序列的起始位置&#xff0c;然后&#xff0c;再从剩余未排序元素中继续寻找最小&#xff08;或最大&#xff…...

02_登录窗口

新建场景 重命名为GameRoot 双击GameRoot进入新场景 同样摄像机清除格式 删除平行光并关闭渲染灯光的天空盒 新建空节点重命名为GameRoot GameRoot为游戏的根节点 在整个游戏中都不会被删除 在游戏的根节点下创建UI的根节点Canvas 创建一个空节点 作为UI根节点下的 登录场景UI…...

NodeJS | 搭建本地/公网服务器 live-server 的使用与安装

目录 介绍 安装 live-server 安装方法 安装后的验证 环境变量问题 Node.js 环境变量未配置正确 全局安装的 live-server 路径未添加到环境变量 运行测试 默认访问主界面 访问文件 报错信息与解决 问题一&#xff1a;未知命令 问题二&#xff1a;拒绝脚本 公网配置…...

SystemUI 实现音量条同步功能

需求&#xff1a;SystemUI 实现音量条同步功能 具体问题 以前在SystemUI 下拉框添加了音量条控制&#xff0c;目前发现在SystemUI下拉框显示状态的情况下&#xff0c; 按键或者底部虚拟导航点击音量加减时候&#xff0c;SystemUI音量条不更新。 如下图&#xff1a;两个Syste…...

嵌入式知识点总结 C/C++ 专题提升(一)-关键字

针对于嵌入式软件杂乱的知识点总结起来&#xff0c;提供给读者学习复习对下述内容的强化。 目录 1.C语言宏中"#“和"##"的用法 1.1.(#)字符串化操作符 1.2.(##)符号连接操作符 2.关键字volatile有什么含意?并举出三个不同的例子? 2.1.并行设备的硬件寄存…...

基础入门-传输加密数据格式编码算法密文存储代码混淆逆向保护安全影响

知识点&#xff1a; 1、传输格式&传输数据-类型&编码&算法 2、密码存储&代码混淆-不可逆&非对称性 一、演示案例-传输格式&传输数据-类型&编码&算法 传输格式 JSON XML WebSockets HTML 二进制 自定义 WebSockets&#xff1a;聊天交互较常…...

几个Linux系统安装体验(续): 统信桌面系统

本文介绍统信桌面系统&#xff08;uos&#xff09;的安装。 下载 下载地址&#xff1a; https://www.chinauos.com/resource/download-professional 下载文件&#xff1a;本文下载文件名称为uos-desktop-20-professional-1070-amd64.iso。 下载注意事项&#xff1a;可直接下…...

算法日记6.StarryCoding P52:我们都需要0(异或)

一、题目 二、题解&#xff1a; 1、对于这道题&#xff0c;题意为让我们寻找一个数x使得 b[i]a[i]^x&#xff0c; 并且b[1]^b[2]^b[3]^ b[4]^b[5]....0 2、我们把b[i]给拆开&#xff0c;可以得到 3、又因为^满足结合律&#xff0c;因此&#xff0c;可以把括号给拆开 4、接着…...

【网络协议】RFC3164-The BSD syslog Protocol

引言 Syslog常被称为系统日志或系统记录&#xff0c;是一种标准化的协议&#xff0c;用于网络设备、服务器和应用程序向中央Syslog服务器发送日志消息。互联网工程任务组&#xff08;IETF&#xff09;发布的RFC 3164&#xff0c;专门定义了BSD Syslog协议的规范和实现方式。通…...

SpringCloud -根据服务名获取服务运行实例并进行负载均衡

Nacos注册中心 每个服务启动之后都要向注册中心发送服务注册请求&#xff0c;注册中心可以和各个注册客户端自定义协议实现服务注册和发现。 pom.xml <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-na…...

CentOS 安装Redis

1. 安装 Redis 安装 EPEL 仓库&#xff08;对于 CentOS/RHEL 系统&#xff09;&#xff1a; 首先安装 EPEL 仓库&#xff0c;因为 Redis 存在于 EPEL 仓库中&#xff1a; yum install epel-release安装 Redis 数据库&#xff1a; yum install redis2. 修改 Redis 配置文件 …...

Linux网络 TCP socket

TCP简介 TCP&#xff08;Transmission Control Protocol&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议。它位于OSI模型的第四层&#xff0c;主要为应用层提供数据传输服务。TCP通过三次握手建立连接&#xff0c;确保数据在发送和接收过程中的准确性和顺序…...

(一)相机标定——四大坐标系的介绍、对应转换、畸变原理以及OpenCV完整代码实战(C++版)

一、四大坐标系介绍 1&#xff0c;世界坐标系 从这个世界&#xff08;world&#xff09;的视角来看物体 世界坐标系是3D空间坐标&#xff0c;每个点的位置用 ( X w , Y w , Z w ) (X_w,Y_w,Z_w) (Xw​,Yw​,Zw​)表示 2&#xff0c;相机坐标系 相机本身具有一个坐标系&…...

【Linux网络编程】高效I/O--I/O的五种类型

目录 I/O的概念 网络通信的本质 I/O的本质 高效I/O 五种I/O模型 阻塞I/O 非阻塞I/O 信号驱动I/O 多路转接/多路复用I/O 异步I/O 非阻塞I/O的实现 I/O的概念 网络通信的本质 网络通信的本质其实就是I/O I&#xff1a;表示input(输入)O&#xff1a;表示ou…...

企业级NoSQL数据库Redis

1.浏览器缓存过期机制 1.1 最后修改时间 last-modified 浏览器缓存机制是优化网页加载速度和减少服务器负载的重要手段。以下是关于浏览器缓存过期机制、Last-Modified 和 ETag 的详细讲解&#xff1a; 一、Last-Modified 头部 定义&#xff1a;Last-Modified 表示服务器上资源…...

Vscode:问题解决办法 及 Tips 总结

Visual Studio Code&#xff08;简称VSCode&#xff09;是一个功能强大的开源代码编辑器&#xff0c;广泛用于各种编程语言和开发场景&#xff0c;本博客主要记录在使用 VSCode 进行verilog开发时遇到的问题及解决办法&#xff0c;使用过程中的技巧 文章目录 扩展安装失败调试配…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型

在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重&#xff0c;适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解&#xff0c;并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...

AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)

Name&#xff1a;3ddown Serial&#xff1a;FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名&#xff1a;Axure 序列号&#xff1a;8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...

goreplay

1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具&#xff0c;可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长&#xff0c;测试它所需的工作量也会呈指数级增长。GoRepl…...

OpenGL-什么是软OpenGL/软渲染/软光栅?

‌软OpenGL&#xff08;Software OpenGL&#xff09;‌或者软渲染指完全通过CPU模拟实现的OpenGL渲染方式&#xff08;包括几何处理、光栅化、着色等&#xff09;&#xff0c;不依赖GPU硬件加速。这种模式通常性能较低&#xff0c;但兼容性极强&#xff0c;常用于不支持硬件加速…...