QAbstractProxyModel is not updated by dataChanged () signal
Here's mine setData
in the original 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 have hooked up a signal dataChanged
from the original model to dataChanged
the proxy model signal, but a table view that shows the proxy model is updated only if I click on it. What could be wrong in this situation? Do I have to emit the dataChanged
signal manually somehow in the proxy model?
Model data:
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 assumed that the proxy model should be used mapFromSource
for the indexes that came from TreeModel::dataChanged
, but it seems that the proxy doesn't call mapFromSource
, so I don't understand how the update happens.
Also the same behavior when I try to edit a tree item via the proxy model - the original model does not update it. However, in this case, I can set the data in the proxy using the original 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 like I almost figured it out. The KDE KDescendantsProxyModel model emits the dataChanged
signal itself, so I also created a slot onSourceDataChanged
and connected it to the source signal dataChanged
(now it only updates the first index):
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: is it right or is something wrong?
source to share
I have connected signal
dataChanged
from original model todataChanged
proxy mode signal
You cannot re-radiate the signal of the original model, as this signal is indexed to the wrong model. Remember the contract dataChanged
: the index it emits is a valid index for the model the signal is coming from. However, you are emitting an index that is not valid for your proxy model.
You need to wire the original signal to a slot or functor, which then maps the index to the proxy index and emits that.
source to share