首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >信号:QStandarditemmodel::datachanged(.)在使用QStandarditemmodel::setData(.)时不发出角色

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

Stack Overflow用户
提问于 2018-06-12 13:16:44
回答 1查看 1.7K关注 0票数 1

我的问题是,当使用

代码语言:javascript
复制
QStandarditemmodel::setData(const QModelIndex &index, const QVariant &value, int role)

这个角色似乎从来没有被释放过。

示例:

代码语言:javascript
复制
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();
}

给定产出:

代码语言:javascript
复制
0
0
2

预期产出:

代码语言:javascript
复制
1
1
2

我知道信号中的角色QVector是可选的。Qt是否有可能忽略角色,而只使用默认角色?也许我必须使用正确的信号(而不是那些你可以省略角色的信号.)解释得很清楚,但我不知道怎么说。

对不起,英语不好,谢谢你的帮助!)

编辑1:进一步调查:

我已经浏览了Qt源代码,并在qstandarditemmodel.cpp中找到了这个

代码语言:javascript
复制
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()时的片段:

代码语言:javascript
复制
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本机函数不使用角色,似乎得到了确认。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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为空,则需要获取与视图相关的所有角色的数据。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50818216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档