QSqlTableModel操作数据库单表使用总结

本文记录使用QSqlTableModel等组件实现单表的数据库操作。

QSqlTableModel是一个模型类,它的实例可以作为一个数据表的模型。使用QSqlTableModel模型和QTableView组件构成模型/视图结构,就可以实现数据表的数据显示和编辑。

目录

所需的类及定义

表格控件设置QTableView

打开数据库连接db.open()

表设置初始化、表查询

设置表名

设置表排序字段

打开表-查询

显示行数

设置表格的水平字段标题

创建选择模型

绑定数据模型 和 选择模型

绑定之后,将图片列和备注列在表格中不显示

绑定自定义下拉框到部门列、性别列

创建界面组件与数据模型字段之间的数据映射

定义数据映射组件

设置界面组件和模型字段之间的映射

移动到首记录,将首行的记录赋值给绑定的控件

表插入

表追加一行

表操作撤销

表操作提交

表记录删除

表排序切换

表条件过滤及过滤条件清空

逐行修改数据并提交

BLOB字段的保存、清空、显示图片

表事件处理

单元格值发生变化处理事件

焦点行发生变换

表其他操作

获取水平列名


所需的类及定义

解释
数据库连接QSqlDatabase
显示控件QTableView
Model视图QSqlTableModel
选择ModelQItemSelectionModel
字段编辑绑定QDataWidgetMapper
自定义combox代理控件TComboBoxDelegate
性别字符列表genderList
部门字符列表deptList
省份字符列表provinceList
    QSqlDatabase DB;QSqlTableModel *tabModel;QItemSelectionModel *selModel;QDataWidgetMapper *dataMapper;//数据映射TComboBoxDelegate delegateSex;TComboBoxDelegate delegateDept;QStringList genderList;QStringList deptList;QStringList provinceList;

表格控件设置QTableView

行背景交替颜色、单个单元格选择模式

    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);ui->tableView->setAlternatingRowColors(true);

打开数据库连接db.open()

打开SQLite数据库

bool SqlTableModelExample::openDataBase(QString aFile)
{DB = QSqlDatabase::addDatabase("QSQLITE");//添加SQLite驱动DB.setDatabaseName(aFile);//设置数据库名称if(!DB.open())//打开数据库{QMessageBox::warning(this, "错误", "打开数据库失败");return false;}else{openTable();return true;}
}

表设置初始化、表查询

设置表名

tabModel = new QSqlTableModel(this,DB);
tabModel->setTable("employee");

设置表排序字段

tabModel->setSort(tabModel->fieldIndex("empNo"),Qt::AscendingOrder);

打开表-查询

if(!tabModel->select()){//MessageBoxHelper::critical(this,"打开数据表错误,错误信息:\n"+tabModel->lastError().text());QMessageBox::critical(this,"错误信息","打开数据表错误,错误信息:\n"+tabModel->lastError().text());return;}

显示行数

void SqlTableModelExample::showRecordCount()
{ui->statusbar->showMessage(QString("记录条数:%1").arg(tabModel->rowCount()));
}

设置表格的水平字段标题

tabModel->setHeaderData(tabModel->fieldIndex("empNo"),Qt::Horizontal,"工号");tabModel->setHeaderData(tabModel->fieldIndex("Name"),Qt::Horizontal,"姓名");tabModel->setHeaderData(tabModel->fieldIndex("Gender"),Qt::Horizontal,"性别");tabModel->setHeaderData(tabModel->fieldIndex("Birthday"),Qt::Horizontal,"出生日期");tabModel->setHeaderData(tabModel->fieldIndex("Province"),Qt::Horizontal,"省份");tabModel->setHeaderData(tabModel->fieldIndex("Department"),Qt::Horizontal,"部门");tabModel->setHeaderData(tabModel->fieldIndex("Salary"),Qt::Horizontal,"薪水");//不在列表tabView中显示tabModel->setHeaderData(tabModel->fieldIndex("Memo"),Qt::Horizontal,"备注");tabModel->setHeaderData(tabModel->fieldIndex("Photo"),Qt::Horizontal,"照片");

创建选择模型

selModel = new QItemSelectionModel(tabModel,this);

将选择模型的单元格值变化事件、行变化/切换 绑定到处理方法

如单元格值发生变化,将保存、撤销操作按钮变亮;行切换时,绑定的显示控件显示对应行的值

    connect(selModel,&QItemSelectionModel::currentChanged,this,&SqlTableModelExample::do_currentChanged);connect(selModel,&QItemSelectionModel::currentRowChanged,this,&SqlTableModelExample::do_currentRowChanged);

绑定数据模型 和 选择模型

    ui->tableView->setModel(tabModel);ui->tableView->setSelectionModel(selModel);

绑定之后,将图片列和备注列在表格中不显示

    ui->tableView->setColumnHidden(tabModel->fieldIndex("Memo"),true);ui->tableView->setColumnHidden(tabModel->fieldIndex("Photo"),true);

绑定自定义下拉框到部门列、性别列

 bool isEditable = false;delegateSex.setItems(genderList,isEditable);ui->tableView->setItemDelegateForColumn(tabModel->fieldIndex("Gender"),&delegateSex);isEditable = true;delegateDept.setItems(deptList,isEditable);ui->tableView->setItemDelegateForColumn(tabModel->fieldIndex("Department"),&delegateDept);

创建界面组件与数据模型字段之间的数据映射

定义数据映射组件

    dataMapper = new QDataWidgetMapper(this);dataMapper->setModel(tabModel);dataMapper->setModel(tabModel);   dataMapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit); //自动提交

