[Qt-interest] dataChanged() SIGNAL in proxy models

Stephen Kelly steveire at gmail.com
Thu Jul 1 11:04:13 CEST 2010


Mandeep Sandhu wrote:

> Does the default implementation of QAbstractProxyModel handle the
> dataChanged() from the source model?

Nope.

> If no, is it the sub-class's responsibility to generate a
> dataChanged() SIGNAL?

Yes.

> The proxy models doc does not mention anything
> on this.
> 
> I have a QStringListModel on which I have applied my proxy model to
> return the data in a tabular manner (rows/cols).

I would say it's a better idea to write your own table model instead of 
trying to turn a list into a table. Adding extra columns by using a proxy 
model is a bad idea and will likely cause QPersistentModelIndexes to become 
corrupted.

> 
> Initially I thought that the signal will be handled by
> QAbstractProxyModel class. But that did not work.
> So I though of emitting the signal on my own, whenever the same signal
> is emitted by the source model (who's data is being proxied).
> 
> <snip>
> ...
> void setSourceModel(QAbstractItemModel *sourceModel)
> {
>     QAbstractProxyModel::setSourceModel(sourceModel);
> 
>     connect(sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
>             this, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
> }
> ...
> </snip>
> 
> This should work, right? 

Nope. The QModelIndexes in the signal are from the source model. You need to 
map the source indexes to the proxy.

void sourceDataChanged(const QModelIndex &sourceTopLeft, const QModelIndex 
&sourceBottomRight)
{
  const QModelIndex proxyTopLeft = mapFromSource(sourceTopLeft);
  const QModelIndex proxyBottom = mapFromSource(sourceBottomRight);
  const QModelIndex proxyBotttomRight = 
proxyBottom.sibling(proxyBottom.row(), proxyBottom.column() + 
number_of_extra_columns);

  emit dataChanged(proxyTopLeft, proxyBottomRight);
}

> But it doesn't.
> 
> Instead of directly linking a SIGNAL to another SIGNAL, I even made it
> go through a SLOT which emits the dataChanged() signal just to see if
> the signal was being emitted by the source model or not. The signal
> was emitted but somehow the view did not react to it.
> 
> If I directly attach the QStringListModel to a QListView widget,
> things obviously work (i.e the view reacts to changes to the data in
> the model).

I suggest you implement QAbstractTableModel instead.

All the best,

Steve,

> 
> Do see any problem in the above approach?
> 
> Thanks,
> -mandeep





More information about the Qt-interest-old mailing list