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

打印 上一主题 下一主题

主题 861|帖子 861|积分 2583

本文记载利用QSqlTableModel等组件实现单表的数据库操作。
   QSqlTableModel是一个模型类,它的实例可以作为一个数据表的模型。利用QSqlTableModel模型和QTableView组件构成模型/视图布局,就可以实现数据表的数据表现和编辑。
  目次
所需的类及界说
表格控件设置QTableView
打开数据库毗连db.open()
表设置初始化、表查询
设置表名
设置表排序字段
打开表-查询
表现行数
设置表格的程度字段标题
创建选择模型
绑定数据模型 和 选择模型
绑定之后,将图片列和备注列在表格中不表现
绑定自界说下拉框到部分列、性别列
创建界面组件与数据模型字段之间的数据映射
界说数据映射组件
设置界面组件和模型字段之间的映射
移动到首记载,将首行的记载赋值给绑定的控件
表插入
表追加一行
表操作撤销
表操作提交
表记载删除
表排序切换
表条件过滤及过滤条件清空
逐行修改数据并提交
BLOB字段的保存、清空、表现图片
表事件处理
单元格值发生变革处理事件
焦点行发生变换
表其他操作
获取程度列名


所需的类及界说

解释
数据库毗连QSqlDatabase
表现控件QTableView
Model视图QSqlTableModel
选择ModelQItemSelectionModel
字段编辑绑定QDataWidgetMapper
自界说combox代理控件TComboBoxDelegate
性别字符列表genderList
部分字符列表deptList
省份字符列表provinceList
  1.     QSqlDatabase DB;
  2.     QSqlTableModel *tabModel;
  3.     QItemSelectionModel *selModel;
  4.     QDataWidgetMapper *dataMapper;//数据映射
  5.     TComboBoxDelegate delegateSex;
  6.     TComboBoxDelegate delegateDept;
  7.     QStringList genderList;
  8.     QStringList deptList;
  9.     QStringList provinceList;
复制代码
表格控件设置QTableView

行背景交替颜色、单个单元格选择模式
  1.     ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
  2.     ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
  3.     ui->tableView->setAlternatingRowColors(true);
复制代码
打开数据库毗连db.open()

打开SQLite数据库
  1. bool SqlTableModelExample::openDataBase(QString aFile)
  2. {
  3.     DB = QSqlDatabase::addDatabase("QSQLITE");//添加SQLite驱动
  4.     DB.setDatabaseName(aFile);//设置数据库名称
  5.     if(!DB.open())//打开数据库
  6.     {
  7.         QMessageBox::warning(this, "错误", "打开数据库失败");
  8.         return false;
  9.     }
  10.     else
  11.     {
  12.         openTable();
  13.         return true;
  14.     }
  15. }
复制代码
表设置初始化、表查询

设置表名

  1. tabModel = new QSqlTableModel(this,DB);
  2. tabModel->setTable("employee");
复制代码
设置表排序字段

  1. tabModel->setSort(tabModel->fieldIndex("empNo"),Qt::AscendingOrder);
复制代码
打开表-查询

  1. if(!tabModel->select())
  2.     {
  3.         //MessageBoxHelper::critical(this,"打开数据表错误,错误信息:\n"+tabModel->lastError().text());
  4.         QMessageBox::critical(this,"错误信息","打开数据表错误,错误信息:\n"+tabModel->lastError().text());
  5.         return;
  6.     }
复制代码
表现行数

  1. void SqlTableModelExample::showRecordCount()
  2. {
  3.     ui->statusbar->showMessage(QString("记录条数:%1").arg(tabModel->rowCount()));
  4. }
复制代码
设置表格的程度字段标题

  1. tabModel->setHeaderData(tabModel->fieldIndex("empNo"),Qt::Horizontal,"工号");
  2.     tabModel->setHeaderData(tabModel->fieldIndex("Name"),Qt::Horizontal,"姓名");
  3.     tabModel->setHeaderData(tabModel->fieldIndex("Gender"),Qt::Horizontal,"性别");
  4.     tabModel->setHeaderData(tabModel->fieldIndex("Birthday"),Qt::Horizontal,"出生日期");
  5.     tabModel->setHeaderData(tabModel->fieldIndex("Province"),Qt::Horizontal,"省份");
  6.     tabModel->setHeaderData(tabModel->fieldIndex("Department"),Qt::Horizontal,"部门");
  7.     tabModel->setHeaderData(tabModel->fieldIndex("Salary"),Qt::Horizontal,"薪水");
  8.     //不在列表tabView中显示
  9.     tabModel->setHeaderData(tabModel->fieldIndex("Memo"),Qt::Horizontal,"备注");
  10.     tabModel->setHeaderData(tabModel->fieldIndex("Photo"),Qt::Horizontal,"照片");
复制代码
创建选择模型

  1. selModel = new QItemSelectionModel(tabModel,this);