设置界面组件和模型字段之间的映射

    dataMapper->addMapping(ui->dbSpinEmpNo,tabModel->fieldIndex("empNo"));dataMapper->addMapping(ui->dbEditName,tabModel->fieldIndex("Name"));dataMapper->addMapping(ui->dbComboSex,tabModel->fieldIndex("Gender"));dataMapper->addMapping(ui->dbEditBirth,tabModel->fieldIndex("Birthday"));dataMapper->addMapping(ui->dbComboProvince,tabModel->fieldIndex("Province"));dataMapper->addMapping(ui->dbComboDept,tabModel->fieldIndex("Department"));dataMapper->addMapping(ui->dbSpinSalary,tabModel->fieldIndex("Salary"));dataMapper->addMapping(ui->dbEditMemo,tabModel->fieldIndex("Memo"));

移动到首记录,将首行的记录赋值给绑定的控件

dataMapper->toFirst();

表插入

void SqlTableModelExample::on_actRecInsert_triggered()
{QModelIndex curIndex = ui->tableView->currentIndex();QSqlRecord rec = tabModel->record();//获取一个空记录,只有字段定义tabModel->insertRecord(curIndex.row(),rec);selModel->clearSelection();selModel->setCurrentIndex(curIndex,QItemSelectionModel::Select);showRecordCount();
}

表追加一行

void SqlTableModelExample::on_actRecAppend_triggered()
{QSqlRecord rec = tabModel->record();//获取一个空记录rec.setValue(tabModel->fieldIndex("empNo"),2000+tabModel->rowCount());rec.setValue(tabModel->fieldIndex("Gender"),"男");tabModel->insertRecord(tabModel->rowCount(),rec);//插入到数据模型的最后selModel->clearSelection();QModelIndex curIndex = tabModel->index(tabModel->rowCount()-1,1);selModel->setCurrentIndex(curIndex,QItemSelectionModel::Select);showRecordCount();
}

表操作撤销

void SqlTableModelExample::on_actRevert_triggered()
{tabModel->revertAll();ui->actSubmit->setEnabled(false);ui->actRevert->setEnabled(false);showRecordCount();
}

表操作提交

void SqlTableModelExample::on_actSubmit_triggered()
{bool res = tabModel->submitAll();if(!res){QMessageBox::critical(this,"错误提示","数据保存错误,错误信息:"+tabModel->lastError().text());return;}else{ui->actSubmit->setEnabled(false);ui->actRevert->setEnabled(false);}showRecordCount();
}

表记录删除

void SqlTableModelExample::on_actRecDelete_triggered()
{QModelIndex curIndex = selModel->currentIndex();tabModel->removeRow(curIndex.row());showRecordCount();
}

表排序切换

void SqlTableModelExample::on_radioBtnDescend_clicked()
{tabModel->setSort(ui->comboFields->currentIndex(),Qt::DescendingOrder);//tabModel->setSort(ui->comboFields->currentIndex(),Qt::AscendingOrder);tabModel->select();//执行刷新 才会显示排序
}
//切换成别的字段排序
void SqlTableModelExample::on_comboFields_currentIndexChanged(int index)
{if(ui->radioBtnAescend->isChecked())tabModel->setSort(index,Qt::AscendingOrder);elsetabModel->setSort(index,Qt::DescendingOrder);tabModel->select();
}

表条件过滤及过滤条件清空

void SqlTableModelExample::on_radioBtnMan_clicked()
{tabModel->setFilter(" Gender='男");showRecordCount();
}
void SqlTableModelExample::on_radioBtnBoth_clicked()
{tabModel->setFilter("");showRecordCount();
}

逐行修改数据并提交

void SqlTableModelExample::on_actScan_triggered()
{if(tabModel->rowCount()==0)return;for(int i=0;i<tabModel->rowCount();i++){QSqlRecord rec = tabModel->record(i);float salary = rec.value("Salary").toFloat();rec.setValue("Salary",salary*1.1);tabModel->setRecord(i,rec);}if(tabModel->submitAll())QMessageBox::information(this,"提示","计算完毕");
}

