Qt: correctly undo frame with QGraphicsScene

I am writing a Qt application based on a canvas QGraphicsScenewith moving shapes on it, and I am trying to integrate undo and undo functions. For most functions, such as creating and deleting shapes, it’s pretty trivial to implement on the actual one QGraphicsScene, but I want the elements to be movable and the movement to be canceled. Right now I am using dragmode rubber tape on stage and flags ItemIsSelectableand ItemIsMovablefor elements. The problem is that there seems to be no good place to create a QUndoCommandfigure to represent the movement. If I do this in a method QGraphicsScene::itemChange, then selecting and moving two or more shapes leads to separate undo commands for different objects alternating and therefore cannot be combined, so undoing leads to unexpected behavior. ATQGraphicsScene there is no event that is triggered when its elements move around what I see, so I'm kind of stuck.

The worst scenario that I see is that I turned off the flag ItemIsMovablein my user objects QGraphicsItemand completely handled the movement in mouse events QGraphicsScene, but re-executing this function seems pretty complicated (I checked how Qt does it internally, and there are quite a few code for handling complex cases, for example, when an object and some of its children are selected). This seems like the most obvious use case for the undo stack (so much so that the sample program for the undo framework is a programQGraphicsScene, the same as mine, except without the support of several objects), so it seems strange that there is no built-in - to do this without overriding a significant part of the main functions. Does anyone have any ideas or examples of programs that do this?

+5
source share
1 answer

I decided this is somewhat hacky, I think. I added a property preMovePointto my custom shapes and in mousePressedEvent QGraphicsScene, I set preMovePointeach of the selected shapes to the corresponding current positions, and to mouseReleaseEventcreate a compound, move the command from preMovePointto the current of poseach shape. I would still be interested to know if there is a better way.

+4
source

All Articles