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

Qt数据库之QTabelModel

QTabelModel的好处就是不需要执行sql语句就可以对数据库进行操作。

创建数据库:

QSqlDatabase  DB;//数据库连接
QString aFile=QFileDialog::getOpenFileName(this,"选择数据库文件","","SQL Lite数据库(*.db *.db3)");
DB=QSqlDatabase::addDatabase("QSQLITE"); //添加 SQL LITE数据库驱动DB.setDatabaseName(aFile); //设置数据库名称
//    DB.setHostName();
//    DB.setUserName();
//    DB.setPassword();if (!DB.open())   //打开数据库{QMessageBox::warning(this, "错误", "打开数据库失败",QMessageBox::Ok,QMessageBox::NoButton);

创建模型:

QSqlTableModel  *tabModel;  //数据模型
tabModel=new QSqlTableModel(this,DB);//数据表

设置要打开哪张表:

tabModel->setTable("employee"); //设置要打开的数据表

设置数据保存的条件:

tabModel->setEditStrategy(QSqlTableModel::OnManualSubmit);//数据保存方式,OnManualSubmit , OnRowChange

设置数据显示的时候排序的条件:

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

判断打开数据表是否成功:

tabModel->select()

将数据库每个字段的名称与模型对应视图应该现实的名称对应起来:

//字段显示名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("Height"),Qt::Horizontal,"身高");tabModel->setHeaderData(tabModel->fieldIndex("Birthday"),Qt::Horizontal,"出生日期");tabModel->setHeaderData(tabModel->fieldIndex("Mobile"),Qt::Horizontal,"手机");tabModel->setHeaderData(tabModel->fieldIndex("Province"),Qt::Horizontal,"省份");tabModel->setHeaderData(tabModel->fieldIndex("City"),Qt::Horizontal,"城市");tabModel->setHeaderData(tabModel->fieldIndex("Department"),Qt::Horizontal,"部门");tabModel->setHeaderData(tabModel->fieldIndex("Education"),Qt::Horizontal,"学历");tabModel->setHeaderData(tabModel->fieldIndex("Salary"),Qt::Horizontal,"工资");tabModel->setHeaderData(tabModel->fieldIndex("Memo"),Qt::Horizontal,"备注"); //这两个字段不再tableView中显示tabModel->setHeaderData(tabModel->fieldIndex("Photo"),Qt::Horizontal,"照片");

创建选择模型并进行关联:

 QItemSelectionModel *theSelection; //选择模型
theSelection=new QItemSelectionModel(tabModel);//关联选择模型

连接两个槽函数:

//theSelection当前项变化时触发currentChanged信号connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)),this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));
//选择行变化时connect(theSelection,SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),this,SLOT(on_currentRowChanged(QModelIndex,QModelIndex)));
void MainWindow::on_currentChanged(const QModelIndex &current, const QModelIndex &previous)
{//更新actPost和actCancel 的状态Q_UNUSED(current);Q_UNUSED(previous);ui->actSubmit->setEnabled(tabModel->isDirty()); //有未保存修改时可用ui->actRevert->setEnabled(tabModel->isDirty());
}
void MainWindow::on_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;}dataMapper->setCurrentIndex(current.row()); //更新数据映射的行号int curRecNo=current.row();//获取行号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()));}
}

将模型和视图进行绑定并设置不显示列:

ui->tableView->setModel(tabModel);//设置数据模型ui->tableView->setSelectionModel(theSelection); //设置选择模型ui->tableView->setColumnHidden(tabModel->fieldIndex("Memo"),true);//隐藏列,即不显示这列ui->tableView->setColumnHidden(tabModel->fieldIndex("Photo"),true);//隐藏列,即不显示这列

为某些列指定代理组件,主要用于需要进行编辑的列:

