Qt中使用QSqlTableModel和QTableView实现与MySQL数据库的联动

4 篇文章 0 订阅

连接MySQL数据库

    QSqlDatabase sqldb = QSqlDatabase::addDatabase("QMYSQL");
    sqldb.setHostName("localhost");
    sqldb.setDatabaseName("patient");
    sqldb.setUserName("root");
    sqldb.setPassword("123456");
    if (!sqldb.open()) {
        QMessageBox::critical(0, QObject::tr("后台数据库连接失败"), "无法创建连接!请排查故障后重新启动",QMessageBox::Cancel);
        return false;
    }
    /* 
        数据库操作
     */
    sqldb.close();

 数据库中的user_profile表:

 插入数据到数据库


    //创建SQL查询
    QSqlQuery query(sqldb);
    //向数据库中插入数据
//    QString insStr = "insert into user_profile values('320199101011806888','张美丽','女','汉','1986-03-04','南京市高淳区淳溪镇汶溪路666号','暂无',null)";
//    if(!query.exec (insStr)){
//        qDebug() << "插入失败";
//    }else{
//        qDebug() << "插入成功";
//    }
    //向数据库中插入照片
    //照片路径
    QString photoPath = "C:\\Users\\LUO\\Desktop\\10.jpg";
    //照片文件对象
    QFile photoFile(photoPath);

    //判断照片是否存在
    if(photoFile.exists ()){
        //存在的话就存入数据库
        //用字节数组存储图片数据
        QByteArray picData;
        //用只读的方式打开图片文件
        photoFile.open (QIODevice::ReadOnly);
        //将图片数据读入字节数组
        picData = photoFile.readAll ();
        //文件关闭
        photoFile.close ();
        //将照片数据封装成变量
        QVariant var(picData);
        //更新的sql语句
        QString sqlstr = "update user_profile set picture=? where name='葛二妮'";
//                QString sqlstr = "insert into user_profile values('320199101011806999','张美兰','女','汉','1996-12-04','南京市高淳区淳溪镇汶溪路999号','暂无',?)";
        query.prepare (sqlstr);
        //绑定数据,填入照片数据参数
        query.addBindValue (var);
        //执行更新操作
        if(!query.exec ()){
            qDebug() << "插入照片失败";
        }else{
            qDebug() << "插入照片成功";
        }
    }

QSqlTableModel模型加载数据库视图

数据库中basic_inf视图

 basic_inf视图sql语句:

select `user_profile`.`ssn` AS `社会保障号码`,`user_profile`.`name` AS `患者`,`user_profile`.`sex` AS `性别`,`user_profile`.`ethnic` AS `民族`,`user_profile`.`birth` AS `出生日期`,`user_profile`.`address` AS `住址` from `user_profile`

数据库中details视图:

sql语句:

select `user_profile`.`name` AS `姓名`,`user_profile`.`casehistory` AS `病历`,`user_profile`.`picture` AS `照片` from `user_profile`

sql模型加载视图,tableview加载sql模型:

    QSqlTableModel* model;    //访问数据库视图信息的模型
    QSqlTableModel* model_d;  //访问数据库附加详细信息(病历、照片)视图的模型
    
    //基本视图信息;
    model = new QSqlTableModel(this);
    model->setTable("basic_inf");
    model->select();  //加载数据
    //附加详细信息视图
    model_d = new QSqlTableModel(this);
    model_d->setTable("details_inf");
    model_d->select();

    //数据网格信息加载
    ui->basicTableView->setModel(model);

模型加载成功后,可以直接在tableview中修改表格中的数据,并且表格数据的变化会联动到数据库,数据库中的数据也会跟着变化。

使用QSqlTableModel修改数据库中的数据

使用setData()函数

Reimplements: QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role).

Sets the data for the item index for the role role to value.

For edit strategy OnFieldChange, an index may receive a change only if no other index has a cached change. Changes are submitted immediately. However, rows that have not yet been inserted in the database may be freely changed and are not submitted automatically. Submitted changes are not reverted upon failure.

For OnRowChange, an index may receive a change only if no other row has a cached change. Changes are not submitted automatically.

