当前位置: 首页 > 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;使用过程中的技巧 文章目录 扩展安装失败调试配…...

M5146-C2234E-250BG压力传感器测量误差如何补偿

M5146-C2234E-250BG压力传感器主要有偏移误差、灵敏度误差、线性误差和延迟误差&#xff0c;合理地进行压力传感器的误差补偿是应用的核心。由于这种差异&#xff0c;必须能够最大限度地补偿M5146-C2234E-250BG压力传感器的测量误差。这是确保传感器满足设计和应用要求的重要一…...

Flux.1-Dev深海幻境助力学术研究:为论文生成假设验证过程的可视化图表

Flux.1-Dev深海幻境助力学术研究&#xff1a;为论文生成假设验证过程的可视化图表 1. 引言 写论文最头疼的环节是什么&#xff1f;对很多理工科的研究者来说&#xff0c;可能不是实验&#xff0c;也不是数据分析&#xff0c;而是如何把脑子里那个复杂的理论模型或验证过程&am…...

STM32H7 SPI4与W25Q128 Flash通信实战:50MHz时钟配置避坑指南

STM32H7 SPI4与W25Q128 Flash通信实战&#xff1a;50MHz时钟配置避坑指南 在嵌入式开发中&#xff0c;高速SPI通信一直是工程师们面临的挑战之一。特别是当我们需要在STM32H7系列微控制器上实现50MHz时钟频率的SPI4接口与W25Q128 Flash通信时&#xff0c;各种意想不到的问题往往…...

【JavaScript高级编程】拆解函数流水线 上郴

一、什么是setuptools&#xff1f; setuptools 是一个用于创建、分发和安装 Python 包的核心库。 它可以帮助你&#xff1a; 定义 Python 包的元数据&#xff08;如名称、版本、作者等&#xff09;。 声明包的依赖项&#xff0c;确保你的包能够正确运行。 构建源代码分发包&…...

全球线性可变位移传感器:工业数字化转型与智能制造驱动下的稳增进阶,2025年11.7亿,2032年规模19.25亿,2026-2032年CAGR7.5%

QYResearch调研显示&#xff0c;2025年全球线性可变位移传感器市场规模大约为11.7亿美元&#xff0c;预计2032年将达到19.25亿美元&#xff0c;2026-2032期间年复合增长率&#xff08;CAGR&#xff09;为7.5%。技术创新驱动市场发展制造商正专注于提升LVDT传感器的性能特征&…...

完整Modbus协议栈:pymodbus核心组件详解

完整Modbus协议栈&#xff1a;pymodbus核心组件详解 【免费下载链接】pymodbus A full modbus protocol written in python 项目地址: https://gitcode.com/gh_mirrors/py/pymodbus PyModbus是一个用Python编写的完整Modbus协议实现&#xff0c;提供了客户端、服务器和模…...

2025届毕业生推荐的降重复率助手实际效果

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek AI写作软件&#xff0c;是内容生产领域里的辅助工具&#xff0c;它的核心价值表现在&#xf…...

基于ModelEngine Nexent与RAG技术:构建智能AI心理医生全流程指南

本文将手把手带你使用ModelEngine Nexent框架&#xff0c;基于RAG技术构建一个能提供专业心理支持的AI助手。我们将从环境配置开始&#xff0c;逐步实现知识库构建、智能体编排到最终部署的全流程。 文章目录一、认识ModelEngine二、环境配置三、模型配置3.1 准备API-Key3.2 配…...

2024 CKA备考环境搭建实战 | 从零构建VMware Ubuntu虚拟化平台

1. 为什么选择VMware搭建CKA备考环境 备考CKA认证时&#xff0c;一个稳定、可复现的实验环境至关重要。我在过去三年帮助过上百名学员搭建环境&#xff0c;发现VMware Workstation有三大不可替代的优势&#xff1a; 首先是硬件兼容性。我的旧笔记本只有8GB内存&#xff0c;通过…...

如何解决地理数据可视化难题:geojson2svg的坐标映射与样式控制方案

如何解决地理数据可视化难题&#xff1a;geojson2svg的坐标映射与样式控制方案 【免费下载链接】geojson2svg Converts GeoJSON to SVG string given SVG view port size and maps extent. 项目地址: https://gitcode.com/gh_mirrors/ge/geojson2svg 在Web地图开发中&am…...