使用场景:你有一个db,你想将db中某张表的数据显示到界面上,用户可以在界面进行增删改查。
这时候我们使用QSqlTableModel+QTableView的组合完成需求。
现在你有一个book.db,里面有一张book表长这样。
首先我们要做的是打开db
//头文件中声明
QSqlTableModel *pSqlTableModel=nullptr;
QSqlDatabase DB;//数据库连接
bool MainWindow::createConnection()
{
DB = QSqlDatabase::addDatabase("QSQLITE");//添加QSQLITE数据库驱动
DB.setDatabaseName("./book.db");//设置数据库名称
if (!DB.open())//打开数据库
{
OutputDebugStringA("db open fail");
QMessageBox::warning(nullptr, "错误", "打开数据库失败",
QMessageBox::Ok,QMessageBox::NoButton);
return false;
}
return true;
}
构造函数中要设置tableView显示属性, new QSqlTableModel并与tableView绑定,这里使用setModel
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setWindowTitle("图书管理系统");
//设置选择模式
ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
//Selecting single items.
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
//自动调整该部分的大小以填充可用空间。
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
//在具有交替行颜色的视图中用作备用背景颜色
ui->tableView->setAlternatingRowColors( true );
createConnection();
pSqlTableModel = new QSqlTableModel(this,DB);
//在调用 submitAll() 或 revertAll() 之前,所有更改都将缓存在模型中
pSqlTableModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
//设置要呈现的视图的模型。
ui->tableView->setModel(pSqlTableModel);
}
查询功能
查询书籍,根据书名进行模糊查询并按价格降序排序 ,显示时将db列名对应成中文
自己写sql语句是这样的:QString sql=QString(“select * from book where book_name LIKE’%%1%’ order by price desc”).arg(bookName); 这里的bookName=“c";
void MainWindow::on_btn_searchBook_clicked()
{
QString bookName=ui->lineEdit_bookName->text();
pSqlTableModel->setTable("book");//设置表名
pSqlTableModel->setFilter(QString("book_name LIKE'%%1%'").arg(bookName));//相当于where条件
pSqlTableModel->setSort(pSqlTableModel->fieldIndex("price"),Qt::DescendingOrder);//排序
pSqlTableModel->select();//开始查询
setHeaderName(pSqlTableModel,"book");//表头显示中文
}
//db显示时列名对应中文
void MainWindow::setHeaderName(QSqlTableModel *pSqlTableModel,QString tableName)
{
if(tableName=="book")
{
pSqlTableModel->setHeaderData(pSqlTableModel->fieldIndex("book_id"),Qt::Horizontal,"编号");
pSqlTableModel->setHeaderData(pSqlTableModel->fieldIndex("book_name"),Qt::Horizontal,"书名");
pSqlTableModel->setHeaderData(pSqlTableModel->fieldIndex("author_name"),Qt::Horizontal,"作者");
pSqlTableModel->setHeaderData(pSqlTableModel->fieldIndex("press_name"),Qt::Horizontal,"出版社");
pSqlTableModel->setHeaderData(pSqlTableModel->fieldIndex("price"),Qt::Horizontal,"价格");
pSqlTableModel->setHeaderData(pSqlTableModel->fieldIndex("storage"),Qt::Horizontal,"库存");
pSqlTableModel->setHeaderData(pSqlTableModel->fieldIndex("total"),Qt::Horizontal,"总数");
pSqlTableModel->setHeaderData(pSqlTableModel->fieldIndex("UpdateTime"),Qt::Horizontal,"更新时间");
}
}
查询结果显示:
在没有界面显示的情况下判断是否查询到数据:pSqlTableModel->rowCount()是否=0;
新增一行
void MainWindow::on_btn_add_clicked()
{
//获取表的行数
int row = pSqlTableModel->rowCount();
//添加一行
pSqlTableModel->insertRow(row);
}
移除选中的一行
void MainWindow::on_btn_delete_clicked()
{
//获取选中的行
int curRow = ui->tableView->currentIndex().row();
//删除该行
pSqlTableModel->removeRow(curRow);
int ret = QMessageBox::warning(this, tr("删除当前行"), tr("你确定要删除该行吗"), QMessageBox::Yes | QMessageBox::No);
if (ret == QMessageBox::Yes)
{
//确认删除该行 提交到数据库
pSqlTableModel->database().transaction();//开启事务
if(pSqlTableModel->submitAll())
{
pSqlTableModel->database().commit();
}
else
{
//对于某些数据库,当在数据库上有活动查询正在执行,那么事务提交会失败并返回false。在事务提交之前应使查询失效。
pSqlTableModel->database().rollback();
QMessageBox::warning(this, tr("提示"), tr("数据库错误: %1").arg(pSqlTableModel->lastError().text()));
}
}
else
{
//不删除 撤销操作
pSqlTableModel->revertAll();
}
}
提交修改
void MainWindow::on_btn_commit_clicked()
{
//开启事务
pSqlTableModel->database().transaction();
if (pSqlTableModel->submitAll())
{
OutputDebugStringA("submitAll()");
//提交事务
pSqlTableModel->database().commit();
}
else
{
//回滚事务
pSqlTableModel->database().rollback();
QMessageBox::warning(this, tr("TableView"), tr("数据库错误: %1").arg(pSqlTableModel->lastError().text()));
}
}
撤销修改
void MainWindow::on_btn_cancel_clicked()
{
pSqlTableModel->revertAll();
}
更新数据
void MainWindow::on_actScan_triggered()
{//涨工资,记录遍历
if (tabModel->rowCount()==0)
return;
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);
}
// 索引方式刷新记录,速度一样
// float salary;
// for (int i=0;irowCount();i++)
// {
// salary=tabModel->data(tabModel->index(i,10)).toFloat();
// salary=salary*1.1;
// tabModel->setData(tabModel->index(i,10),salary);
// }
if (tabModel->submitAll())
QMessageBox::information(this, "消息", "涨工资计算完毕",
QMessageBox::Ok,QMessageBox::NoButton);
}