A full reset (begin/endResetModel, and the QTableView::reset() reached via
modelUpdated()->onModelUpdated()) releases every open item editor through
deleteLater(). During fast hex editing that deferred delete races against
Qt's deferred editor commit/close (_q_commitDataAndCloseEditor) and ends up
dereferencing a freed editor -> crash (read access violation on editor).
//
A byte edit never changes the grid: columnCount is constant and rowCount
only changes when the file size or shown page changes. So when the row
count is unchanged we repaint the visible cells in place with dataChanged()
and emit neither the model reset nor modelUpdated() - editors are left
completely untouched. A genuine layout change (size/structural change, which
never coincides with an open cell editor) still takes the full-reset path.
1. The PeTreeModel base constructor already connected modified() -> onNeedReset()
with a direct connection. Re-route it (and marked()) to queued connections so
the full model reset never runs in the middle of a cell-editor commit: reset()
clears the view's editor registry, which tears down the active editor mid-edit
and makes Qt log "editor does not belong to this view" on the following
commitData()/closeEditor(). Deferring the reset by one event-loop cycle lets the
edit fully unwind first; for non-edit changes (fill/paste/undo) it is an
invisible one-tick delay. (This also drops a pre-existing redundant connection.)
2. Queued so the advance (setCurrentIndex + edit of the next cell) runs after the
current editor's commit/close has unwound AND after the queued model reset in
HexDumpModel; otherwise the freshly opened next-cell editor would be torn down
by that reset. Ordering is guaranteed: modified() is emitted before dataSet(),
so the reset is queued ahead of this advance.