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

Qt数据库操作-QSqlQueryModel 的使用

QSqlQueryModel 功能概述

QSqlQueryModel 是 QSqlTableModel 的父类。QSqlQueryModel 封装了执行 SELECT 语句从数据库查询数据的功能,但是 QSqlQueryModel 只能作为只读数据源使用,不可以编辑数据。QSqlQueryModel 类的主要函数如下:

接口函数功能描述
void clear()清除数据模型,释放所有获得的数据
QSqlError lastError()返回上次的错误,可以获取错误的类型和文本信息
QSqlQuery query()返回当前关联的 QSqlQuery 对象
void setQuery(QSqlQuery& query)设置一个 QSqlQuery 对象,获取数据
void setQuery(QString& query)设置一个 SELECT 语句创建查询,获取数据
QSqlRecord record()返回一个空记录,包含当前查询的字段信息
QSqlRecord record(int row)返回行号为 row 的记录
int rowCount()返回查询到的记录条数
int columnCount()返回查询的字段个数
void setHeaderData(int section, Qt::Orientation orientation, QVariant& value)设置表头数据,一般用于设置字段的表头标题

使用 QSqlQueryModel 作为数据模型从数据库查询数据,只需要使用 setQuery() 函数设置一个 SELECT 查询语句即可。QSqlQueryModel 可以作为 QTableView 等视图组件的数据源,也可以使用 QDataWidgetMapper 创建字段与界面组件的映射,只是查询出来的数据是不可编辑的。

使用 QSqlQueryModel 实现数据查询

实例功能

image.png

使用 QSqlQueryModel 可以从一个数据表或多个数据表里查询数据,只要设计好 SELECT 语句即可。由于 QSqlQueryModel 读出的数据是只读的,所以没有编辑保存等功能,主窗口定义如下:

class MainWindow : public QMainWindow
{Q_OBJECTprivate:QLabel  *LabInfo;QSqlDatabase  DB; //数据库QSqlQueryModel  *qryModel; //数据模型QItemSelectionModel *theSelection; //选择模型QDataWidgetMapper   *dataMapper;//数据界面映射void    openTable();//打开数据表void    refreshTableView();//移动记录时刷新TableView的当前行
public:explicit MainWindow(QWidget *parent = 0);~MainWindow();private slots:// QTableView的SelectionModel的行发生了变化,进行处理void on_currentRowChanged(const QModelIndex &current, const QModelIndex &previous);
///void on_actOpenDB_triggered();void on_actRecFirst_triggered();void on_actRecPrevious_triggered();void on_actRecNext_triggered();void on_actRecLast_triggered();private:Ui::MainWindow *ui;
};

这里定义了 QSqlQueryModel 类型的数据模型变量 qryModel,也定义了数据库、选择模型和数据界面映射的变量。refreshTableView() 函数用于记录移动后刷新 TableView 上的当前行位置。自定义槽函数 on_currentRowChanged() 在选择模型的当前变化时,处理 Photo 字段的查询与照片显示。

打开数据库

openTable() 用于查询数据,简历界面显示等具体操作,代码如下:

