信号:QStandarditemmodel::datachanged(...) 在使用 QStandarditemmodel::setData(...) 时不发出角色

SIGNAL: QStandarditemmodel::datachanged(...) does not emit roles when using QStandarditemmodel::setData(...))

我的问题是,当使用

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 原生函数不使用角色,似乎得到了证实。

来自信号文档QAbstractItemModel::dataChanged()(我强调):

void QAbstractItemModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = ...)
[...]
The optional roles argument can be used to specify which data roles have actually been modified. An empty vector in the roles argument means that all roles should be considered modified.

如您所述,Qt 的 QStandardItemModel 实现不关心指定哪些角色数据已更改,而是指定应更新 所有 数据。

问题的答案(你没有问)是:

如果您的广告位是使用一组特定的 roles 调用的,您可以为此进行优化。如果 roles 为空,您需要获取与您的观点相关的 所有 个角色的数据。