QT数据库:QSqlQueryModel实现数据查询

ops/2024/12/13 20:23:52/

QSqlQueryModel 可以设置任意的 SELECT 语句来从数据库中查询数据,可以查询一个数据表部分字段的数据,也可以是多个数据表组合的数据。该模型的数据是只读的,即使在界面上修改了QSqlQueryModel 模型的数据,也不能将所做的修改提交到数据库

要从数据库查询数据并将其作为 QSqlQueryModel 的数据源,需要运行函数 setQuery()

有两种原型:

void QSqlQueryModel::setQuery(const QString &query, const QSqlDatabase &db = QSqlDatabase())

参数 query 是一条完整的 SELECT 查询语句;参数 db 是数据库连接,若不指定数据库连接, 就用程序默认的数据库连接。

void QSqlQueryModel::setQuery(QSqlQuery &&query)

QSqlQuery 是可以运行任何 SQL 语句的类,当然也能运行 SELECT 语句从数据库获取数据。

查询出数据后,可以用 QSqlQueryModel 的函数 record()访问数据记录。

//1. 创建数据模型,查询数据qryModel=new QSqlQueryModel(this);qryModel->setQuery("SELECT empNo, Name, Gender,  Birthday,  Province,  Department, "" Salary FROM employee ORDER BY empNo",DB);if (qryModel->lastError().isValid()){QMessageBox::critical(this, "错误", "数据表查询错误,错误信息\n"+qryModel->lastError().text());return;}//2. 设置字段显示标题QSqlRecord rec=qryModel->record();  //获取一个空记录,为了获取字段序号qryModel->setHeaderData(rec.indexOf("empNo"),  Qt::Horizontal, "工号");qryModel->setHeaderData(rec.indexOf("Name"),   Qt::Horizontal, "姓名");qryModel->setHeaderData(rec.indexOf("Gender"), Qt::Horizontal, "性别");qryModel->setHeaderData(rec.indexOf("Birthday"),   Qt::Horizontal, "出生日期");qryModel->setHeaderData(rec.indexOf("Province"),   Qt::Horizontal, "省份");qryModel->setHeaderData(rec.indexOf("Department"), Qt::Horizontal, "部门");qryModel->setHeaderData(rec.indexOf("Salary"),     Qt::Horizontal, "工资");//3. 创建选择模型selModel=new QItemSelectionModel(qryModel,this);connect(selModel,&QItemSelectionModel::currentRowChanged,this, &MainWindow::do_currentRowChanged);ui->tableView->setModel(qryModel);//4. 创建数据映射dataMapper= new QDataWidgetMapper(this);dataMapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);dataMapper->setModel(qryModel);//界面组件与数据模型的具体字段之间的映射dataMapper->addMapping(ui->dbSpinEmpNo, rec.indexOf("empNo"));dataMapper->addMapping(ui->dbEditName,  rec.indexOf("Name"));dataMapper->addMapping(ui->dbComboSex,  rec.indexOf("Gender"));dataMapper->addMapping(ui->dbEditBirth, rec.indexOf("Birthday"));dataMapper->addMapping(ui->dbComboProvince, rec.indexOf("Province"));dataMapper->addMapping(ui->dbComboDep,      rec.indexOf("Department"));dataMapper->addMapping(ui->dbSpinSalary,    rec.indexOf("Salary"));dataMapper->toFirst();  //移动到首记录

record函数不带参数可以获取字段名称,想要获取对应记录的字段对应值,可以参考以下:

    QSqlRecord rec1=qryModel->record(2);QVariant vr = rec1.value("Name");QString qs = vr.toString();qDebug() << qs;

使用ui->tableView->setSelectionModel(selModel);语句将界面显示与模型绑定在一起。

dataMapper将UI中的一系列界面组件映射到一条记录的不同字段,便设置显示为第一条记录的数据内容。

ui->tableView->setSelectionModel(selModel);设置了选择模型,当选择的行发生改变时候会进入以下槽函数:

void MainWindow::do_currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{Q_UNUSED(previous);if (!current.isValid()){ui->dbLabPhoto->clear();ui->dbEditMemo->clear();return;}dataMapper->setCurrentModelIndex(current);      //设置当前行//    dataMapper->setCurrentIndex(current.row());   //这个也可以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=selModel->currentIndex().row();QSqlRecord  curRec=qryModel->record(curRecNo);  //获取当前记录int empNo=curRec.value("EmpNo").toInt();    //主键字段QSqlQuery query(DB);    //查询某个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());
}

在槽函数中获取当前选择的记录,并设置dataMapper,选择的记录条在其他组件中同步更新,获取该记录的一些数据,然后用一个 QSqlQuery 变量 query 运行查询语句,查询对应EmpNo号对应记录的BLOB类型数据,并转化显示为图片。

记录的移动需要根据 QDataWidgetMapper 对象的当前行设置选择模型的当前行,这样才能使

QTableView组件和数据感知组件的当前行是同步的。


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();
}//刷新tableView的当前行
void MainWindow::refreshTableView()
{int index=dataMapper->currentIndex();   //dataMapper的当前行号QModelIndex curIndex=qryModel->index(index,1);  //为当前行创建模型索引selModel->clearSelection();         //清空选择项selModel->setCurrentIndex(curIndex,QItemSelectionModel::Select);    //设置当前行
}


http://www.ppmy.cn/ops/141624.html

相关文章

OpenAI重磅消息发布12天直播 –实时更新day4

OpenAI提前开启了假期&#xff0c;推出了为期 12 天的活动&#xff0c;名为“OpenAI 12 天”。在接下来的一周左右的每一天&#xff0c;OpenAI 都将发布现有产品的新更新以及新软件&#xff0c;包括备受期待的 Sora AI 视频生成器。 OpenAI 首席执行官 Sam Altman 表示&#x…

数造科技入选 2024 爱分析·数据要素 x 厂商全景报告两大场景

近日&#xff0c;爱分析正式发布《2024 爱分析数据要素厂商全景报告》。数造科技凭借在数据要素领域的卓越技术能力和长期深耕的行业大数据解决方案服务积淀&#xff0c;成功入选为协同制造以及区域协同治理两个细分领域的代表厂商。 一、数据要素引领新时代经济发展 在当今时…

Redis Java 集成到 Spring Boot

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;Redis &#x1f4da;本系列文章为个人学习笔…

【docker】docker添加host操作 dockerfile

一、–add-host docker run 后追加参数--add-hostwww.test.cn:192.168.100.10 二、使用容器卷 docker run -v 宿主机内hosts文件:/etc/hosts 三、dockerfile内设计 思路&#xff1a; &#xff08;1&#xff09;dockerfile entrypoint启动一个shell&#xff0c;在shell内先…

【AI知识】人工智能、机器学习、深度学习的概念与联系

下图来自博客 机器学习和深度学习概念入门 &#xff0c;图中可明显看到人工智能、机器学习、深度学习三个概念的包含关系&#xff0c;下面简单介绍一下这三个概念已经它们之间的联系。 1. 人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09; 概念&#x…

List<T>中提取某个属性值并进行去重

以下是几种在C#中从List<T>提取某个属性值并进行去重的常见方法&#xff0c;这里假设T是一个自定义类&#xff0c;且包含需要提取并去重的属性&#xff0c;示例代码如下&#xff1a; 1. 使用LINQ的Select和Distinct方法&#xff08;推荐&#xff09; 假如有一个类Perso…

Spring Boot接收从前端传过来的数据常用方式以及处理的技巧

Spring Boot接收从前端传过来的数据常用方式以及处理的技巧 一、params 传参 restful风格的请求 二、Body中的form-data 传参三、Body中的raw的json格式 传参 一、params 传参 参数是会拼接到url后面的请求 场景规范&#xff1a;url后面的key值<3个参数的时候&#xff0c…

Java程序员如何深入学习并发编程?

不知道大家今年的金九银十是否有出去面试过&#xff1f;有出去面试的朋友肯定深有感受&#xff0c;像我们刚入行那会面试的加分项现在卷得已经成为了面试的基础题&#xff08;手动狗头&#xff09;。其中最典型的就属这个Java并发编程了。之前一般只有大厂才会有高并发编程相关…