• 23466阅读
  • 16回复

[提问]QTableView实时刷新数据与选择某一行的UI矛盾 [复制链接]

上一主题 下一主题
离线stlcours
 

只看楼主 倒序阅读 楼主  发表于: 2014-12-18
好不容易搞懂了Model-View,成功控制了QTableView和它的TableModel(继承自QAbstractTableModel,并做扩展),可以分别达到两个目的:
1. 用户选择QTableView的某一行,然后可以做一些相应的操作,就像播放音乐文件一样。
2. QTableView不断刷新数据

没想到又来了一个新的矛盾:就是实时刷新数据的时候,几乎每秒都要调用QAbstractTableModel的一个自定义函数:

void TableModel::refrushModel()
{
    beginResetModel(); // model 内置函数,这句是最关键的
    endResetModel();
}
这样才能做到实时刷新。
但是刷新时,用户根本无法选中某一行了。即使选中,也会被刷新后自动取消,导致不能根据选中项目做一些其它的多线程操作,这该如何是好?
离线stlcours

只看该作者 1楼 发表于: 2014-12-18
我想了一个办法,就是只要点击了QTableView的某一项,就把它记录在m_selectitem里。然后每次刷新完毕以后,重新调用
m_tableview->selectRow(m_selectitem);

看上去这个方法可以,可是一旦执行,就会出错,而且执行四次,出错的QT库源代码位置都不一样(不是我的源代码位置),所以我想应该不是我的问题。
看来我这个笨办法还是不行,有没有别的办法,请各位多指教。
离线dbzhang800

只看该作者 2楼 发表于: 2014-12-18
你的 void TableModel::refrushModel() 想法有问题吧?动不动就 reset Model?
离线stlcours

只看该作者 3楼 发表于: 2014-12-18
回 dbzhang800 的帖子
dbzhang800:你的 void TableModel::refrushModel() 想法有问题吧?动不动就 reset Model?
 (2014-12-18 09:05) 

请教那应该怎么办?
离线dbzhang800

只看该作者 4楼 发表于: 2014-12-18
回 stlcours 的帖子
stlcours:请教那应该怎么办? (2014-12-18 21:27) 

不知道你代码最终目的是什么啊。感觉上你想做的是对Model进行 追加/插入/删除 行等操作,而不是 reset Model.
离线stlcours

只看该作者 5楼 发表于: 2014-12-19
我是想修改后刷新显示,请指教!
离线dbzhang800

只看该作者 6楼 发表于: 2014-12-19
回 stlcours 的帖子
stlcours:我是想修改后刷新显示,请指教! (2014-12-19 00:25) 

你的修改到底指代什么:

修改现有行或列的内容? 添加?删除?插入?   (使用model提供的相应操作)

还是完全无关的修改,比如,这次内容是中国各省列表,下一次是中国朝代变更表?  (使用model的reset)
离线stlcours

只看该作者 7楼 发表于: 2014-12-19
回 dbzhang800 的帖子
dbzhang800:你的修改到底指代什么:
修改现有行或列的内容? 添加?删除?插入?   (使用model提供的相应操作)
....... (2014-12-19 08:54) 

我修改的是现有的内容,但是没有使用model提供的操作,而是直接改数据,比如mydata[1][2]=100,然后希望能够刷新。

另外,我加你的QQ了,希望能回应一下。
离线XChinux

只看该作者 8楼 发表于: 2014-12-22
应该是,你直接修改model中对应index里的data值(Qt::DisplayRole 和Qt::EditRole?),然后通知view说我哪些index变化了,要更新一下,这样model和index没变,selectionModel也没变。。。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线prcseraph

只看该作者 9楼 发表于: 2015-02-15
mark
离线stlcours

只看该作者 10楼 发表于: 2015-02-16
提示一下,最后完美解决这个问题,不再使用
beginResetModel(); // model 内置函数,这句是最关键的
endResetModel();

而是使用
void TableModel::updateData(int i)
{
    if (i<0) return;
    // 根据指定行列,得到index
    QModelIndex t1 = index(i, 3);
    QModelIndex t2 = index(i, 5);
    emit dataChanged(t1, t2); // view good 最关键的刷新数据,不会取消所选项
}
离线z55716368

只看该作者 11楼 发表于: 2015-07-11
回 stlcours 的帖子
stlcours:提示一下,最后完美解决这个问题,不再使用
beginResetModel(); // model 内置函数,这句是最关键的
endResetModel();
而是使用
....... (2015-02-16 17:00) 

请教一下,我现在使用的tableview和QStandardItemModel进行显示数据库数据,然后第九列可以编辑。当编辑之后,按下回车就能执行save(),现在的问题就是怎么触发这个回车。我调用了回车的事件,但是它只对这个界面回车,并且不是对这个单元格,每次修改完毕之后,必须回车2次才能save()。而单独在界面回车也会save()。
每一个问题 都是一次进步
离线mxl198869

只看该作者 12楼 发表于: 2015-12-17
回 stlcours 的帖子
stlcours:提示一下,最后完美解决这个问题,不再使用
beginResetModel(); // model 内置函数,这句是最关键的
endResetModel();
而是使用
....... (2015-02-16 17:00) 

你好,我现在也碰到同样的问题,对于你的提示不是很明白,你能完整的说一下吗?谢谢!
离线stlcours

只看该作者 13楼 发表于: 2015-12-17
回 mxl198869 的帖子
mxl198869:你好,我现在也碰到同样的问题,对于你的提示不是很明白,你能完整的说一下吗?谢谢! (2015-12-17 11:39) 

我写的很清楚啊,发射信号进行局部更新,这种更新法不会取消所选项
离线mxl198869

只看该作者 14楼 发表于: 2015-12-18
回 stlcours 的帖子
stlcours:我写的很清楚啊,发射信号进行局部更新,这种更新法不会取消所选项 (2015-12-17 16:28) 

是应该model->updateData(x)形式给其传值吧,我这边检测信号发出的行列始终是-1, 小弟初学,没想明白~~
离线萱苏

只看该作者 15楼 发表于: 2018-10-16
回 stlcours 的帖子
stlcours:我写的很清楚啊,发射信号进行局部更新,这种更新法不会取消所选项 (2015-12-17 16:28) 

执行emit dataChanged(t1, t2);后槽函数需要自己实现吗?
离线lwei24

只看该作者 16楼 发表于: 2021-10-08
楼主,请问实时刷新并且在快速点击表头进行排序时,选中行可能出现位置错乱导致了对选中行的误操作,比如右键删除等,请问有什么办法可以避免或判断排序是否结束吗?
快速回复
限100 字节
 
上一个 下一个