Qt数据库之QTabelModel

news/2024/10/22 11:43:21/

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();
}


http://www.ppmy.cn/news/1217775.html

相关文章

数字三角形模型 笔记

方格取数 走两次的最大值 f[k][i1][i2]来表示 k i1 j1 i2 j2; 每一个状态可由四种状态转换来&#xff0c;分别为 第一条路走下&#xff0c;第二条路走下 第一条路走下&#xff0c;第二条路走右 第一条路走右&#xff0c;第二条路走下 第一条路走右&#xff0c;第二条…

【JVM】类加载器 Bootstrap、Extension、Application、User Define 以及 双亲委派

以下环境为 jdk1.8 两大类 分类成员语言继承关系引导类加载器bootstrap 引导类加载器C/C无自定义类加载器extension 拓展类加载器、application 系统/应用类加载器、user define 用户自定义类加载器Java继承于 java.lang.ClassLoader 四小类 Bootstrap 引导类加载器 负责加…

自动化之python面试

一.基础数据类型的划分 可变/不可变&#xff1a; 可变&#xff1a;列表、集合、字典&#xff08;可以进行更改&#xff0c;并且更改后物理地址不会发生改变&#xff09; 不可变的&#xff1a;数字、字符串、元组&#xff08;不可以进行更改&#xff0c;更改后就是一个新的对象…

【nlp】2.5 人名分类器实战项目(对比RNN、LSTM、GRU模型)

人名分类器实战项目 0 项目说明1 案例介绍2 案例步骤2.1 导入必备的工具包2.2 数据预处理2.2.1 获取常用的字符数量2.2.2 国家名种类数和个数2.2.3 读数据到python环境中2.2.4 构建数据源NameClassDataset2.2.5 构建迭代器遍历数据2.3 构建RNN及其变体模型2.3.1 构建RNN模型2.3…

viple模拟器使用(一):线控模拟

(1)unity模拟器 通过viple程序&#xff0c;将viple编写逻辑运行在unity模拟器中。 首先编写viple程序&#xff0c;逻辑&#xff1a;设置一个机器人主机&#xff0c;并且&#xff0c;按↑、↓、←、→方向键的时候&#xff0c;能分别控制模拟机器人在unity模拟器中运行。 主机…

BUUCTF刷题十一道【缺】(10)

文章目录 EasyBypass[SCTF2019]Flag Shop[BSidesCF 2019]SVGMagic[极客大挑战 2020]Greatphp[GYCTF2020]Easyphp【留坑-反序列化】[HarekazeCTF2019]Avatar Uploader 1[FireshellCTF2020]Caas[ISITDTU 2019]EasyPHP[N1CTF 2018]eating_cms[GYCTF2020]Ez_Express【留坑-nodejs原…

HG/T 6002-2022 氟树脂粉末涂料检测

氟树脂粉末涂料是指以三氟氯乙烯-乙烯基醚、四氟乙烯-乙烯基醚等交联型氟树脂或聚偏二氟乙烯PVDF树脂为主要成膜物质&#xff0c;可加入颜料、填料、助剂、固化剂等制成的粉末涂料&#xff0c;主要用于铝型材、幕墙金属板、家电等表面的装饰和保护。 HG/T 6002-2022 氟树脂粉末…

SSH全能终端工具mobaXterm(远程工具)使用教程

参考文章&#xff1a;SSH全能终端工具MobaXterm Personal v23.0 完全汉化绿色版 参考文章&#xff1a;MobaXterm 23终端控制软件 文章目录 SSH全能终端工具mobaXterm使用教程目录引言mobaXterm概述安装与配置下载mobaXterm安装过程基础设置 SSH连接创建SSH会话SSH命令行操作文…