Qt:正确地将undo框架与QGraphicsScene集成

时间:2013-01-31 16:57:25

标签: c++ qt undo qgraphicsscene

我正在编写一个基于QGraphicsScene画布的Qt应用程序,其上有可移动的形状,我正在尝试集成undo-redo功能。对于大多数函数,比如创建和删除形状,在QGraphicsScene本身上实现它是相当简单的,但我希望元素是可移动的,并且运动是可撤销的。现在我在场景中使用橡皮筋拖曳模式,并在项目上使用ItemIsSelectableItemIsMovable标志。问题是,似乎没有好地方可以创建QUndoCommand来表示形状移动。如果我在QGraphicsScene::itemChange方法中执行此操作,则选择并移动两个或多个形状会导致不同对象的单独撤消命令被交错,因此无法合并,因此撤消会导致意外行为。 QGraphicsScene中没有任何事件在其项目移动时被调用,我可以看到,所以我有点卡住了。

我看到的最糟糕的情况是我在自定义ItemIsMovable对象上禁用QGraphicsItem标志并完全处理QGraphicsScene鼠标事件中的移动,但正确地重新实现该功能似乎非常复杂(我检查了Qt如何在内部执行它,并且有很多代码用于处理复杂的情况,例如选择对象及其某些子对象的位置)。这似乎是撤销堆栈最明显的用例(以至于撤消框架的示例程序是一个QGraphicsScene程序,就像我的一样,除非没有多个对象移动支持)所以看起来很奇怪没有重新实现核心功能的重要部分,没有内置的方法。有没有人有任何见解或程序实例可以做到这一点?

1 个答案:

答案 0 :(得分:4)

我认为这有些愚蠢地解决了这个问题。我在自定义形状中添加了preMovePoint属性,在mousePressedEvent的{​​{1}}中,我将每个选定形状的QGraphicsScene设置为各自的当前位置,在preMovePoint中,创建了从mouseReleaseEvent到每个形状的当前preMovePoint的复合移动命令。我仍然有兴趣知道是否有更好的方法。