本文记载利用QSqlTableModel等组件实现单表的数据库操作。
QSqlTableModel是一个模型类,它的实例可以作为一个数据表的模型。利用QSqlTableModel模型和QTableView组件构成模型/视图布局,就可以实现数据表的数据表现和编辑。
目次
所需的类及界说
表格控件设置QTableView
打开数据库毗连db.open()
表设置初始化、表查询
设置表名
设置表排序字段
打开表-查询
表现行数
设置表格的程度字段标题
创建选择模型
绑定数据模型 和 选择模型
绑定之后,将图片列和备注列在表格中不表现
绑定自界说下拉框到部分列、性别列
创建界面组件与数据模型字段之间的数据映射
界说数据映射组件
设置界面组件和模型字段之间的映射
移动到首记载,将首行的记载赋值给绑定的控件
表插入
表追加一行
表操作撤销
表操作提交
表记载删除
表排序切换
表条件过滤及过滤条件清空
逐行修改数据并提交
BLOB字段的保存、清空、表现图片
表事件处理
单元格值发生变革处理事件
焦点行发生变换
表其他操作
获取程度列名
所需的类及界说
解释 | 类 | 数据库毗连 | QSqlDatabase | 表现控件 | QTableView | Model视图 | QSqlTableModel | 选择Model | QItemSelectionModel | 字段编辑绑定 | QDataWidgetMapper | 自界说combox代理控件 | TComboBoxDelegate | 性别字符列表 | genderList | 部分字符列表 | deptList | 省份字符列表 | provinceList |
- QSqlDatabase DB;
- QSqlTableModel *tabModel;
- QItemSelectionModel *selModel;
- QDataWidgetMapper *dataMapper;//数据映射
- TComboBoxDelegate delegateSex;
- TComboBoxDelegate delegateDept;
- QStringList genderList;
- QStringList deptList;
- QStringList provinceList;
复制代码 表格控件设置QTableView
行背景交替颜色、单个单元格选择模式
- ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
- ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
- ui->tableView->setAlternatingRowColors(true);
复制代码 打开数据库毗连db.open()
打开SQLite数据库
- bool SqlTableModelExample::openDataBase(QString aFile)
- {
- DB = QSqlDatabase::addDatabase("QSQLITE");//添加SQLite驱动
- DB.setDatabaseName(aFile);//设置数据库名称
- if(!DB.open())//打开数据库
- {
- QMessageBox::warning(this, "错误", "打开数据库失败");
- return false;
- }
- else
- {
- openTable();
- return true;
- }
- }
复制代码 表设置初始化、表查询
设置表名
- tabModel = new QSqlTableModel(this,DB);
- tabModel->setTable("employee");
复制代码 设置表排序字段
- tabModel->setSort(tabModel->fieldIndex("empNo"),Qt::AscendingOrder);
复制代码 打开表-查询
- if(!tabModel->select())
- {
- //MessageBoxHelper::critical(this,"打开数据表错误,错误信息:\n"+tabModel->lastError().text());
- QMessageBox::critical(this,"错误信息","打开数据表错误,错误信息:\n"+tabModel->lastError().text());
- return;
- }
复制代码 表现行数
- void SqlTableModelExample::showRecordCount()
- {
- ui->statusbar->showMessage(QString("记录条数:%1").arg(tabModel->rowCount()));
- }
复制代码 设置表格的程度字段标题
- 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("Birthday"),Qt::Horizontal,"出生日期");
- tabModel->setHeaderData(tabModel->fieldIndex("Province"),Qt::Horizontal,"省份");
- tabModel->setHeaderData(tabModel->fieldIndex("Department"),Qt::Horizontal,"部门");
- tabModel->setHeaderData(tabModel->fieldIndex("Salary"),Qt::Horizontal,"薪水");
- //不在列表tabView中显示
- tabModel->setHeaderData(tabModel->fieldIndex("Memo"),Qt::Horizontal,"备注");
- tabModel->setHeaderData(tabModel->fieldIndex("Photo"),Qt::Horizontal,"照片");
复制代码 创建选择模型
- selModel = new QItemSelectionModel(tabModel,this);
复制代码 将选择模型的单元格值变革事件、行变革/切换 绑定到处理方法
如单元格值发生变革,将保存、撤销操作按钮变亮;行切换时,绑定的表现控件表现对应行的值
- connect(selModel,&QItemSelectionModel::currentChanged,this,&SqlTableModelExample::do_currentChanged);
- connect(selModel,&QItemSelectionModel::currentRowChanged,this,&SqlTableModelExample::do_currentRowChanged);
复制代码 绑定数据模型 和 选择模型
- ui->tableView->setModel(tabModel);
- ui->tableView->setSelectionModel(selModel);
复制代码 绑定之后,将图片列和备注列在表格中不表现
- ui->tableView->setColumnHidden(tabModel->fieldIndex("Memo"),true);
- ui->tableView->setColumnHidden(tabModel->fieldIndex("Photo"),true);
复制代码 绑定自界说下拉框到部分列、性别列
- bool isEditable = false;
- delegateSex.setItems(genderList,isEditable);
- ui->tableView->setItemDelegateForColumn(tabModel->fieldIndex("Gender"),&delegateSex);
- isEditable = true;
- delegateDept.setItems(deptList,isEditable);
- ui->tableView->setItemDelegateForColumn(tabModel->fieldIndex("Department"),&delegateDept);
复制代码 创建界面组件与数据模型字段之间的数据映射
界说数据映射组件
- dataMapper = new QDataWidgetMapper(this);
- dataMapper->setModel(tabModel);
- dataMapper->setModel(tabModel);
- dataMapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit); //自动提交
复制代码 设置界面组件和模型字段之间的映射
- dataMapper->addMapping(ui->dbSpinEmpNo,tabModel->fieldIndex("empNo"));
- dataMapper->addMapping(ui->dbEditName,tabModel->fieldIndex("Name"));
- dataMapper->addMapping(ui->dbComboSex,tabModel->fieldIndex("Gender"));
- dataMapper->addMapping(ui->dbEditBirth,tabModel->fieldIndex("Birthday"));
- dataMapper->addMapping(ui->dbComboProvince,tabModel->fieldIndex("Province"));
- dataMapper->addMapping(ui->dbComboDept,tabModel->fieldIndex("Department"));
- dataMapper->addMapping(ui->dbSpinSalary,tabModel->fieldIndex("Salary"));
- dataMapper->addMapping(ui->dbEditMemo,tabModel->fieldIndex("Memo"));
复制代码 移动到首记载,将首行的记载赋值给绑定的控件
表插入
- void SqlTableModelExample::on_actRecInsert_triggered()
- {
- QModelIndex curIndex = ui->tableView->currentIndex();
- QSqlRecord rec = tabModel->record();//获取一个空记录,只有字段定义
- tabModel->insertRecord(curIndex.row(),rec);
- selModel->clearSelection();
- selModel->setCurrentIndex(curIndex,QItemSelectionModel::Select);
- showRecordCount();
- }
复制代码 表追加一行
- void SqlTableModelExample::on_actRecAppend_triggered()
- {
- QSqlRecord rec = tabModel->record();//获取一个空记录
- rec.setValue(tabModel->fieldIndex("empNo"),2000+tabModel->rowCount());
- rec.setValue(tabModel->fieldIndex("Gender"),"男");
- tabModel->insertRecord(tabModel->rowCount(),rec);//插入到数据模型的最后
- selModel->clearSelection();
- QModelIndex curIndex = tabModel->index(tabModel->rowCount()-1,1);
- selModel->setCurrentIndex(curIndex,QItemSelectionModel::Select);
- showRecordCount();
- }
复制代码 表操作撤销
- void SqlTableModelExample::on_actRevert_triggered()
- {
- tabModel->revertAll();
- ui->actSubmit->setEnabled(false);
- ui->actRevert->setEnabled(false);
- showRecordCount();
- }
复制代码 表操作提交
- void SqlTableModelExample::on_actSubmit_triggered()
- {
- bool res = tabModel->submitAll();
- if(!res)
- {
- QMessageBox::critical(this,"错误提示","数据保存错误,错误信息:"+tabModel->lastError().text());
- return;
- }
- else
- {
- ui->actSubmit->setEnabled(false);
- ui->actRevert->setEnabled(false);
- }
- showRecordCount();
- }
复制代码 表记载删除
- void SqlTableModelExample::on_actRecDelete_triggered()
- {
- QModelIndex curIndex = selModel->currentIndex();
- tabModel->removeRow(curIndex.row());
- showRecordCount();
- }
复制代码 表排序切换
- void SqlTableModelExample::on_radioBtnDescend_clicked()
- {
- tabModel->setSort(ui->comboFields->currentIndex(),Qt::DescendingOrder);
- //tabModel->setSort(ui->comboFields->currentIndex(),Qt::AscendingOrder);
- tabModel->select();//执行刷新 才会显示排序
- }
复制代码- //切换成别的字段排序
- void SqlTableModelExample::on_comboFields_currentIndexChanged(int index)
- {
- if(ui->radioBtnAescend->isChecked())
- tabModel->setSort(index,Qt::AscendingOrder);
- else
- tabModel->setSort(index,Qt::DescendingOrder);
- tabModel->select();
- }
复制代码 表条件过滤及过滤条件清空
- void SqlTableModelExample::on_radioBtnMan_clicked()
- {
- tabModel->setFilter(" Gender='男");
- showRecordCount();
- }
复制代码- void SqlTableModelExample::on_radioBtnBoth_clicked()
- {
- tabModel->setFilter("");
- showRecordCount();
- }
复制代码 逐行修改数据并提交
- void SqlTableModelExample::on_actScan_triggered()
- {
- if(tabModel->rowCount()==0)
- return;
- for(int i=0;i<tabModel->rowCount();i++)
- {
- QSqlRecord rec = tabModel->record(i);
- float salary = rec.value("Salary").toFloat();
- rec.setValue("Salary",salary*1.1);
- tabModel->setRecord(i,rec);
- }
- if(tabModel->submitAll())
- QMessageBox::information(this,"提示","计算完毕");
- }
复制代码 BLOB字段的保存、清空、表现图片
- void SqlTableModelExample::on_actPhoto_triggered()
- {
- QString aFile = QFileDialog::getOpenFileName(this,"选择图片文件","","照片(*.jpg)");
- if(aFile.isEmpty())
- return;
- QByteArray data;
- QFile *file = new QFile(aFile);
- file->open(QIODevice::ReadOnly);
- data = file->readAll();
- file->close();
- delete file;
- int curRecNo = selModel->currentIndex().row();
- QSqlRecord curRec= tabModel->record(curRecNo);
- curRec.setValue("Photo",data);
- tabModel->setRecord(curRecNo,curRec);
- QPixmap pic;
- pic.load(aFile);
- ui->dbLabPhoto->setPixmap(pic.scaledToWidth(ui->dbLabPhoto->size().width()));;
- }
复制代码 通过tableModel.SubmitAll() 提交
表事件处理
单元格值发生变革处理事件
判断是否更改 isDirty()方法
- //数据发生更改的时候,更新actPost 和 actCancel的状态
- void SqlTableModelExample::do_currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
- {
- Q_UNUSED(current);
- Q_UNUSED(previous);
- ui->actSubmit->setEnabled(tabModel->isDirty());
- ui->actRevert->setEnabled(tabModel->isDirty());
- }
复制代码 焦点行发生变换
切换dataMapper
- void SqlTableModelExample::do_currentRowChanged(const QModelIndex ¤t, 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;
- }
- int curRecNo = current.row();
- dataMapper->setCurrentIndex(curRecNo);
- 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()));
- }
- }
复制代码
表其他操作
获取程度列名
- void SqlTableModelExample::getFieldNames()
- {
- QSqlRecord emptyRec = tabModel->record();
- for(int i=0;i<emptyRec.count();i++)
- {
- qDebug()<<emptyRec.count();
- ui->comboFields->addItem(emptyRec.fieldName(i));
- }
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |