[Qt教程] 第25篇 数据库(五)SQL表格模型QSqlTableModel

楼主

 发表于 2013-5-21 20:36:22 | 查看: 923| 回复: 7
SQL表格模型QSqlTableModel
版权声明

该文章原创于作者yafeilinux,转载请注明出处!
导语

在上一篇我们讲到只读的QsqlQueryModel模型其实也可以实现编辑功能的,但是实现起来很麻烦。而QSqlTableModel提供了一个一次只能操作单个SQL表的读写模型,它是QSqlQuery的更高层次的替代品,可以浏览和修改独立的SQL表,并且只需编写很少的代码,而且不需要了解SQL语法。
环境:Windows Xp + Qt 4.8.4+QtCreator 2.6.2
目录

一、创建数据库
二、修改操作
三、查询操作
四、排序操作
五、删除操作
六、插入操作
正文

一、创建数据库
1.新建Qt Gui应用,项目名称为tableModel,基类QMainWindow,类名MainWindow。
2.完成后打开tableModel.pro文件,将第一行代码更改为:
QT       += coregui sql
然后保存文件。
3.向项目中添加新的C++头文件,名称为connection.h。完成后将其内容更改如下:
#ifndef CONNECTION_H
#define CONNECTION_H
#include <QSqlDatabase>
#include <QSqlQuery>
static bool createConnection()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("database.db");
    if(!db.open()) return false;
    QSqlQuery query;
    query.exec(QString(
      "create tablestudent (id int primary key, name vchar)"));
    query.exec(QString("insert into student values (0,'刘明')"));
    query.exec(QString("insert into student values (1,'陈刚')"));
    query.exec(QString("insert into student values (2,'王红')"));
    return true;
}
#endif // CONNECTION_H
这里因为语句中使用了中文,所以使用了QString()进行编码转换,这个还需要在main()函数中设置编码。
4.下面将main.cpp文件更改如下:
#include "mainwindow.h"
#include <QApplication>
#include "connection.h"
#include <QTextCodec>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));

    QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
    if(!createConnection())
       return 1;
    MainWindow w;
    w.show();
   
    return a.exec();
}
    这里的setCodecForCStrings()就是用来设置字符串编码的。
