Qt-interest Archive, February 2007
Re: Resetting a sub-tree of a QAbstractItemModel
Message 1 in thread
On Wednesday 31 January 2007 14:15, Craig Ringer wrote:
> Hi folks
>
> I'm facing a variant of a problem that appears to come up on this list,
> and was hoping for a few ideas. I'm working on a QAbstractItemModel that
> presents a directed cyclic graph as a tree to the user. To handle this
> I'm demand-building an intermediate tree that keeps track of parentage
> and node aliases. That all works well.
>
> The problem arises when the user triggers a non-trivial modification to
> the model tree, eg by changing a link from a node to another part of the
> graph.
>
> QAbstactItemModel doesn't seem to provide a clean way to handle this. It
> permits one to reset the model completely, forcing all views to discard
> their state and start again. It's also able to easily add or remove
> ranges of rows. What it can't seem to easily do is reset a subtree of
> the model completely, as reset() resets the whole model.
>
> I've tried to achieve the same effect by removing all child rows from
> the node being modified using beginRemoveRows(...) and endRemoveRows(),
> then adding back the new set (the same way) of rows after the change is
> made. The old node objects are deleted after the rows are removed and
> they should no longer be accessible, and new ones are constructed when
> the new rows are added.
>
> I'd expect this to work, and in some situations it initially seems to.
> However, sooner or later the model ends up being passed a QModelIndex
> that points to deleted memory by the view, and subsequently crashing -
> and _ONLY_ after an attempted sub-tree reset. This is despite the fact
> that all rows that could've referred to those grandchild nodes were
> removed from the view using beginRemoveRows(...) / endRemoveRows(). Now,
> I don't deny the fairly strong possibility that I've simply made an
> error in this fairly complex code, but I'm at a bit of a loss as to how
> or where.
>
> What I'm hoping is that:
>
> - Perhaps Qt 4.3.x could contain a method
> QAbstractItemModel::reset(const QModelIndex& index)
> to reset the tree at and below `index'.
>
> - Someone might have a few ideas about how to sanely
> reset a sub-tree of a model in qt 4.2.x .
>
> Any help or suggestions would be very much appreciated at this point.
> --
> Craig Ringer
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body. List archive and information:
> http://lists.trolltech.com/qt-interest/
During the 4.2 development a number of edge cases for cyclic trees were fixed,
but there was one major change to QTreeView that was not fixed until after
the release and was put into 4.3. Check out the 4.3 snapshot and see if it
is still segfaulting for you.
http://www.trolltech.com/developer/downloads/qt/snapshots
A short term work around is to first remove all of the nodes, set them
internally to a null state (so your functions can know that this node is
dead) and after the final endRemoveRows() actually delete the nodes.
-Benjamin Meyer
--
[ signature omitted ]