我的问题是,当使用
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中的角色参数对您来说只是可选的,而本机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忽略了角色参数。这意味着我先前的猜测,即Qt本机函数不使用角色,似乎得到了确认。
发布于 2018-06-18 12:23:17
来自信号QAbstractItemModel::dataChanged()的文档(由我强调):
void QAbstractItemModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = ...)..。 可选角色参数可用于指定实际修改了哪些数据角色。角色参数中的空向量意味着all 应该被视为修改。
正如您所述,Qt的QStandardItemModel实现并不是为了指定更改了哪些角色数据,而是指定应该更新所有的数据。
这个问题的答案(你没有问)是:
如果您的插槽是用一组特定的roles调用的,则可以为此进行优化。如果roles为空,则需要获取与视图相关的所有角色的数据。
https://stackoverflow.com/questions/50818216
复制相似问题