BLOB字段的保存、清空、显示图片

void SqlTableModelExample::on_actPhoto_triggered()
{QString aFile = QFileDialog::getOpenFileName(this,"选择图片文件","","照片(*.jpg)");if(aFile.isEmpty())return;QByteArray data;QFile *file = new QFile(aFile);file->open(QIODevice::ReadOnly);data = file->readAll();file->close();delete file;int curRecNo = selModel->currentIndex().row();QSqlRecord curRec= tabModel->record(curRecNo);curRec.setValue("Photo",data);tabModel->setRecord(curRecNo,curRec);QPixmap pic;pic.load(aFile);ui->dbLabPhoto->setPixmap(pic.scaledToWidth(ui->dbLabPhoto->size().width()));;
}

通过tableModel.SubmitAll() 提交

表事件处理

单元格值发生变化处理事件

判断是否更改 isDirty()方法

//数据发生更改的时候,更新actPost 和 actCancel的状态
void SqlTableModelExample::do_currentChanged(const QModelIndex &current, const QModelIndex &previous)
{Q_UNUSED(current);Q_UNUSED(previous);ui->actSubmit->setEnabled(tabModel->isDirty());ui->actRevert->setEnabled(tabModel->isDirty());
}

焦点行发生变换

切换dataMapper

void SqlTableModelExample::do_currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{Q_UNUSED(previous);ui->actRecDelete->setEnabled(current.isValid());ui->actPhoto->setEnabled(current.isValid());ui->actPhotoClear->setEnabled(current.isValid());if(!current.isValid()){ui->dbLabPhoto->clear();return;}int curRecNo = current.row();dataMapper->setCurrentIndex(curRecNo);QSqlRecord curRec = tabModel->record(curRecNo);//获取当前记录if(curRec.isNull("Photo"))ui->dbLabPhoto->clear();else{QByteArray data =curRec.value("Photo").toByteArray();QPixmap pic;pic.loadFromData(data);ui->dbLabPhoto->setPixmap(pic.scaledToWidth(ui->dbLabPhoto->size().width()));}
}

表其他操作

获取水平列名

void SqlTableModelExample::getFieldNames()
{QSqlRecord emptyRec = tabModel->record();for(int i=0;i<emptyRec.count();i++){qDebug()<<emptyRec.count();ui->comboFields->addItem(emptyRec.fieldName(i));}
}

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

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

相关文章

简化数据流:Apache SeaTunnel实现多表同步的高效指南

Apache SeaTunnel除了单表之间的数据同步之外&#xff0c;也支持单表同步到多表&#xff0c;多表同步到单表&#xff0c;以及多表同步到多表&#xff0c;下面简单举例说明如何实现这些功能。 单表 to 单表 一个source&#xff0c;一个sink。 从mysql同步到mysql&#xff0c;…

Pytorch TensorBoard的使用

from torch.utils.tensorboard import SummaryWriter writer SummaryWriter("logs")for i in range(100):writer.add_scalar("yx",i,i) writer.close() 第一个参数 y2x: 这是图表的标题或标签。它会显示在TensorBoard界面中,帮助你识别这条曲线。 第二个参…

(35)远程识别(又称无人机识别)(二)

文章目录 前言 4 ArduRemoteID 5 终端用户数据的设置和使用 6 测试 7 为OEMs添加远程ID到ArduPilot系统的视频教程 前言 在一些国家&#xff0c;远程 ID 正在成为一项法律要求。以下是与 ArduPilot 兼容的设备列表。这里(here)有一个关于远程 ID 的很好解释和常见问题列表…

【数据结构】排序算法——Lesson2

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

uni-app pinia搭建

1.新建store文件 新建index.js&#xff0c;代码&#xff1a; // import { // createPinia // } from pinia //const store createPinia() import * as Pinia from pinia const pinia Pinia.createPinia() export * from "./modules/user" export * from ".…

计算机网络 6.1Internet概念

第六章 Internet基础 第一节 Internet概念 一、认识Internet 1.定义&#xff1a;集现代计算机技术、通信技术于一体的全球性计算机互联网。 2.地位&#xff1a;当今世界上规模最大的计算机互联网。 3.使用协议&#xff1a;TCP/IP。 4.基本结构&#xff1a; ​ ①主干网…

vscode 寻找全部分支的提交

vscode 寻找全部分支的提交 Git Graph

Python 机器学习求解 PDE 学习项目——PINN 求解二维 Poisson 方程

本文使用 TensorFlow 1.15 环境搭建深度神经网络&#xff08;PINN&#xff09;求解二维 Poisson 方程: 模型问题 − Δ u f in Ω , u g on Γ : ∂ Ω . \begin{align} -\Delta u & f \quad & \text{in } \Omega,\\ u & g \quad & \text{on } \Gamma:\p…

