Here is my setData
in source model:
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;
}
I connected dataChanged
signal from source model to dataChanged
signal of proxy model but the table view which shows proxy model updates only if I click on it. What can be wrong in this situation? Should I somehow emit dataChanged
signal manually in proxy model?
Data from model:
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());
}
And from TreeItem:
QVariant TreeItem::dataAt(int n) const
{
if (n < m_data.size())
return m_data[n];
else
return {};
}
Update:
I supposed that proxy model should use mapFromSource
on indices that came from TreeModel::dataChanged
but it seems proxy doesn't call mapFromSource
, so I don't understand how updating happens.
Also the same behaviour when I try to edit tree item through proxy model - source model doesn't update it's view. However in that case I can set data in proxy using source model:
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);
}
UPDATE:
Finally, it seems that I'm almost got it. KDE's KDescendantsProxyModel model emitting dataChanged
signal itself, so I also created onSourceDataChanged
slot and connected it to source's dataChanged
signal (it updates only first index now):
void ProxyModel::onSourceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight,
const QVector<int>& roleNames)
{
auto index = mapFromSource(topLeft);
emit dataChanged(index, index);
}
The only question: is it a right way or I do something wrong?
I connected
dataChanged
signal from source model todataChanged
signal of proxy mode
You cannot re-emit the source model's signal, as that signal has the index to a wrong model. Remember dataChanged
's contract: the index it emits is a valid index on the model the signal comes from. Yet you're emitting an index that's not valid on your proxy model.
You need to connect the source's signal to a slot or functor that then maps the index to the proxy's index and emits that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With