以下是源模型中的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 {};
}
更新:
我认为代理模型应该对来自mapFromSource
的索引使用TreeModel::dataChanged
,但似乎代理不会调用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);
}
唯一的问题:这是正确的方式还是我做错了什么?
答案 0 :(得分:1)
我将来自源模型的
dataChanged
信号连接到代理模式的dataChanged
信号
您无法重新发射源模型的信号,因为该信号具有错误模型的索引。记住dataChanged
的合同:它发出的索引是信号来自模型的有效索引。但是,您发布的索引在代理模型上无效。
您需要将源信号连接到插槽或仿函数,然后将索引映射到代理的索引并发出该信号。