我的问题是,在使用时
QStandarditemmodel::setData(const QModelIndex &index, const QVariant &value, int role)
似乎这个角色永远不会发出。
示例:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
QStandardItemModel *model = new QStandardItemModel();
QList<QStandardItem*> itemList;
itemList.append(new QStandardItem());
model->appendRow(itemList);
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), this, SLOT(myslot_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
model->item(0,0)->setData("supercool value", Qt::DisplayRole); // // should emit 1 role, but 0 are arriving
model->item(0,0)->setData("another supercool value", Qt::UserRole); // // should emit 1 role, but 0 are arriving
QVector<int> roles;
roles.append(Qt::DisplayRole);
roles.append(Qt::UserRole);
emit model->dataChanged(model->index(0,0), model->index(0,0), roles); // works. roles.count() == 2
}
MainWindow::myslot_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
qDebug() << roles.count();
}
给定输出:
0
0
2
预期产出:
1
1
2
我知道信号中QVector的角色是可选的。在某种程度上,Qt可以省略角色并且只使用默认角色吗?也许我必须使用正确的信号(不是你可以省略角色的那些......),但我不知道如何。
抱歉英文不好,谢谢你的帮助! ;)
编辑1:进一步调查:
我已经浏览了Qt源代码并在qstandarditemmodel.cpp中找到了这个
void QStandardItem::setData(const QVariant &value, int role)
{
Q_D(QStandardItem);
role = (role == Qt::EditRole) ? Qt::DisplayRole : role;
QVector<QStandardItemData>::iterator it;
for (it = d->values.begin(); it != d->values.end(); ++it) {
if ((*it).role == role) {
if (value.isValid()) {
if ((*it).value.type() == value.type() && (*it).value == value)
return;
(*it).value = value;
} else {
d->values.erase(it);
}
if (d->model)
d->model->d_func()->itemChanged(this);
return;
}
}
d->values.append(QStandardItemData(role, value));
if (d->model)
d->model->d_func()->itemChanged(this);
}
使用setData时,使用的函数itemChanged不关心角色。似乎dataChanged中的roles参数对您来说是可选的,并且从未被本机Qt函数使用。
编辑2:更多调查......
我逐步完成了setData函数。 以下是setData调用itemChanged()时的代码段:
void QStandardItemModelPrivate::itemChanged(QStandardItem *item)
{
Q_Q(QStandardItemModel);
Q_ASSERT(item);
if (item->d_func()->parent == 0) {
// Header item
int idx = columnHeaderItems.indexOf(item);
if (idx != -1) {
emit q->headerDataChanged(Qt::Horizontal, idx, idx);
} else {
idx = rowHeaderItems.indexOf(item);
if (idx != -1)
emit q->headerDataChanged(Qt::Vertical, idx, idx);
}
} else {
// Normal item
QModelIndex index = q->indexFromItem(item);
emit q->dataChanged(index, index);
}
}
如前面调查中所述,setData调用itemChanged
,后者又调用emit q->dataChanged(index, index);
在那里我们看到dataChanged省略了role参数。这意味着我之前的猜测,即Qt原生函数不使用角色,似乎已经确认。
答案 0 :(得分:1)
来自信号QAbstractItemModel::dataChanged()
的文件(我强调):
<强>
void QAbstractItemModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = ...)
强>
[...]
可选的 roles 参数可用于指定实际修改了哪些数据角色。 roles 参数中的空向量表示应将所有角色视为已修改。
如您所述,Qt的QStandardItemModel
实施并不关心指定数据更改的角色,而是指定应更新所有数据。
问题的答案(你没有问过)是:
如果使用特定的roles
集调用您的广告位,则可以对其进行优化。如果roles
为空,则需要获取与您的视图相关的所有角色的数据。