//tableView上为“性别”和“部门”两个字段设置自定义代理组件QStringList strList;strList<<"男"<<"女";bool isEditable=false;delegateSex.setItems(strList,isEditable);ui->tableView->setItemDelegateForColumn(tabModel->fieldIndex("Gender"),&delegateSex); //Combbox选择型strList.clear();strList<<"销售部"<<"技术部"<<"生产部"<<"行政部";isEditable=true;delegateDepart.setItems(strList,isEditable);ui->tableView->setItemDelegateForColumn(tabModel->fieldIndex("Department"),&delegateDepart); //Combbox选择型
创建界面组件与数据模型的字段之间的数据映射,这样就将界面上的各个编辑组件与对应字段的数据进行绑定:
QDataWidgetMapper   *dataMapper; //数据映射
//创建界面组件与数据模型的字段之间的数据映射dataMapper= new QDataWidgetMapper();dataMapper->setModel(tabModel);//设置数据模型dataMapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);////    dataMapper->setItemDelegate(new QSqlRelationalDelegate(this)); //含有外键的
//界面组件与tabModel的具体字段之间的联系dataMapper->addMapping(ui->dbSpinEmpNo,tabModel->fieldIndex("empNo"));dataMapper->addMapping(ui->dbEditName,tabModel->fieldIndex("Name"));dataMapper->addMapping(ui->dbComboSex,tabModel->fieldIndex("Gender"));dataMapper->addMapping(ui->dbSpinHeight,tabModel->fieldIndex("Height"));dataMapper->addMapping(ui->dbEditBirth,tabModel->fieldIndex("Birthday"));dataMapper->addMapping(ui->dbEditMobile,tabModel->fieldIndex("Mobile"));dataMapper->addMapping(ui->dbComboProvince,tabModel->fieldIndex("Province"));dataMapper->addMapping(ui->dbEditCity,tabModel->fieldIndex("City"));dataMapper->addMapping(ui->dbComboDep,tabModel->fieldIndex("Department"));dataMapper->addMapping(ui->dbComboEdu,tabModel->fieldIndex("Education"));dataMapper->addMapping(ui->dbSpinSalary,tabModel->fieldIndex("Salary"));
dataMapper->addMapping(ui->dbEditMemo,tabModel->fieldIndex("Memo"));//    dataMapper->addMapping(ui->dbPhoto,tabModel->fieldIndex("Photo")); //图片无法直接映射dataMapper->toFirst();//移动到首记录

创建数据记录QSqlRecord:

//获取所有字段名称进行填充QSqlRecord  emptyRec=tabModel->record();//获取空记录,只有字段名for (int i=0;i<emptyRec.count();i++)ui->comboFields->addItem(emptyRec.fieldName(i));QSqlRecord  rec(int row)返回的就是第row行记录

增删改查的操作:

void MainWindow::on_actRecAppend_triggered()
{//添加记录tabModel->insertRow(tabModel->rowCount(),QModelIndex()); //在末尾添加一个记录QModelIndex curIndex=tabModel->index(tabModel->rowCount()-1,1);//创建最后一行的ModelIndextheSelection->clearSelection();//清空选择项theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);//设置刚插入的行为当前选择行int currow=curIndex.row(); //获得当前行tabModel->setData(tabModel->index(currow,0),2000+tabModel->rowCount()); //自动生成编号tabModel->setData(tabModel->index(currow,2),"男");
// 插入行时设置缺省值,需要在primeInsert()信号里去处理
}void MainWindow::on_actRecInsert_triggered()
{//插入记录QModelIndex curIndex=ui->tableView->currentIndex();tabModel->insertRow(curIndex.row(),QModelIndex());theSelection->clearSelection();//清除已有选择theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
}void MainWindow::on_actRevert_triggered()
{//取消修改tabModel->revertAll();ui->actSubmit->setEnabled(false);ui->actRevert->setEnabled(false);
}void MainWindow::on_actSubmit_triggered()
{//保存修改bool res=tabModel->submitAll();if (!res)QMessageBox::information(this, "消息", "数据保存错误,错误信息\n"+tabModel->lastError().text(),QMessageBox::Ok,QMessageBox::NoButton);else{ui->actSubmit->setEnabled(false);ui->actRevert->setEnabled(false);}
}
void MainWindow::on_actRecDelete_triggered()
{//删除当前记录QModelIndex curIndex=theSelection->currentIndex();//获取当前选择单元格的模型索引tabModel->removeRow(curIndex.row()); //删除最后一行
}

获取记录并设置记录的值:

for (int i=0;i<tabModel->rowCount();i++){QSqlRecord aRec=tabModel->record(i); //获取当前记录float salary=aRec.value("Salary").toFloat();//获取值salary=salary*1.1;aRec.setValue("Salary",salary);//设置值tabModel->setRecord(i,aRec);}

按设定的字段进行排序:

void MainWindow::on_comboFields_currentIndexChanged(int index)
{//选择字段进行排序if (ui->radioBtnAscend->isChecked())tabModel->setSort(index,Qt::AscendingOrder);elsetabModel->setSort(index,Qt::DescendingOrder);tabModel->select();
}

相关文章:

Qt数据库之QTabelModel

QTabelModel的好处就是不需要执行sql语句就可以对数据库进行操作。 创建数据库&#xff1a; QSqlDatabase DB;//数据库连接 QString aFileQFileDialog::getOpenFileName(this,"选择数据库文件","","SQL Lite数据库(*.db *.db3)"); DBQSqlData…...

计算机视觉(CV)技术的优势和挑战

计算机视觉技术在很多领域具有很大的优势,例如: 自动化:计算机视觉技术可以帮助实现自动化生产和检测,省去了人力成本和时间成本。 准确性:计算机视觉技术可以提高生产和检测的准确性,降低了人工操作产生的误差。 速度:计算机视觉技术可以实现高速速度的生产和检测,提高…...

面试官:【后端一次性返回10万条数据怎么处理/后端发送大数据量的数据如何处理】

文章目录 前言定时器分片处理文档碎片懒加载后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;前端系列文章 &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错误…...

深入理解强化学习——多臂赌博机:梯度赌博机算法的数学证明

分类目录&#xff1a;《深入理解强化学习》总目录 通过将梯度赌博机算法理解为梯度上升的随机近似&#xff0c;我们可以深人了解这一算法的本质。在精确的梯度上升算法中&#xff0c;每一个动作的偏好函数 H t ( a ) H_t(a) Ht​(a)与增量对性能的影响成正比&#xff1a; H t …...

StackExchange.Redis 高并发下timeout超时问题如何解决?

查看服务端程序负载还行&#xff0c;根据打印的连接看到一知半懂&#xff0c;按GitHub的issue提示&#xff0c;这2个Busy的数量不能比Min的大&#xff0c;即要提示Min的数值; 的各个字段&#xff1a; Timeout performing EXEC (1000ms): 表示在执行一个事务&#xff08;MULTI..…...

JAVA基础7:数组

1.数组定义格式 1&#xff09;数组概述 一次性声明大量的用于存储数据的变量 要存储的数据通常都是同类型数据&#xff0c;比如&#xff1a;考试成绩 数组&#xff08;array)是一种用于存储多个相同类型数据的存储模型 2&#xff09;数组定义格式 格式一&#xff1a;数据类…...

Riskified: 2023年电商政策滥用问题恶化,正严重挑战商家盈利底线

2023年11月14日&#xff0c;中国上海 —— 近日&#xff0c;由全球领先的电子商务欺诈和风险智能解决方案提供商 Riskified 发布的《政策滥用及其对商家的影响&#xff1a;2023年全球参考基准》报告显示&#xff0c;政策滥用问题正进一步恶化&#xff0c;超过九成电商商家正在承…...

【论文阅读】多模态NeRF:Cross-Spectral Neural Radiance Fields

https://cvlab-unibo.github.io/xnerf-web intro 从不同的light spectrum sensitivity获取信息&#xff0c;同时需要obtain a unified Cross-Spectral scene representation – allowing for querying, for any single point, any of the information sensed across spectra。…...

Huggingface

1 介绍 Hugging Face 是一个开源模型社区。目前已经共享 300k 模型&#xff0c;100k 应用&#xff0c;50k 数据集&#xff08;截至 231114 数据&#xff09;&#xff0c;可视为 AI 界的 github。 2 官网 https://huggingface.co/ 3 主要功能 3.1 Models 模型 大家都用过就…...

【深度学习】pytorch——常用工具模块

笔记为自我总结整理的学习笔记&#xff0c;若有错误欢迎指出哟~ 深度学习专栏链接&#xff1a; http://t.csdnimg.cn/dscW7 pytorch——常用工具模块 数据处理 torch.utils.data模块DatasetDataLoadersamplertorch.utils.data的使用 计算机视觉工具包 torchvisiontorchvision.d…...

【Android】统一系统动画

需求&#xff1a;除panel动画效果为弹出之外&#xff0c;其余的应用效果为渐入渐出 从系统层面统一把控动画效果&#xff0c;而不是单个应用自己处理 Android系统版本&#xff1a;9.0 代码地址 \frameworks\base\core\res\res\values\styles.xml 当时看注释&#xff0c;以为…...

京东数据运营与分析:如何全面获取电商销售数据?

随着电商行业的快速发展&#xff0c;数据分析成为了电商运营中一个非常重要的环节&#xff0c;这一环往往能够帮助品牌方来提升销售业绩和管理效率。然而&#xff0c;如何获取到电商平台中详细、全面的销售数据是很多电商品牌方所关心的问题&#xff0c;事实上&#xff0c;第三…...

du_命令可以像find_命令那样列出最大的文件吗

【赠送】IT技术视频教程&#xff0c;白拿不谢&#xff01;思科、华为、红帽、数据库、云计算等等_厦门微思网络的博客-CSDN博客文章浏览阅读418次。风和日丽&#xff0c;小微给你送福利~如果你是小微的老粉&#xff0c;这里有一份粉丝福利待领取...如果你是新粉关注到了小微&am…...

asp.net blazor集成TinyMCE.Blazor

asp.net blazor项目添加TinyMCE.Blazor nuget包 在blazor页面中添加&#xff0c;可以通过ScriptSrc参数配置自定义TinyMCE.Blazor js <EditForm class"mb-3" Model"Model" OnValidSubmit"HandleValidSubmit"><div class"form-gro…...

CSS注入的四种实现方式

目录 CSS注入窃取标签属性数据 简单的一个实验&#xff1a; 解决hidden 方法1&#xff1a;jsnode.js实现 侧信道攻击 方法2&#xff1a;对比波兰研究院的方案 使用兄弟选择器 方法3&#xff1a;jswebsocket实现CSS注入 实验实现&#xff1a; 方法4&#xff1a;window…...

突然消失的桌面文件如何恢复?详细教程让你轻松解决问题!

桌面文件突然消失&#xff0c;对于很多人来说&#xff0c;可能是个令人头疼的问题。这些文件可能包含重要的信息&#xff0c;也可能是数日甚至数周的努力成果。那么&#xff0c;当这种情况发生时&#xff0c;我们如何恢复丢失的文件呢&#xff1f;本文将提供一些实用的建议。 1…...

Springboot+Dubbo+Nacos 集成 Sentinel(入门)

Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。Sentinel 官网 1.版本选择 参考 SpringClou…...

ARPG----C++学习记录05 Section10 武器类,IK重定向,装备和捡起武器,动画蓝图

代码更新 11.13 BAOfanTing/ARPG_Game_Code7ab54d2 GitHub 武器类 基于item类&#xff0c;创建一个weapon的C类&#xff0c;基于它创建一个蓝图&#xff0c;刀剑的网格体给它。在蓝图里调动之前在C写好的sin函数添加到世界偏移量里&#xff0c;得到一把悬浮刀 在item把重叠函…...

CSRF跨站请求伪造

CSRF CSRF&#xff08;Cross-Site Request Forgery&#xff0c;跨站请求伪造&#xff09;是通过诱导用户执行操作&#xff0c;利用用户在网站上的登录状态&#xff0c;以用户的身份在网站上执行恶意操作。 以下是CSRF攻击的一些关键特征&#xff1a; 用户身份&#xff1a;CSR…...

修改kernel驱动配置文件

对于内核分析&#xff0c;使用CONFIG_KPROBESy和CONFIG_KPROBE_EVENTSy来启用内核动态跟踪&#xff0c;而CONFIG_FRAME_POINTERy用于基于帧指针的内核堆栈。对于用户级分析&#xff0c;CONFIG_UPROBESy和CONFIG_UROBE_EVENTSy用于用户级动态跟踪。 添加位置在 kernel/.config...

Qwen3.5-2B轻量模型评测:端侧推理延迟、功耗、准确率三维平衡点实测

Qwen3.5-2B轻量模型评测&#xff1a;端侧推理延迟、功耗、准确率三维平衡点实测 1. 模型概述 Qwen3.5-2B是通义千问团队推出的轻量化多模态基础模型&#xff0c;属于Qwen3.5系列的小参数版本&#xff08;20亿参数&#xff09;。该模型专为低功耗、低门槛部署场景设计&#xf…...

Fluent后处理效率翻倍:用View功能建立你的专属仿真报告视角库

Fluent后处理效率翻倍&#xff1a;用View功能建立你的专属仿真报告视角库 在仿真工程师的日常工作中&#xff0c;最耗时的往往不是计算本身&#xff0c;而是后处理阶段——反复调整视角、截图、标注、排版&#xff0c;只为生成一份清晰直观的报告。我曾参与过一个散热器优化项目…...

如何破解Godot游戏的黑盒:解密PCK文件中的资源宝藏

如何破解Godot游戏的黑盒&#xff1a;解密PCK文件中的资源宝藏 【免费下载链接】godot-unpacker godot .pck unpacker 项目地址: https://gitcode.com/gh_mirrors/go/godot-unpacker 你是否曾好奇Godot游戏内部隐藏着怎样的资源结构&#xff1f;当面对那些看似神秘的.pc…...

概率论其实很简单:从“明天会不会下雨”到“AI怎么猜你心思”

一、概率就是“长期来看&#xff0c;这件事发生的比例”你早上看天气预报&#xff0c;说“降水概率30%”。你心想&#xff1a;才30%&#xff0c;不带了伞。结果下午淋成落汤鸡。你骂天气乱报&#xff1f;不用。因为30%的意思是&#xff1a;如果像今天这样的天气有100天&#xf…...

小白友好:Qwen-Image-Layered快速部署,轻松实现AI图片元素分离

小白友好&#xff1a;Qwen-Image-Layered快速部署&#xff0c;轻松实现AI图片元素分离 你是否遇到过这样的情况&#xff1a;好不容易用AI生成了一张满意的图片&#xff0c;却发现某个元素需要修改&#xff0c;比如想换个背景颜色、调整某个物体的位置&#xff0c;或者改变文字…...

Nginx多服务静态资源路径冲突解决方案

在Nginx反向代理多个Flask服务时&#xff0c;不同服务的静态资源路径会发生冲突&#xff0c;导致服务A的页面加载了服务B的CSS/JS文件&#xff0c;或者找不到静态资源返回404错误。 问题场景 部署架构 域名: mathcoding.top ├── 主服务 (端口5000) → 路径前缀: / └──…...

2025版等级保护测评报告模板:风险导向与合规深化的实践指南

1. 2025版等级保护测评报告模板的核心变革 如果你最近接触过等级保护测评工作&#xff0c;一定会注意到2025版报告模板带来的显著变化。这个版本最大的特点就是从过去的"得分导向"彻底转向了"风险导向"。在实际工作中&#xff0c;我发现很多企业安全负责人…...

突破安卓HTTPS抓包困境:Xposed+JustTrustMe框架实战指南

1. 为什么HTTPS抓包在安卓上这么难&#xff1f; 最近几年做安全测试的朋友应该深有体会&#xff0c;安卓应用的HTTPS抓包越来越难搞了。我刚开始接触这块时也踩了不少坑&#xff0c;明明在浏览器里能轻松抓到的HTTPS请求&#xff0c;到了APP里就死活抓不到。后来才发现&#xf…...

用STM32F103C8T6和NRF24L01自制遥控器,从硬件选型到代码调试的完整避坑指南

STM32F103C8T6与NRF24L01遥控器开发实战&#xff1a;从硬件设计到软件调试的全流程解析 在创客和嵌入式开发领域&#xff0c;无线遥控系统一直是热门话题。无论是机器人控制、无人机飞行还是智能家居应用&#xff0c;稳定可靠的遥控器都是不可或缺的核心组件。本文将详细介绍如…...

用Python手把手实现ALNS算法:从TSP路径规划到代码实战(附完整源码)

用Python手把手实现ALNS算法&#xff1a;从TSP路径规划到代码实战 旅行商问题&#xff08;TSP&#xff09;是组合优化中最经典的NP难问题之一&#xff0c;如何在合理时间内找到近似最优解一直是算法研究的重点。自适应大邻域搜索&#xff08;ALNS&#xff09;作为LNS算法的增强…...