[Interest] Models and aborting structural changes

Elvis Stansvik elvstone at gmail.com
Thu Jun 4 09:00:01 CEST 2020


Den ons 3 juni 2020 10:38Jonathan Purol <contact at folling.de> skrev:

> Hello everyone,
>
> I've been in a bit of a tough spot recently with `QAbstractItemModel`.
> I'll try to delineate my situation, then my problem, and then the
> potential solutions and why I think they're all inferior to what I wish
> to have.
>
> We have a desktop applications using QtWidgets, however instead of a
> data model we obtain our data from an "external source" (this is a
> little complicated in our use case, but you can think of it as a remote
> server for all intents and purposes).
> Now the server emits events for changes in the underlying data model.
> For example there is an event for `itemAdded` with all appropriate data
> points being passed to us via a web socket.
> This is all fine and dandy.
>
> The problem arises when I try to now connect this to the model
> representing all `Item` objects.
> Qt requires both `beginInsertRows` and `endInsertRows` to be called when
> these changes are made. Furthermore it requires the underlying data to
> really only be changed in-between those calls. I.e. `rowCount` should
> return something different at the time `beginInsertRows` is called than
> at the time `endInsertRows` is called. So far so good. But we don't
> really have that in-between point. We only get notified when the change
> has already happened.
>
> There are a few solutions I could see here:
> 1. Keep a local cache of all of the data, update it incrementally when
> changes come through with this pattern:
> - change events arrives
> - emit "begin change"
> - update internal data
> - emit "end change"
>
> 2. Keep a local cache of all the data on a per-model basis then repeat
> as can be seen above
>
> I dislike both of these changes, even if they do solve the issue
> flawlessly. The reason for that is that it is quite a bit of overhead.
> Both regarding code complexity as well as regarding memory usage and
> performance. Don't get me wrong, having a cache is important, and we
> will have one as well. What doesn't stick right with me is a cache that
> in turn keeps track of all the data all the time.
>
> Now you might say "why not just have the server emit both a "before" and
> a "after" change event for whatever happens.
> Yeah, I would love to do that - but with Qt's current setup it just
> isn't possible.
> What Qt is missing is an `abortInsertRows` function to reset the model's
> internal state.
> There are many, many things that can go wrong in our setup, even IF the
> data was successfully updated. And if we cannot tell Qt to revert the
> changes in case such an error occurs we cannot possible use this approach.
> The only solution I would see here would be to call
> `begin/endResetModel` in case an error occurs, but that sounds like
> trying to put a nail into a coffin with a wrecking ball.
>

I understand your problem. I've not been in your situation, but how about

- Change server to emit before and after events, plus a cancel event.

- Upon receiving a before event, call beginInsertRows,

- Upon receiving an after event, call endInsertRows,

- Upon receiving a cancel event, call endInsertRows, then call
beginRemoveRows, remove the cancelled rows, then call endRemoveRows.

Could that work? I don't think the models would ever show the cancelled
data, as control never returned to the event loop during the dance in the
last step.

Cheers,
Elvis


> My questions now are as follows:
> Is there any chance `abort*` methods would be added in the future?
> Could I perhaps add such a method myself?
> Is it safe to just call `endInsertRows` when no changes were made?
> Is there a simple solution I overlooked?
>
> Sincerely,
> Jonathan Purol
>
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> https://lists.qt-project.org/listinfo/interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20200604/d79e75c3/attachment.html>


More information about the Interest mailing list