void MainWindow::openTable()
{//打开数据表qryModel=new QSqlQueryModel(this);qryModel->setQuery("SELECT empNo, Name, Gender, Height, Birthday, Mobile, Province, City, Department, "" Education, Salary FROM employee ORDER BY empNo");if (qryModel->lastError().isValid()){QMessageBox::critical(this, "错误", "数据表查询错误,错误信息\n"+qryModel->lastError().text(),QMessageBox::Ok,QMessageBox::NoButton);return;}LabInfo->setText(QString::asprintf("记录条数:%d",qryModel->rowCount()));qryModel->setHeaderData(0,Qt::Horizontal,"工号");qryModel->setHeaderData(1,Qt::Horizontal,"姓名");qryModel->setHeaderData(2,Qt::Horizontal,"性别");qryModel->setHeaderData(3,Qt::Horizontal,"身高");qryModel->setHeaderData(4,Qt::Horizontal,"出生日期");qryModel->setHeaderData(5,Qt::Horizontal,"手机");qryModel->setHeaderData(6,Qt::Horizontal,"省份");qryModel->setHeaderData(7,Qt::Horizontal,"城市");qryModel->setHeaderData(8,Qt::Horizontal,"部门");qryModel->setHeaderData(9,Qt::Horizontal,"学历");qryModel->setHeaderData(10,Qt::Horizontal,"工资");theSelection=new QItemSelectionModel(qryModel);//选择行变化时connect(theSelection,SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),this,SLOT(on_currentRowChanged(QModelIndex,QModelIndex)));ui->tableView->setModel(qryModel);ui->tableView->setSelectionModel(theSelection);
//    ui->tableView->resizeColumnsToContents();
//    ui->tableView->horizontalHeader()->setStretchLastSection(true);//创建数据映射dataMapper= new QDataWidgetMapper();dataMapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);dataMapper->setModel(qryModel);dataMapper->addMapping(ui->dbSpinEmpNo,0);//"empNo";dataMapper->addMapping(ui->dbEditName,1);//"Name";dataMapper->addMapping(ui->dbComboSex,2);//"Gender";dataMapper->addMapping(ui->dbSpinHeight,3);//"Height";dataMapper->addMapping(ui->dbEditBirth,4);//"Birthday";dataMapper->addMapping(ui->dbEditMobile,5);//"Mobile";dataMapper->addMapping(ui->dbComboProvince,6);//"Province";dataMapper->addMapping(ui->dbEditCity,7);//"City";dataMapper->addMapping(ui->dbComboDep,8);//"Department";dataMapper->addMapping(ui->dbComboEdu,9);//"Education";dataMapper->addMapping(ui->dbSpinSalary,10);//"Salary";dataMapper->toFirst();ui->actOpenDB->setEnabled(false);
}

程序首先创建了 QSqlQueryModel 类型的私有变量 qryModel,然后调用 setQuery() 函数设置了 SELECT 查询语句,SELECT 语句从 employee 表里查询除了 Memo 和 Photo 之外的所有其他字段。使用 setHeadData() 函数为每个字段设置显示标题,为了代码简化,这里直接使用字段的序号。
qryModel 创建了选择模型 theSelection,并将其 currentRowChanged() 信号和自定义槽函数关联,查询出数据显示在界面上,槽函数代码如下:

void MainWindow::on_currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{Q_UNUSED(previous);if (!current.isValid()){ui->dbLabPhoto->clear();return;}dataMapper->setCurrentModelIndex(current);bool first=(current.row()==0); //是否首记录bool last=(current.row()==qryModel->rowCount()-1);//是否尾记录ui->actRecFirst->setEnabled(!first); //更新使能状态ui->actRecPrevious->setEnabled(!first);ui->actRecNext->setEnabled(!last);ui->actRecLast->setEnabled(!last);int curRecNo=theSelection->currentIndex().row();QSqlRecord  curRec=qryModel->record(curRecNo); //获取当前记录int empNo=curRec.value("EmpNo").toInt();QSqlQuery query; //查询当前empNo的Memo和Photo字段的数据query.prepare("select EmpNo, Memo, Photo from employee where EmpNo = :ID");query.bindValue(":ID",empNo);query.exec();query.first();QVariant    va=query.value("Photo");//if (!va.isValid())  //图片字段内容为空ui->dbLabPhoto->clear();else{//显示照片QByteArray data=va.toByteArray();QPixmap pic;pic.loadFromData(data);ui->dbLabPhoto->setPixmap(pic.scaledToWidth(ui->dbLabPhoto->size().width()));}QVariant    va2=query.value("Memo");//显示备注ui->dbEditMemo->setPlainText(va2.toString());
}

记录移动

用于数据映射的 QDataWidgetMapper 类设置数据模型后,总是指向数据模型的当前记录。QDataWidgetMapper 有四个函数进行当前记录移动,分别是 toFirst()toLast()toNext()toPrevious()。当前记录移动时,会引起数据模型关联的选择模型发射 currentRowChanged() 信号,触发槽函数。工具栏的四个移动按钮代码如下:

void MainWindow::on_actRecFirst_triggered()
{ //首记录dataMapper->toFirst();refreshTableView();
}void MainWindow::on_actRecPrevious_triggered()
{ //前一条记录dataMapper->toPrevious();refreshTableView();
}void MainWindow::on_actRecNext_triggered()
{//后一条记录dataMapper->toNext();refreshTableView();
}void MainWindow::on_actRecLast_triggered()
{//最后一条记录dataMapper->toLast();refreshTableView();
}

参考资料:https://github.com/0voice

相关文章:

Qt数据库操作-QSqlQueryModel 的使用

QSqlQueryModel 功能概述 QSqlQueryModel 是 QSqlTableModel 的父类。QSqlQueryModel 封装了执行 SELECT 语句从数据库查询数据的功能,但是 QSqlQueryModel 只能作为只读数据源使用,不可以编辑数据。QSqlQueryModel 类的主要函数如下: 接口…...

C语言编程1.21波兰国旗问题

题目描述 桌上有 n ( 1 < n < 10000 ) 面小旗&#xff0c;一部分是白旗&#xff0c;一部分是红旗(波兰国旗由白色和红色组成)。唯一允许的操作是交换两面小旗位置。请你设计一个算法&#xff0c;用最少的交换操作将所有的白旗都置于红旗的之前。 输入格式 第一行为一个…...

如何利用微型5G网关为智慧无人矿车提供精确定位

随着5G、AI、物联网技术的发展和普及&#xff0c;越来越多行业正在加快生产、运营、管理的无人化、数字化与智能化&#xff0c;以适应当前我国“智慧、绿色、低碳”的新型发展模式需要。其中矿产业就是典型场景之一。针对矿山场景的智慧化、无人化转型&#xff0c;佰马提供基于…...

使用docker-compese部署SFTPGo详解

官网&#xff1a;SFTP & FTP as a Managed Service (SaaS) and On-premise 一、SFTPGo简介 SFTPGo 是一款功能强大的文件传输服务器软件。它支持多种协议&#xff08;SFTP、SCP、FTP/S、WebDAV、HTTP/S&#xff09;和多个存储后端。 借助 SFTPGo&#xff0c;您可以利用本地…...

Ajax基础总结(思维导图+二维表)

一些话 刚开始学习Ajax的时候&#xff0c;感觉很模糊&#xff0c;但是好像学什么都是这样的&#xff0c;很正常&#xff0c;但是当你学习的时候要持续性敲代码&#xff0c;边敲代码其实就可以理解很多了。然后在最后的总结&#xff0c;其实做二维表之后&#xff0c;就可以区分…...

Spring Task和WebSocket使用

在现代 Web 应用中&#xff0c;WebSocket 作为一种全双工通信协议&#xff0c;为实时数据传输提供了强大的支持。若要确保 WebSocket 在生产环境中的稳定性和性能&#xff0c;使用 Nginx 作为反向代理服务器是一个明智的选择。本篇文章将带你了解如何在 Nginx 中配置 WebSocket…...

微信小程序 本地调试和vconsole可以 但在体验上页面不请求数据

微信小程序页面不请求数据 本地调试和vconsole可以 但在体验版页面不请求数据&#xff0c;如遇到这类问题基本都是一样的解决办法 1、如何调试找到问题 首先要把小程序本地设置的不校验合法域名关掉&#xff0c;不然本地一直都是好的 然后通过本地真机调试打断点找到问题位…...

QT:将QTableWidget内容写入txt文件中

文章详请&#xff1a;最近在做手在眼上的标定&#xff0c;首先要采集机械臂数据和图像数据&#xff0c;我使用tablewidget进行机械臂数据的显示&#xff0c;最后的计算需要将机械臂位姿数据存储在txt文件中。 引用&#xff1a;Qt如何保存tableWidget数据&#xff1f;_qt table…...

前端面试题(六)

1.let,var,const区别 1.作用域&#xff1a;  var&#xff1a;var声明的变量存在函数作用域或全局作用域&#xff0c;这意味着它们在声明它们的函数内部可见&#xff0c;而不在块级作用域内可见。 let和const&#xff1a;let和const声明的变量存在块级作用域&#xff0c;这…...