复制代码
将选择模型的单元格值变革事件、行变革/切换 绑定到处理方法
如单元格值发生变革,将保存、撤销操作按钮变亮;行切换时,绑定的表现控件表现对应行的值
  1.     connect(selModel,&QItemSelectionModel::currentChanged,this,&SqlTableModelExample::do_currentChanged);
  2.     connect(selModel,&QItemSelectionModel::currentRowChanged,this,&SqlTableModelExample::do_currentRowChanged);
复制代码
绑定数据模型 和 选择模型

  1.     ui->tableView->setModel(tabModel);
  2.     ui->tableView->setSelectionModel(selModel);
复制代码
绑定之后,将图片列和备注列在表格中不表现

  1.     ui->tableView->setColumnHidden(tabModel->fieldIndex("Memo"),true);
  2.     ui->tableView->setColumnHidden(tabModel->fieldIndex("Photo"),true);
复制代码
绑定自界说下拉框到部分列、性别列

  1. bool isEditable = false;
  2.     delegateSex.setItems(genderList,isEditable);
  3.     ui->tableView->setItemDelegateForColumn(tabModel->fieldIndex("Gender"),&delegateSex);
  4.     isEditable = true;
  5.     delegateDept.setItems(deptList,isEditable);
  6.     ui->tableView->setItemDelegateForColumn(tabModel->fieldIndex("Department"),&delegateDept);
复制代码
创建界面组件与数据模型字段之间的数据映射

界说数据映射组件

  1.     dataMapper = new QDataWidgetMapper(this);
  2.     dataMapper->setModel(tabModel);
  3.     dataMapper->setModel(tabModel);   
  4.     dataMapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit); //自动提交
复制代码
设置界面组件和模型字段之间的映射

  1.     dataMapper->addMapping(ui->dbSpinEmpNo,tabModel->fieldIndex("empNo"));
  2.     dataMapper->addMapping(ui->dbEditName,tabModel->fieldIndex("Name"));
  3.     dataMapper->addMapping(ui->dbComboSex,tabModel->fieldIndex("Gender"));
  4.     dataMapper->addMapping(ui->dbEditBirth,tabModel->fieldIndex("Birthday"));
  5.     dataMapper->addMapping(ui->dbComboProvince,tabModel->fieldIndex("Province"));
  6.     dataMapper->addMapping(ui->dbComboDept,tabModel->fieldIndex("Department"));
  7.     dataMapper->addMapping(ui->dbSpinSalary,tabModel->fieldIndex("Salary"));
  8.     dataMapper->addMapping(ui->dbEditMemo,tabModel->fieldIndex("Memo"));
复制代码
移动到首记载,将首行的记载赋值给绑定的控件

  1. dataMapper->toFirst();
复制代码
表插入

  1. void SqlTableModelExample::on_actRecInsert_triggered()
  2. {
  3.     QModelIndex curIndex = ui->tableView->currentIndex();
  4.     QSqlRecord rec = tabModel->record();//获取一个空记录,只有字段定义
  5.     tabModel->insertRecord(curIndex.row(),rec);
  6.     selModel->clearSelection();
  7.     selModel->setCurrentIndex(curIndex,QItemSelectionModel::Select);
  8.     showRecordCount();
  9. }
复制代码
表追加一行

  1. void SqlTableModelExample::on_actRecAppend_triggered()
  2. {
  3.     QSqlRecord rec = tabModel->record();//获取一个空记录
  4.     rec.setValue(tabModel->fieldIndex("empNo"),2000+tabModel->rowCount());
  5.     rec.setValue(tabModel->fieldIndex("Gender"),"男");
  6.     tabModel->insertRecord(tabModel->rowCount(),rec);//插入到数据模型的最后
  7.     selModel->clearSelection();
  8.     QModelIndex curIndex = tabModel->index(tabModel->rowCount()-1,1);
  9.     selModel->setCurrentIndex(curIndex,QItemSelectionModel::Select);
  10.     showRecordCount();
  11. }
复制代码
表操作撤销

  1. void SqlTableModelExample::on_actRevert_triggered()
  2. {
  3.     tabModel->revertAll();
  4.     ui->actSubmit->setEnabled(false);
  5.     ui->actRevert->setEnabled(false);
  6.     showRecordCount();
  7. }
复制代码
表操作提交

  1. void SqlTableModelExample::on_actSubmit_triggered()
  2. {
  3.     bool res = tabModel->submitAll();
  4.     if(!res)
  5.     {
  6.         QMessageBox::critical(this,"错误提示","数据保存错误,错误信息:"+tabModel->lastError().text());
  7.         return;
  8.     }
  9.     else
  10.     {
  11.         ui->actSubmit->setEnabled(false);
  12.         ui->actRevert->setEnabled(false);
  13.     }
  14.     showRecordCount();
  15. }
复制代码
表记载删除

  1. void SqlTableModelExample::on_actRecDelete_triggered()
  2. {
  3.     QModelIndex curIndex = selModel->currentIndex();
  4.     tabModel->removeRow(curIndex.row());
  5.     showRecordCount();
  6. }