5.下面进入设计模式,向窗口上拖入Label、Push Button、Line Edit和Table View等部件,进行界面设计,效果如下图所示。
6.完成后到mainwindow.h文件中,先包含头文件:
#include <QSqlTableModel>
然后添加私有对象声明:
QSqlTableModel *model;
7.到mainwindow.cpp,在构造函数添加如下代码:
model = new QSqlTableModel(this);
model->setTable("student");
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select(); //选取整个表的所有行
//不显示name属性列,如果这时添加记录,则该属性的值添加不上
// model->removeColumn(1);
ui->tableView->setModel(model);
//使其不可编辑
//ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
这里创建一个QSqlTableModel后,只需使用setTable()来为其指定数据库表,然后使用select()函数进行查询,调用这两个函数就等价于执行了“select * from student”这个SQL语句。这里还可以使用setFilter()来指定查询时的条件,在后面会看到这个函数的使用。在使用该模型以前,一般还要设置其编辑策略,它由QSqlTableModel::EditStrategy枚举变量定义,一共有三个值,如下图所示。用来说明当数据库中的值被编辑后,什么情况下提交修改。
运行程序,效果如下图所示。
可以看到,这个模型已经完全脱离了SQL语句,我们只需要执行select()函数就能查询整张表。上面有两行代码被注释掉了,你可以取消注释,测试一下它们的作用。
二、修改操作
1.我们进入“提交修改”按钮的单击信号槽,更改如下:
void MainWindow::on_pushButton_3_clicked()
{
    model->database().transaction(); //开始事务操作
    if (model->submitAll()) {
       model->database().commit(); //提交
    } else {
       model->database().rollback(); //回滚
       QMessageBox::warning(this, tr("tableModel"),
                             tr("数据库错误: %1")
                             .arg(model->lastError().text()));
    }
}
这里用到了事务操作,真正起提交操作的是model->submitAll()一句,它提交所有更改。
2.进入“撤销修改”按钮的单击信号槽,更改如下:
void MainWindow::on_pushButton_4_clicked()
{
    model->revertAll();
}
3.在mainwindow.cpp文件中包含头文件:
#include <QMessageBox>
#include <QSqlError>
4.现在运行程序,我们将“陈刚”改为“李强”,如果我们点击“撤销修改”,那么它就会重新改为“陈刚”,而当我们点击“提交修改”后它就会保存到数据库,此时再点击“撤销修改”就修改不回来了。
可以看到,这个模型可以将所有修改先保存到model中,只有当我们执行提交修改后,才会真正写入数据库。当然这也是因为我们在最开始设置了它的保存策略:
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
这里的OnManualSubmit表明我们要提交修改才能使其生效。
三、查询操作
1.进入“查询”按钮的单击信号槽,更改如下:
void MainWindow::on_pushButton_clicked()
{
    QString name = ui->lineEdit->text();
    //根据姓名进行筛选
    model->setFilter(QString("name = '%1'").arg(name));
    //显示结果
    model->select();
}
使用setFilter()函数进行关键字筛选,这个函数是对整个结果集进行查询。
2.进入“显示全表”按钮的单击信号槽,更改如下:
void MainWindow::on_pushButton_2_clicked()
{
    model->setTable("student");   //重新关联表
    model->select();   //这样才能再次显示整个表的内容
}
为了再次显示整个表的内容,我们需要再次关联这个表。
3.下面运行程序,输入一个姓名,点击“查询”按钮后,就可以显示该记录了。再点击“显示全表”按钮则返回。如下图所示。
四、排序操作
分别进入“按id升序排序”和“按id降序排序”按钮的单击信号槽,更改如下:
// 升序
void MainWindow::on_pushButton_7_clicked()
{
    model->setSort(0, Qt::AscendingOrder); //id属性即第0列,升序排列
    model->select();
}
// 降序
void MainWindow::on_pushButton_8_clicked()
{
    model->setSort(0, Qt::DescendingOrder);
    model->select();  
}
这里使用了setSort()函数进行排序,它有两个参数,第一个参数表示按第几个属性排序,表头从左向右,最左边是第0个属性,这里就是id属性。第二个参数是排序方法,有升序和降序两种。运行程序,效果如下图所示。
五、删除操作
我们进入“删除选中行”按钮的单击信号槽,更改如下:
void MainWindow::on_pushButton_6_clicked()
{
    //获取选中的行
    int curRow = ui->tableView->currentIndex().row();
   
    //删除该行
    model->removeRow(curRow);
   
    int ok = QMessageBox::warning(this,tr("删除当前行!"),tr("你确定"
                                                 "删除当前行吗?"),
                                  QMessageBox::Yes,QMessageBox::No);
    if(ok == QMessageBox::No)
    {
       model->revertAll(); //如果不删除,则撤销
    }
    else model->submitAll(); //否则提交,在数据库中删除该行  
}
删除行的操作会先保存在model中,当我们执行了submitAll()函数后才会真正的在数据库中删除该行。这里我们使用了一个警告框来让用户选择是否真得要删除该行。运行程序,效果如下图所示。
我们点击第二行,然后单击“删除选中行”按钮,出现了警告框。这时你会发现,表中的第二行前面出现了一个小感叹号,表明该行已经被修改了,但是还没有真正的在数据库中修改,这时的数据有个学名叫脏数据(Dirty Data)。当我们按钮“Yes”按钮后数据库中的数据就会被删除,如果按下“No”,那么更改就会取消。
六、插入操作
我们进入“添加记录”按钮的单击信号槽,更改如下:
void MainWindow::on_pushButton_5_clicked()
{
    int rowNum = model->rowCount(); //获得表的行数
    int id = 10;
    model->insertRow(rowNum); //添加一行
    model->setData(model->index(rowNum,0),id);
    //model->submitAll(); //可以直接提交
}
在表的最后添加一行,因为在student表中我们设置了id号是主键,所以这里必须使用setData()函数给新加的行添加id属性的值,不然添加行就不会成功。这里可以直接调用submitAll()函数进行提交,也可以利用“提交修改”按钮进行提交。运行程序,效果如下图所示。
按下“添加记录”按钮后,就添加了一行,不过在该行的前面有个星号,如果我们按下“提交修改”按钮,这个星号就会消失。当然,如果我们将上面代码里的提交函数的注释去掉,也就不会有这个星号了。
结语

可以看到这个模型很强大,而且完全脱离了SQL语句,就算你不怎么懂数据库知识,也可以利用它进行大部分常用的操作。我们也看到了,这个模型提供了缓冲区,可以先将修改保存起来,当我们执行提交函数时,再去真正地修改数据库。当然,这个模型比前面的模型更高级,前面讲的所有操作,在这里都能执行。

涉及到的源码:  tableModel.zip (3.98 KB, 下载次数: 11)


