[Interest] Models and aborting structural changes
roland at logikalsolutions.com
Sun Jun 7 19:43:17 CEST 2020
On 6/4/20 5:00 AM, Jonathan Purol wrote:
>> 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.
> I have thought about that and believe that in theory it could work
> although it would require some testing.
> What should definitely work is to call `begin/endResetModel` in case an
> error occurs, though that has obvious drawbacks as well. I'd have to
> give it a test run. It does seem like a very hacky solution however.
> I've spoken with my partners and for now we'll just go with a cache that
> duplicates all necessary data - from what I understand we only really
> have to duplicate structural information, since the normal "data
> changes" don't require the begin-end system (i.e. `emit dataChanged`).
>> Thinking a bit more (and I'm no expert), if I understand your setup
>> correctly, I still think there's a race that could confuse your views.
>> If I understand you right, your model always reports "live" data from
>> the server, which I presume means your data(..) returns data fetched
>> from the server.
>> If so, then I think this scenario could happen (?):
>> 1. View requests some data at index X, and gets back data Y.
>> 2. Something happens on the server so the data changes.
>> 3. The server sends out a change event.
>> 4. View again requests some data at index X, but gets back data Z (!).
>> 5. The change event arrives at your application.
>> This is a situation in which the data returned at some index changes
>> from the POV of the view, with no beginInsertRows/endInsertRows in
>> between, which I think is a breach of the Qt model/view contract.
>> I may be wrong though, so maybe someone more knowledgeable can step in
>> an confirm/deny.
> Yeah this would definitely break the contract. Furthermore - I believe
> Qt wouldn't even poll for any information about index X if it hasn't
> been established that index X exists yet (either by a remove, insert, or
> move command). Anything else would seem like a false implementation of
> what I expect the view-classes to do.
> I genuinely believe that the `abort*` functions are just... missing - it
> seems like such an inherent feature to me. Perhaps the complexity of
> implementing it was considered too large to be worth the hassle. In the
> forums people say "just verify everything beforehand" - but not every
> situation warrants that.
> Thank you for your time and effort! If I try out the "just call the
> reverse if it fails" and it works I'll let you know!
You can't really use any of the SQL Model classes (or those like them)
in a client/server situation.
During the green-screen days of client/server we had one section of the
screen for entry and another section for displaying the scrolling data.
The entry portion would send a message back to the server with the new
data. Server would chew on it. Eventually, when successful, it would
send out a success message that contained new data for the scrolling
region. Sometimes we got a message back to display in the status bar at
the bottom of the screen, telling the user the update tanked.
These systems were multi-user. 50+ people all entering and editing data.
Today I guess the "trendy" name for this is publish-subscribe. We called
it echo because good terminals had "local echo" disabled. When you typed
a character on the keyboard it did not appear on the screen until the
computer echoed it back.
The default models for things in Qt implement the "bad" terminal feature
of local echo. When you typed a key it displayed on the terminal _then_
it was sent to the computer. You could type a great many keys that never
arrived and you would only notice it if some of the things you typed
were supposed to do something. If you were just typing text into a
document you could go a very long time before discovering something was
This is basically the problem you are having. The Qt architecture
implements the "bad" terminal feature of local echo. Changes take place
in the model _then_ they get sent to the server.
You need to turn your widget into a "dumb terminal" that just echos what
the server sends it. You won't be able to use the prepacked data model
Roland Hughes, President
More information about the Interest