找回密码
 立即注册
收起左侧

请教一个QTableModel使用的问题

2
回复
8766
查看
[复制链接]
累计签到:27 天
连续签到:1 天
来源: 2018-5-24 00:03:36 显示全部楼层 |阅读模式
10Qter豆
本帖最后由 clickto 于 2018-5-24 00:43 编辑

请教一个QTableModel在使用中的问题:有数据表table_user,使用QTableModel和QTableView来操作。
table_user的字段有:id,name,age,**,code,在界面中显示的是name,age和**,其中id为主键,code是根据name和age算的一个编码。
需求:
1、右键菜单新增一行;
2、在model提交数据库之前要计算好id值,否则插入失败;
3、在界面编辑数据内容后,鼠标点击切换不同的row,或者回车,这两个条件都需要model进行提交数据
4、code的值是根据name和age算的一个编码,在新增记录时即生成。
5、在修改现有数据时,根据修改结果自动实时计算显示关联的其它数据(需通过表修改的表内容做参数)
描述:
1、新增一行,并计算id,我是这样实现的:  
  1.        //添加一行
  2.         connect(ui->action_append,&QAction::triggered,this,[=](){
  3.            QSqlRecord record = model->record();
  4.             record.setValue("unit_id",g_current_unit_id);//设置单位id
  5.             QSqlQuery qr(g_db_local);
  6.             qr.exec("select max(id) from ryb");//取出当前的最大id
  7.             if(qr.next())
  8.             {
  9.                 int id = qr.value(0).toInt();
  10.                 record.setValue("id",id + 1);
  11.                 if(model->insertRecord(-1,record))
  12.                 {
  13.                     insertrow_completed = false;//设置标志位,用来做其它操作的判据
  14.                     peple_row = model->rowCount()-1;//保存当前所选择的行
  15.                 }
  16.             }
  17.         });
复制代码

2、切换行时提交数据,我是通过响应tableview的clicked信号在实现的,代码如下:
  1. void Form_Peple::tableview_rowchanged(QModelIndex current)
  2. {
  3.     if(current.row() != peple_row )//换行了
  4.     {
  5.         //注意鉴别插入的空行
  6.         QSqlRecord record = model->record(current.row());
  7.         int id = record.value("id").toInt(&ok);

  8.         if(!insertrow_completed) //插入新行
  9.         {
  10.             //添加code字段值.....
  11.             record.setValue("code",12345);
  12.             //提交数据库,设置标志
  13.             if(model->submitAll())
  14.             {
  15.                 insertrow_completed = true;
  16.             }
  17.         }

  18.         peple_row = current.row();//保存当前所选择的行
  19.         if(id >0)
  20.         {
  21.                 emit person_changed(id);//发送人员选择更改信号,做其它运算
  22.         }
  23.     }
  24. }
复制代码


3、修改记录时,自动实时计算显示关联数据,我是在model的dataChanged信号中实现,代码如下:
  1. void Form_Peple::do_modeldatachanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
  2. {
  3.         int row = topLeft.row();
  4.         int column = topLeft.column();
  5.         QSqlRecord rcd = model->record(row);
  6.         peple_row = row;
  7.         QString name,date,code;

  8.      //注意鉴别是否是新插入的空行调用
  9.         if(insertrow_completed)
  10.         {
  11.                 QString name= rcd.value("name").toString();
  12.                 int age = rcd.value("age").toInt();
  13.                 if(!(name.isEmpty() || age<0))
  14.                 {
  15.                         if(insertrow_completed)//如果是已存数据,需要重新计算code
  16.                         {
  17.                                 code = 23456;
  18.                                 model->setData(model->index(row,1),code);//直接修改数据库
  19.                                 //rcd.setValue("code",code);
  20.                         }
  21.                         g_current_code = code;
  22.                 }

  23.                 //model->submitAll();
  24.                 emit person_data_changed(person_id);//发送信息更改信号,做实时计算处理
  25.         }

  26. }
复制代码


我觉得上述代码可以实现,但问题是一旦运行,就会出问题,经过设置断点多次运行,发现问题出在model的信号上。当我新增一行时,这3个消息会被同时发出,要命的是,这3个消息响应函数的运行顺序是不确定的,而且可以相互中断!!!
这就导致一种可能的情况:insertrow_completed这个标志量在新插入行后还没进行设置为false时,就走到了代码段2或代码段3,此时insertrow_completed为true,就直接运行了其它代码,导致程序崩溃。
想请教大家,怎样保证这3个槽函数按照我预想的顺序执行,起码先将insertrow_completed标志位设置为false?(我试过在代码段1中的第一行就进行设置,但遇到先执行代码段2或3的情况)
另外,如果是你们,上述需求该怎么实现?
请大家不吝赐教!!!




回复

使用道具 举报

累计签到:742 天
连续签到:1 天
2018-5-24 10:07:02 显示全部楼层
这个你修改一下逻辑会不会好一点,数据提交的方式优化一下,你觉得呢?
回复

使用道具 举报

累计签到:27 天
连续签到:1 天
2018-5-24 10:39:55 显示全部楼层
请教,逻辑怎么修改和怎么优化呢?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了