发出 dataChanged(createIndex(1,1),createIndex(1,1)) 导致许多 ::data 调用
Posted
技术标签:
【中文标题】发出 dataChanged(createIndex(1,1),createIndex(1,1)) 导致许多 ::data 调用【英文标题】:emit dataChanged(createIndex(1,1),createIndex(1,1)) results in many ::data invocations 【发布时间】:2012-03-23 17:59:40 【问题描述】:我有一个 QTableView 和一个对应的 QAbtractTableModel 子实例。
我很惊讶地发现,如果我的表模型实例发出一个命名单个单元格的 dataChanged,那么 Qt 框架将对我的表模型的 ::data() 成员函数发出大量调用。这些调用的行/列范围似乎涵盖了屏幕上的整个范围+一些额外内容。
这超出了我的预期。我原以为命名单个单元格的 dataChanged() 只会导致 ::data() 调用请求该单元格的数据。毕竟,这是我的表格模型所说的唯一改变的单元格。但 Qt 框架似乎非常合群,并且会查询所有单元格。
我显然对 dataChanged() 信号的意图有一个破碎的理解。
有没有办法告诉 QTableView 只更新一个单元格和一个单元格,而不会将所有额外的聊天发送到我的表格模型?
更新:包括代码示例 此处的示例是标题、源代码和用于创建表的代码块。对我来说,表格显示为 12 列和 29 行。在最后的“issueEmit”调用之后,::data 将被调用 1044 次,这都是因为单个单元格的 dataChanged() 信号。
// Declaration
#include <QAbstractTableModel>
class SimpleModel : public QAbstractTableModel
Q_OBJECT
private:
bool _post_emit;
public:
explicit SimpleModel(QObject *parent=0);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
void issueEmit();
;
// Implementation
#include <stdlib.h>
#include <stdio.h>
#include "simplemodel.h"
SimpleModel::SimpleModel(QObject *parent) : QAbstractTableModel(parent), _post_emit(false)
int SimpleModel::rowCount(const QModelIndex &parent) const
return 100;
int SimpleModel::columnCount(const QModelIndex &parent) const
return 100;
QVariant SimpleModel::data(const QModelIndex &index, int role) const
if (role==Qt::DisplayRole)
if (_post_emit)
static unsigned s_calls=0;
s_calls++;
printf("Data calls: %d\n",s_calls);
return ((rand()%10000)/1000.00);
return QVariant();
void SimpleModel::issueEmit()
_post_emit=true;
emit dataChanged(createIndex(1,1),createIndex(1,1));
// Usage
QTableView *table=new QTableView;
table->setMinimumSize(1200,900);
SimpleModel *model=new SimpleModel;
table->setModel(model);
table->show();
model->issueEmit();
【问题讨论】:
我已经提交了bug report in the Qt system,因为那可能是更好的家。我会酌情更新或关闭。 【参考方案1】:QVariant QStandardItem::data ( int role = Qt::UserRole + 1 ) const [virtual]
返回给定角色的项目数据,如果没有该角色的数据,则返回无效的 QVariant。
这里的论点真的很有趣。模型中的每个项目都包含许多 QVariants,这些 QVariants 维护有关项目的不同信息。
这些变体都分配了roles。每当您发出该数据已更改时,模型都必须重新绘制该项目。要重新绘制项目,它必须查看许多不同的数据(下面包含小摘录)
描述外观和元数据的角色(以及相关类型): 常量值说明 Qt::FontRole 6 用于使用默认委托渲染的项目的字体。 (QFont) Qt::TextAlignmentRole 7 使用默认委托渲染的项目的文本对齐方式。 (Qt::AlignmentFlag) Qt::BackgroundRole 8 用于使用默认委托渲染的项目的背景画笔。 (QBrush)
【讨论】:
你是说 ::data() 只会被称为“n-roles”次,并为单个单元格发出 dataChanged() 吗?因为我相信我正在通过“n-columns”和“n-roles”的调用次数观察“n-rows”。如果我能举出一个我正在观察的小例子,然后继续下去,那可能是最好的。当我有那个时,我会重新发布。 我已经用一些示例代码更新了我的原始帖子,这些示例代码说明了我认为我正在观察的问题。对我来说,问题在于旨在更新单个单元格的发出 dataChanged() 会生成大量对 ::data() 的调用。以上是关于发出 dataChanged(createIndex(1,1),createIndex(1,1)) 导致许多 ::data 调用的主要内容,如果未能解决你的问题,请参考以下文章
发出 dataChanged(createIndex(1,1),createIndex(1,1)) 导致许多 ::data 调用