[Qt教程] 第25篇 数据库(五)SQL表格模型QSqlTableModel相关推荐

  1. [Qt教程] 第23篇 数据库(三)利用QSqlQuery类执行SQL语句

    [Qt教程] 第23篇 数据库(三)利用QSqlQuery类执行SQL语句 楼主  发表于 2013-5-15 22:39:29 | 查看: 813| 回复: 0 利用QSqlQuery类执行SQL语 ...

  2. [Qt教程] 第24篇 数据库(四)SQL查询模型QSqlQueryModel

    [Qt教程] 第24篇 数据库(四)SQL查询模型QSqlQueryModel 楼主  发表于 2013-5-21 14:33:47 | 查看: 869| 回复: 1 SQL查询模型QSqlQuery ...

  3. [Qt教程] 第26篇 数据库(六)SQL关系表格模型QSqlRelationalTableModel

    [Qt教程] 第26篇 数据库(六)SQL关系表格模型QSqlRelationalTableModel 楼主  发表于 2013-5-21 20:54:13 | 查看: 677| 回复: 6 SQL关 ...

  4. [Qt教程] 第22篇 数据库(二)编译MySQL数据库驱动

    [Qt教程] 第22篇 数据库(二)编译MySQL数据库驱动 楼主  发表于 2013-5-13 21:28:02 | 查看: 1616| 回复: 12 编译MyQSL数据库驱动 版权声明 该文章原创 ...

  5. [Qt教程] 第21篇 数据库(一)Qt数据库应用简介

    [Qt教程] 第21篇 数据库(一)Qt数据库应用简介 楼主  发表于 2013-5-13 20:56:39 | 查看: 1403| 回复: 13 Qt数据库应用简介 版权声明 该文章原创于作者yaf ...

  6. [Qt教程] 第35篇 网络(五)获取本机网络信息

    [Qt教程] 第35篇 网络(五)获取本机网络信息 楼主  发表于 2013-9-5 11:32:58 | 查看: 278| 回复: 2 获取本机网络信息 版权声明 该文章原创于作者yafeilinu ...

  7. [Qt教程] 第45篇 进阶(五)Qt样式表

    [Qt教程] 第45篇 进阶(五)Qt样式表 楼主  发表于 2013-9-13 15:43:55 | 查看: 329| 回复: 1 Qt样式表 版权声明 该文章原创于Qter开源社区 导语 一个完善 ...

  8. [Qt教程] 第15篇 2D绘图(五)绘制图片

    [Qt教程] 第15篇 2D绘图(五)绘制图片 楼主  发表于 2013-5-2 17:59:00 | 查看: 886| 回复: 3 绘制图片 版权声明 该文章原创于Qter开源社区(www.qter ...

  9. [Qt教程] 第27篇 XML(一)使用DOM读取XML文档

    [Qt教程] 第27篇 XML(一)使用DOM读取XML文档 楼主  发表于 2013-5-21 21:14:28 | 查看: 1001| 回复: 14 使用DOM读取XML文档 版权声明 该文章原创 ...

最新文章

  1. 技术图文:如何利用 Turtle 绘制一棵漂亮的樱花树
  2. 理解GO CONTEXT机制
  3. linux 账号密码 字段,详解Linux中的用户密码管理命令passwd和change
  4. JAVA-用栈机制实现单词逆序排列
  5. java线程三种创建方式与线程池的应用
  6. php 获取远程大文件上传,PHP 获取远程文件大小的3种解决方法
  7. vue项目html,Vue项目接口.html
  8. 常用的Sql命令之造数据
  9. 服务器 显示w3wp.exe,w3wp.exe占用cpu过高的解决方法
  10. nat流量,业务流量_10种增加在线业务流量的方法
  11. java web构建_使用Java构建一个宁静的Web服务
  12. 乐行科技获1.08亿元A轮融资,并推出艾特好车 1
  13. 微信支付 公众号关联商户号
  14. 使用kubecm管理k8s多集群环境
  15. liquibase介绍与使用
  16. Endnote x7在word 2013中插件不显示
  17. c语言编译器2017,2016-2017年本科C语言编译器设计与实现毕业论文设计.doc
  18. 汇编语言:以GRADE为首地址的10个字的数组中保存有学生成绩。建立一个10个字的RNAK 数组,并根据GRADE中的学生成绩将学生名次填入RANK数组中
  19. NKCTF2023 pwn wp
  20. 《数据安全法》今起正式实施,隐私计算迎来千亿级风口|潜在风向标

热门文章

  1. 充分感受中国缺少管理型软件人才的说法
  2. c语言第一课程序代码怎么打,【北北的小程序】北のC语言第一课:helloworld
  3. mysql 技能进阶_mysql的高级进阶(一)
  4. 电脑没有ps怎么改照片dpi_PS入门的小技巧来啦!小白们还在等什么呢?快进来啊!...
  5. oracle带输出参数存储,oracle带输入输出参数存储过程(包括sql分页功能)
  6. android 高级项目,从零开始的Android新项目8 - Data Binding高级篇
  7. 我的世界进服务器显示C1.8-1.11,【插件】 LibsDisguises —— 让你的玩家变成生物或者其他 [1.8-1.11]...
  8. Java基础(三十五)Math、Random类和数字格式化(String.format方法)
  9. JS实现全选、反选、不选
  10. MYSQL中group_concat有长度限制!默认1024