复制代码
表排序切换

  1. void SqlTableModelExample::on_radioBtnDescend_clicked()
  2. {
  3.     tabModel->setSort(ui->comboFields->currentIndex(),Qt::DescendingOrder);
  4.     //tabModel->setSort(ui->comboFields->currentIndex(),Qt::AscendingOrder);
  5.     tabModel->select();//执行刷新 才会显示排序
  6. }
复制代码
  1. //切换成别的字段排序
  2. void SqlTableModelExample::on_comboFields_currentIndexChanged(int index)
  3. {
  4.     if(ui->radioBtnAescend->isChecked())
  5.         tabModel->setSort(index,Qt::AscendingOrder);
  6.     else
  7.         tabModel->setSort(index,Qt::DescendingOrder);
  8.     tabModel->select();
  9. }
复制代码
表条件过滤及过滤条件清空

  1. void SqlTableModelExample::on_radioBtnMan_clicked()
  2. {
  3.     tabModel->setFilter(" Gender='男");
  4.     showRecordCount();
  5. }
复制代码
  1. void SqlTableModelExample::on_radioBtnBoth_clicked()
  2. {
  3.     tabModel->setFilter("");
  4.     showRecordCount();
  5. }
复制代码
逐行修改数据并提交

  1. void SqlTableModelExample::on_actScan_triggered()
  2. {
  3.     if(tabModel->rowCount()==0)
  4.         return;
  5.     for(int i=0;i<tabModel->rowCount();i++)
  6.     {
  7.         QSqlRecord rec = tabModel->record(i);
  8.         float salary = rec.value("Salary").toFloat();
  9.         rec.setValue("Salary",salary*1.1);
  10.         tabModel->setRecord(i,rec);
  11.     }
  12.     if(tabModel->submitAll())
  13.         QMessageBox::information(this,"提示","计算完毕");
  14. }
复制代码
BLOB字段的保存、清空、表现图片

  1. void SqlTableModelExample::on_actPhoto_triggered()
  2. {
  3.     QString aFile = QFileDialog::getOpenFileName(this,"选择图片文件","","照片(*.jpg)");
  4.     if(aFile.isEmpty())
  5.         return;
  6.     QByteArray data;
  7.     QFile *file = new QFile(aFile);
  8.     file->open(QIODevice::ReadOnly);
  9.     data = file->readAll();
  10.     file->close();
  11.     delete file;
  12.     int curRecNo = selModel->currentIndex().row();
  13.     QSqlRecord curRec= tabModel->record(curRecNo);
  14.     curRec.setValue("Photo",data);
  15.     tabModel->setRecord(curRecNo,curRec);
  16.     QPixmap pic;
  17.     pic.load(aFile);
  18.     ui->dbLabPhoto->setPixmap(pic.scaledToWidth(ui->dbLabPhoto->size().width()));;
  19. }
复制代码
通过tableModel.SubmitAll() 提交

表事件处理

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

判断是否更改 isDirty()方法
  1. //数据发生更改的时候,更新actPost 和 actCancel的状态
  2. void SqlTableModelExample::do_currentChanged(const QModelIndex &current, const QModelIndex &previous)
  3. {
  4.     Q_UNUSED(current);
  5.     Q_UNUSED(previous);
  6.     ui->actSubmit->setEnabled(tabModel->isDirty());
  7.     ui->actRevert->setEnabled(tabModel->isDirty());
  8. }
复制代码
焦点行发生变换

切换dataMapper
  1. void SqlTableModelExample::do_currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
  2. {
  3.     Q_UNUSED(previous);
  4.     ui->actRecDelete->setEnabled(current.isValid());
  5.     ui->actPhoto->setEnabled(current.isValid());
  6.     ui->actPhotoClear->setEnabled(current.isValid());
  7.     if(!current.isValid())
  8.     {
  9.         ui->dbLabPhoto->clear();
  10.         return;
  11.     }
  12.     int curRecNo = current.row();
  13.     dataMapper->setCurrentIndex(curRecNo);
  14.     QSqlRecord curRec = tabModel->record(curRecNo);//获取当前记录
  15.     if(curRec.isNull("Photo"))
  16.         ui->dbLabPhoto->clear();
  17.     else
  18.     {
  19.         QByteArray data =curRec.value("Photo").toByteArray();
  20.         QPixmap pic;
  21.         pic.loadFromData(data);
  22.         ui->dbLabPhoto->setPixmap(pic.scaledToWidth(ui->dbLabPhoto->size().width()));
  23.     }
  24. }
复制代码

表其他操作

获取程度列名

  1. void SqlTableModelExample::getFieldNames()
  2. {
  3.     QSqlRecord emptyRec = tabModel->record();
  4.     for(int i=0;i<emptyRec.count();i++)
  5.     {
  6.         qDebug()<<emptyRec.count();
  7.         ui->comboFields->addItem(emptyRec.fieldName(i));
  8.     }
  9. }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

郭卫东

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表