【发布时间】:2017-10-17 22:22:19
【问题描述】:
这是我在源模型中的setData:
bool TreeModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
if (!index.isValid() || role != Qt::EditRole)
return false;
TreeItem* item = static_cast<TreeItem*>(index.internalPointer());
item->setData(index.column(), value);
emit dataChanged(index, index);
return true;
}
我将源模型的dataChanged 信号连接到代理模型的dataChanged 信号,但是只有当我点击它时,显示代理模型的表格视图才会更新。在这种情况下会出现什么问题?我应该以某种方式在代理模型中手动发出dataChanged 信号吗?
来自模型的数据:
QVariant TreeModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid() || role != Qt::DisplayRole)
return {};
TreeItem* item = static_cast<TreeItem*>(index.internalPointer());
return item->dataAt(index.column());
}
来自 TreeItem:
QVariant TreeItem::dataAt(int n) const
{
if (n < m_data.size())
return m_data[n];
else
return {};
}
更新:
我认为代理模型应该在来自TreeModel::dataChanged 的索引上使用mapFromSource,但似乎代理不调用mapFromSource,所以我不明白更新是如何发生的。
当我尝试通过代理模型编辑树项目时,同样的行为 - 源模型不会更新它的视图。但是在这种情况下,我可以使用源模型在代理中设置数据:
bool ProxyModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
// if (!index.isValid() || role != Qt::EditRole)
// return false;
// TreeItem* item = static_cast<TreeItem*>(mapToSource(index).internalPointer());
// item->setData(index.column(), value);
// emit dataChanged(index, index);
// return true;
return sourceModel()->setData(mapToSource(index), value, role);
}
更新:
最后,似乎我几乎明白了。 KDE 的 KDescendantsProxyModel 模型本身发出 dataChanged 信号,所以我还创建了 onSourceDataChanged 插槽并将其连接到源的 dataChanged 信号(它现在只更新第一个索引):
void ProxyModel::onSourceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight,
const QVector<int>& roleNames)
{
auto index = mapFromSource(topLeft);
emit dataChanged(index, index);
}
唯一的问题:这是正确的方法还是我做错了什么?
【问题讨论】:
-
可能,问题出在您的
item->setData。请显示您的TreeModel::data和TreeItem::setData方法的代码。顺便说一句,要编写更清晰的代码,不要忘记使用emit宏:emit dataChanged(index, index);。 -
我在 TreeModel::setData() 方法中发出 dataChanged 信号。显示 TreeModel 的树视图正在按预期更新。
-
不幸的是,我不知道问题出在哪里。顺便说一句,如果您在代理模型中访问
index.internalPointer(),它将无效。您需要直接在源模型索引中访问内部指针。 -
我认为这取决于索引的创建方式。如果我在代理中创建索引为 createIndex(row, column, s.internalPointer()),其中“s”是源模型的索引 - 代理的索引将包含有效指针。
-
仅当您自己在代理中创建索引时。因为我在我的项目中遇到了类似的问题。