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

本文记录使用QSqlTableModel等组件实现单表的数据库操作。

QSqlTableModel是一个模型类,它的实例可以作为一个数据表的模型。使用QSqlTableModel模型和QTableView组件构成模型/视图结构,就可以实现数据表的数据显示和编辑。

目录

所需的类及定义

表格控件设置QTableView

打开数据库连接db.open()

表设置初始化、表查询

设置表名

设置表排序字段

打开表-查询

显示行数

设置表格的水平字段标题

创建选择模型

绑定数据模型 和 选择模型

绑定之后,将图片列和备注列在表格中不显示

绑定自定义下拉框到部门列、性别列

创建界面组件与数据模型字段之间的数据映射

定义数据映射组件

设置界面组件和模型字段之间的映射

移动到首记录,将首行的记录赋值给绑定的控件

表插入

表追加一行

表操作撤销

表操作提交

表记录删除

表排序切换

表条件过滤及过滤条件清空

逐行修改数据并提交

BLOB字段的保存、清空、显示图片

表事件处理

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

焦点行发生变换

表其他操作

获取水平列名


所需的类及定义

解释
数据库连接QSqlDatabase
显示控件QTableView
Model视图QSqlTableModel
选择ModelQItemSelectionModel
字段编辑绑定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"));

移动到首记录,将首行的记录赋值给绑定的控件

dataMapper->toFirst();

表插入

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 &current, 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 &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;
    }
    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));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

castlooo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值