「Mac畅玩鸿蒙与硬件35」UI互动应用篇12 - 简易日历

本篇将带你实现一个简易日历应用&#xff0c;显示当前月份的日期&#xff0c;并支持选择特定日期的功能。用户可以通过点击日期高亮选中&#xff0c;还可以切换上下月份&#xff0c;体验动态界面的交互效果。 关键词 UI互动应用简易日历动态界面状态管理用户交互 一、功能说明…...

Leetcode581. 最短无序连续子数组(HOT100)

链接 我的代码&#xff1a; class Solution { public:int findUnsortedSubarray(vector<int>& nums) {vector<int> res nums;sort(res.begin(),res.end());int l 0,r nums.size()-1;while(nums[l]res[l]){l;if(lnums.size()){return 0;}}while(nums[r]res…...

HTML前端开发-- Flex布局详解及实战

引言 Flex布局&#xff0c;全称为Flexible Box Layout&#xff0c;是一种现代CSS布局技术&#xff0c;它提供了一种更有效的方式来设计响应式布局和复杂页面布局。本文将详细介绍Flex布局的基本概念、属性以及实战应用。 一、基本概念 Flex布局的核心是Flex容器&#xff08;…...

基于JWT跨语言开发分布式业务系统的挑战与实践:多语言协作的最佳方案

在现代分布式架构下&#xff0c;开发团队往往由来自不同技术栈和开发语言的工程师组成。如何有效地管理这些开发人员的协作&#xff0c;尤其是在实现跨语言的认证与授权机制时&#xff0c;成为了开发者面临的一个重大挑战。JSON Web Token&#xff08;JWT&#xff09;作为一种轻…...

二分法篇——于上下边界的扭转压缩间,窥见正解辉映之光(2)

前言 上篇介绍了二分法的相关原理并结合具体题目进行讲解运用&#xff0c;本篇将加大难度&#xff0c;进一步强化对二分法的掌握。 一. 寻找峰值 1.1 题目链接&#xff1a;https://leetcode.cn/problems/find-peak-element/description/ 1.2 题目分析: 题目要求返回数组内…...

什么是 Kata Containers?

什么是 Kata Containers&#xff1f; Kata Containers 是一种结合了容器技术和虚拟机技术的轻量级运行时&#xff0c;旨在提供容器的速度和虚拟机的安全性。它将容器运行在一个隔离的虚拟机中&#xff0c;从而大幅提升安全性&#xff0c;同时保持容器的高效性。 Kata Contain…...

SpringMvc项目配置RabbitMq

前言&#xff1a;只有消费者部分&#xff0c;没有记录生产者部分 结构图 配置类 可以xml配置&#xff0c;也可以配置类&#xff0c;二者可以相互转化。两种bean注入的方式。 import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.spring…...

shell编程(4)脚本与用户交互以及if条件判断

shell编程&#xff08;4&#xff09;脚本与用户交互以及if条件判断 声明&#xff01; 学习视频来自B站up主 ​泷羽sec​​ 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章 笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;…...

vue2组件跨层级数据共享provide 和 inject

在 Vue 2 中&#xff0c;provide 和 inject 的功能也是可以使用的&#xff0c;虽然在 Vue 3 中它们成为了组合式 API 的一部分。在 Vue 2 中&#xff0c;provide 和 inject 主要是用于祖先组件和后代组件之间的数据共享&#xff0c;而不是通过 props 和 emit 逐层传递。 Vue 2…...

springboot/ssm校园闲置物品交易系统ava大学生二手闲置交易平台web二手源码

springboot/ssm校园闲置物品交易系统ava大学生二手闲置交易平台web二手源码 基于springboot(可改ssm)htmlvue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数…...

Redis实现限量优惠券的秒杀

核心&#xff1a;避免超卖问题&#xff0c;保证一人一单 业务逻辑 代码步骤分析 全部代码 Service public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {Resourceprivate ISeckillVoucher…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...