Proxmox8基于PC物理机/服务器安装,初始化,挂载磁盘,安装虚拟机

目录 安装文件 开始安装Proxmox 选择启动菜单&#xff0c;F11 后进入启动菜单选择 按需选择是否关闭RAID 选择对应的U盘 进入安装界面 进入安装启动过程 选择系统盘 设置相关信息 设置IP和开启root远程登录 设置dns 设置网卡ip 设置 ssh 远程登录 开机合并local-l…

LeetCode:爬楼梯(C语言)

1、问题概述&#xff1a;每次可以爬 1 或 2 个台阶。有多少种不同的方法可以爬到楼顶 2、示例 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1. 1 阶 1 阶 2. 2 阶 示例 2&#xff1a; 输入&#xff1a;n 3 输出&a…

Telegram曝零日漏洞,可伪装成视频攻击安卓用户

ESET Research在一个地下论坛上发现了一个针对Android Telegram的零日漏洞广告。 ESET将该漏洞命名为“EvilVideo”&#xff0c;并将其报告给Telegram&#xff0c;Telegram于7月11日更新了该应用程序。 EvilVideo允许攻击者发送恶意的有效载荷&#xff0c;这些载荷以视频文件…

计算机网络-配置双机三层互联(静态路由方式)

目录 交换机工作原理路由器工作原理路由信息表组成部分路由器发决策 ARP工作原理配置双机三层互联&#xff08;静态路由方式&#xff09; 交换机工作原理 MAC自学习过程 初始状态&#xff1a; 刚启动的交换机的MAC地址表是空的。 学习过程&#xff1a; 当交换机收到一个数据帧…

【.NET】asp.net core 程序重启容器后redis无法连接,连接超时

环境是容器化部署asp.net core 程序当有大量请求打到容器如果此时重启容器会出现&#xff0c;redis无法连接情况。 使用 csredis 库报错&#xff1a; Status unavailable, waiting for recovery. Connect to server timeout 使用StackExchange.Redis 报错&#xff1a; Time…

如何将Python应用容器化到Docker中

将Python应用容器化到Docker中是一个常见且有用的做法&#xff0c;它可以帮助你轻松地在不同的环境中部署和运行你的应用&#xff0c;无需担心环境差异带来的问题。以下是编写Dockerfile以容器化Python应用的基本过程&#xff1a; 1. 准备你的Python应用 首先&#xff0c;确保…

基于深度学习的多智能体系统

基于深度学习的多智能体系统&#xff08;Multi-Agent Systems, MAS&#xff09;是指通过多个智能体&#xff08;agents&#xff09;之间的协作或竞争来完成复杂任务的系统。这些智能体通过深度学习和强化学习技术进行学习和决策&#xff0c;广泛应用于机器人协作、自动驾驶、分…

一个注解实现分布式锁加锁

目录 一、概述 二、代码的实现 1、引入依赖 2、配置Redisson 3、定义注解 4、添加aop的切面方法 5、 支持 SpEL 表达式 三、代码验证 四、总结 一、概述 在微服务项目的开发进程中&#xff0c;分布式锁的应用场景屡见不鲜。此时&#xff0c;我们需要借助分布式组件来实…

240723基于opencv下图像阈值

文章目录 1.实验环境2.实验目的3.实验代码4.实验结果1.实验环境 python=3.6 opencv=3.4.1 编译器pycharm 2.实验目的 学习数字图像处理中关于阈值处理的几种方式,分析其中的临界值以及他们的区别 3.实验代码 # @File: 15.1简单阈值.py # @Author: chen_song # @Time: 202…

论文阅读——Integrated Diffusive Antenna Array of Low Backscattering

文章目录 摘要一、背景介绍二、天线结构A. 缝隙天线B. 低频扩散单元C. 高频扩散单元D. 集成设计 三、验证总结 论文来源&#xff1a;https://ieeexplore.ieee.org/document/10309141 摘要 文章提出了一种低雷达散射截面&#xff08;RCS&#xff09;的扩散天线阵列。 作为示例…

优化PyCharm:让IDE响应速度飞起来

优化PyCharm&#xff1a;让IDE响应速度飞起来 PyCharm&#xff0c;作为一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;在提供丰富功能的同时&#xff0c;有时也会出现响应慢的问题。这不仅影响开发效率&#xff0c;还可能打击开发者的积极性。本文将详细…

Linux内存管理--系列文章八——内存管理架构

一、引子 上篇文章讲述了目前内存的硬件架构&#xff0c;本篇阐述内核中是怎么表示不同架构的物理内存页。 二、平坦内存模型&#xff08;Flat Memory Model&#xff09; 在该模型下&#xff0c;物理内存是连续的&#xff0c;所以物理地址也是连续的。这时内核使用struct pa…