Returns true if value is equal to the current value. However, the value will not be submitted to the database.

Returns true if the value could be set or false on error, for example if index is out of bounds.

Returns false if the role is not Qt::EditRole. To set data for roles other than EditRole, either use a custom proxy model or subclass QSqlTableModel.

重新实现:QAbstractItemModel :: setData(const QModelIndex&index,const QVariant&value,int角色)。

将角色角色的项目索引的数据设置为value。

对于编辑策略OnFieldChange,仅当没有其他索引具有缓存的更改时,索引才可以接收更改。 更改将立即提交。 但是,尚未插入数据库中的行可以自由更改,并且不会自动提交。 提交的更改不会在失败后恢复。

对于OnRowChange,仅当没有其他行具有缓存的更改时,索引才可以接收更改。 更改不会自动提交。

如果value等于当前值,则返回true。 但是,该值将不会提交到数据库

如果可以设置该值,则返回true;如果出错则返回false,例如,如果index超出范围。

如果角色不是Qt :: EditRole,则返回false。 若要为EditRole以外的角色设置数据,请使用自定义代理模型或子类QSqlTableModel。

 使用setData函数可以修改model中的数据,但是model并不会主动提交到数据库。

所以还需要使用submit()、submitAll()函数,将变化的数据提交到数据库:


[override virtual slot] bool QSqlTableModel::submit()

Reimplements: QAbstractItemModel::submit().

This reimplemented slot is called by the item delegates when the user stopped editing the current row.

Submits the currently edited row if the model's strategy is set to OnRowChange or OnFieldChange. Does nothing for the OnManualSubmit strategy.

Use submitAll() to submit all pending changes for the OnManualSubmit strategy.

Returns true on success; otherwise returns false. Use lastError() to query detailed error information.

Does not automatically repopulate the model. Submitted rows are refreshed from the database on success.

See also revert(), revertRow(), submitAll(), revertAll(), and lastError().

重新实现:QAbstractItemModel :: submit()。

当用户停止编辑当前行时,项目委托将调用此重新实现的插槽。

如果模型的策略设置为OnRowChange或OnFieldChange,则提交当前编辑的行。 对OnManualSubmit策略不执行任何操作。

使用submitAll()提交OnManualSubmit策略的所有未决更改。

成功返回true; 否则返回false。 使用lastError()查询详细的错误信息。

不会自动重新填充模型。 成功时将从数据库刷新提交的行。


[slot] bool QSqlTableModel::submitAll()

Submits all pending changes and returns true on success. Returns false on error, detailed error information can be obtained with lastError().

In OnManualSubmit, on success the model will be repopulated. Any views presenting it will lose their selections.

Note: In OnManualSubmit mode, already submitted changes won't be cleared from the cache when submitAll() fails. This allows transactions to be rolled back and resubmitted without losing data.

See also revertAll() and lastError().

提交所有未决的更改,并在成功时返回true。 错误时返回false,可以使用lastError()获得详细的错误信息。

在OnManualSubmit中,成功后将重新填充模型。 呈现它的所有视图都将丢失选择。

注意:在OnManualSubmit模式下,当submitAll()失败时,不会从缓存中清除已提交的更改。 这允许事务回滚并重新提交而不会丢失数据。

另请参见revertAll()和lastError()。

    QString name = ui->nameLabel->text ();
    QString str = ui->caseTextEdit->document()->toPlainText ();
    //存入前先转为QVAriant类型
    QVariant var(str);
    QModelIndex index ;
    //只能逐行按照名字查找

    for(int i=0;i<model_d->rowCount ();i++){
        //第0列是姓名,第1列是病历,第2列是图片
        index = model_d->index(i, 0);
        if(model_d->data (index).toString () == name){
            //找到那个人的病历的index,更改
            index = model_d->index (i,1);
            break;
        }
    }
    //找到那个人的病历,更改
    qDebug() <<"原病历:"<< model_d->data (index).toString ();
    model_d->setData (index,var);
    model_d->submitAll ();

参考文章:

SQL查询模型QSqlQueryModel

  • 4
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SOC罗三炮

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

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

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

打赏作者

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

抵扣说明:

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

余额充值