zoukankan      html  css  js  c++  java
  • Qt实用技巧:使用QTableView、QSqlTableMode与QSqlDatabase对数据库数据进行操作

    本文章博客地址:http://blog.csdn.net/qq21497936/article/details/78615800

    Qt实用技巧:使用QTableView、QSqlTableMode与QSqlDatabase对数据库数据进行操作

    需求

            编写应用软件的过程中,需要对保存的数据进行动态的设置,当程序运行的时查询数据库获取相关配置项进行设置。

    原理

            使用时,将QSqlTableModel与QSqlDatabase绑定即model与sql绑定,然后将model与QTableView绑定,实现修改QTableView时,自动更新对数据库的操作,基本的数据库操作语句都省了。

    Demo

    Demo下载地址:http://download.csdn.net/download/qq21497936/10130238

    Demo包含

    Demo截图

    关键代码

    对于数据库的操作:打开数据库

    [cpp] view plain copy
     
    1.     _db = QSqlDatabase::addDatabase("QSQLITE");  
    2.     _db.setDatabaseName("demo.db");  
    3.   
    4.     // 数据库文件是否在应用程序目录下,因为在编码时,应用程序默认路径在.pro文件夹下,但是实际exe路径在的其debug或者release文件夹下  
    5.     // 补充:不论linux还是windows,统一使用单斜杠作为分隔,在linux和windows下都能识别,能更好的跨平台  
    6. #if 0  
    7.     // 发布时  
    8.     QString path = qApp->applicationDirPath()+"/"+"demo.db";  
    9. #else  
    10.     // 编译时  
    11.     QString path = qApp->applicationDirPath()+"/../"+"demo.db";  
    12. #endif  
    13.     if(QFile::exists(path))  
    14.   
    15.     {  
    16.         // 存在则打开  
    17.         _db.open();  
    18.     }else{  
    19.         // 不存在打开并创建数据库表 补充:SQLite是基于文件的数据库,当打开时如果数据库文件不存在将自动创建一个  
    20.         _db.open();  
    21.         QSqlQuery query;  
    22.         // set为sqlite关键字,不能使用  
    23.         bool bRet = query.exec("create table init("   
    24.                                "no   INT    PRIMARY KEY NOT NULL,"  
    25.                                "name TEXT   NOT NULL,"  
    26.                                "content TEXT,"  
    27.                                "description TEXT"  
    28.                                ");");  
    29.         if(!bRet) {  
    30.             _db.close();  
    31.             QFile::remove(path);  
    32.         }else{  
    33.             // 此处演示了三种不同insert插入方法  
    34.             query.exec("insert into init values"   
    35.                        "(1, '启动界面背景', 'images/background.jpg', '请使用1920*1080的图片,图片格式可以为png、jpg。');");  
    36.             query.exec("insert into init       "   
    37.                        "(no,name,content,description) values(2, '欢迎视频', '','进入启动界面后,循环播放的视频,必须为mp4格式,如果为空则循环播放欢迎音乐');");  
    38.             query.exec("insert into init       "   
    39.                        "(no,name,description) values (3, '欢迎音乐','进去启动界面后,循环播放的音频文件,可选择mp3,wav格式');");  
    40.         }  
    41.     }  

    QSqlTableMode与数据库绑定

    [cpp] view plain copy
     
    1. // 如果使用MySqlTableModel,重写了data,但是导致直接点击数据修改的时候,没有更新TableView,不知原因  
    2. // 如果使用QSqlTableMode,则无法通过重载实现每一行自动居中等一些单元格的统一操作,只能遍历单元格设置  
    3. QSqlTableModel *pModel = new QSqlTableModel(this, _db);  
    4. pModel->setTable("init");  
    5. // 三种提交方式,改动即提交,选择其他行时提交,手动提交;经实际测试,其中只有手动提交在显示效果上是最好的  
    6. pModel->setEditStrategy(QSqlTableModel::OnManualSubmit);  
    7. pModel->select();  
    8. pModel->setHeaderData(0, Qt::Horizontal, "序号");  
    9. pModel->setHeaderData(1, Qt::Horizontal, "名称");  
    10. pModel->setHeaderData(2, Qt::Horizontal, "内容");  
    11. pModel->setHeaderData(3, Qt::Horizontal, "描述");  
    12. pModel->sort(0, Qt::AscendingOrder); // 第0列升序排序  

    QTableView与QSqlTableMode绑定

    [cpp] view plain copy
     
    1. ui->tableView->setModel(pModel);  

    QTableView的初始化设置

    [cpp] view plain copy
     
    1. // grid原本就是有多少格显示多少格,  
    2.   ui->tableView->setShowGrid(false); // 可隐藏grid  
    3. // 只能单选  
    4. ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);  
    5. // 以行作为选择标准  
    6. ui->tableView->setSelectionBehavior(QAbstractItemView::QAbstractItemView::SelectRows);  
    7. // 行头隐藏  
    8. ui->tableView->verticalHeader()->hide();  
    9. // 让列头可被点击,触发点击事件  
    10. ui->tableView->horizontalHeader()->setSectionsClickable(true);  
    11. // 去掉选中表格时,列头的文字高亮  
    12. ui->tableView->horizontalHeader()->setHighlightSections(false);  
    13. ui->tableView->horizontalHeader()->setBackgroundRole(QPalette::Background);  
    14. // 列头灰色  
    15. ui->tableView->horizontalHeader()->setStyleSheet("QHeaderView::section{background-color:rgb(225,225,225)};");  
    16. connect(ui->tableView->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(sortByColumn(int)));  

    QTableView点击列头的排序操作(初始化时,开启了列头clicked和关联信号槽)

    [cpp] view plain copy
     
    1. void MainWindow::sortByColumn(int col)  
    2. {  
    3.     QSqlTableModel *pMode = dynamic_cast<QSqlTableModel *>(ui->tableView->model());  
    4.     bool ascending = (ui->tableView->horizontalHeader()->sortIndicatorSection()==col  
    5.                       && ui->tableView->horizontalHeader()->sortIndicatorOrder()==Qt::DescendingOrder);  
    6.     Qt::SortOrder order = ascending ? Qt::AscendingOrder : Qt::DescendingOrder;  
    7.     pMode->sort(col, order);  
    8. }  

    QTableView修改一行的保存操作

    [cpp] view plain copy
     
    1. void MainWindow::on_pushButton_save_clicked()  
    2. {  
    3.   
    4.     QSqlTableModel *pMode = dynamic_cast<QSqlTableModel *>(ui->tableView->model());  
    5.     pMode->database().transaction(); //开始事务操作  
    6.     if (pMode->submitAll()) // 提交所有被修改的数据到数据库中  
    7.     {  
    8.         pMode->database().commit(); //提交成功,事务将真正修改数据库数据  
    9.     } else {  
    10.         pMode->database().rollback(); //提交失败,事务回滚  
    11.         QMessageBox::warning(this, tr("tableModel"),tr("数据库错误: %1").arg(pMode->lastError().text()));  
    12.     }  
    13.     pMode->revertAll(); //撤销修改  
    14. }  

    QTableView新增一行的操作

    [cpp] view plain copy
     
    1. void MainWindow::on_pushButton_add_clicked()  
    2. {  
    3.     QSqlTableModel *pMode = dynamic_cast<QSqlTableModel *>(ui->tableView->model());  
    4. //    pMode->insertRow(pMode->rowCount());  
    5.     QSqlRecord record = pMode->record();  
    6.     int number;  
    7.     // 从1开始遍历,遇到相同的,自增再遍历,直到没有相同的作为number插入  
    8.     // 防止唯一主键重复导致提交失败,因为提交失败tableview还是会更新修改后的(视图)  
    9.     for(number = 1; ; number++)  
    10.     {  
    11.         bool bFlag = false;  
    12.         for(int index = 0; index < pMode->rowCount(); index++) {  
    13.             if(pMode->index(index, 0).data().toInt() == number) {  
    14.                 bFlag = true;  
    15.                 break;  
    16.             }  
    17.         }  
    18.         if(!bFlag) {  
    19.             break;  
    20.         }  
    21.     }  
    22.     record.setValue(0, number);  
    23.     record.setValue(1, "未命令");  
    24.     record.setValue(2, "空");  
    25.     record.setValue(3, "空");  
    26.     pMode->insertRecord(pMode->rowCount(), record);  
    27.     // 每次手动提交,都会重新刷新tableView,保持mode和tableView一致  
    28.     pMode->submitAll();  
    29. }  

    QTableView删除一行的操作

    [cpp] view plain copy
     
    1. void MainWindow::on_pushButton_del_clicked()  
    2. {  
    3.     QSqlTableModel *pMode = dynamic_cast<QSqlTableModel *>(ui->tableView->model());  
    4.     // 当QSqlTableModel::EditStrategy 选择 非QSqlTableModel::OnManualSubmit 时,  
    5.     // 每次删除都可删除掉model,但是tableview那一列为空,一直在,只好设置为 QSqlTableModel::OnManualSubmit  
    6.     pMode->removeRow(ui->tableView->currentIndex().row());  
    7.     // 每次手动提交,都会重新刷新tableView,保持mode和tableView一致  
    8.     pMode->submitAll();  
    9. }  

    拓展

            整个应用,可只打开一次QSqlDatabase,程序中第一次使用了QDatabase,打开后不关闭且不再打开新的数据库,其他类中可直接声明QSqlDatabase对象db,然后使用QSqlQuery进行查询操作。(正常以为是需要传递,但Qt机制中,此处可不第二次打开,只要第一次不关闭,但是都必须在一个应用中)。

    http://blog.csdn.net/qq21497936/article/details/78615800

  • 相关阅读:
    06.django升级打怪学习记
    05.django升级打怪学习记
    04.django升级打怪学习记
    03.django升级打怪学习记
    02.django升级打怪学习记
    python学习手册笔记——39.元类
    python学习手册笔记——35.异常的设计
    关于我
    [Jenkins]Console Output中文显示问号的问题解决
    [Jenkins]JDK版本过高导致的java.io.IOException: Remote call on xxxx failed
  • 原文地址:https://www.cnblogs.com/findumars/p/8205980.html
Copyright © 2011-2022 走看看