【问题标题】:Qt: Properly integrating undo framework with QGraphicsSceneQt:将撤消框架与 QGraphicsScene 正确集成
【发布时间】:2013-01-15 20:50:08
【问题描述】:

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

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

【问题讨论】:

    标签: c++ qt undo qgraphicsscene


    【解决方案1】:

    我认为我解决了这个问题。我在自定义形状中添加了一个preMovePoint 属性,在QGraphicsScenemousePressedEvent 中,我将每个选定形状的preMovePoint 设置为它们各自的当前位置,并在mouseReleaseEvent 中创建了一个合成将命令从preMovePoint 移动到每个形状的当前pos。我仍然想知道是否有更好的方法。

    【讨论】:

    • 我想出了一个类似的 hackish 修复,涉及每个 QGraphicsItem 中的先前位置堆栈,然后将更改的项目推送到撤消堆栈。它很丑,但它有效。感谢您的提问和回答。
    • 我不会说这是 hackish,因为这是在官方 Qt 示例中实现的方式:doc.qt.io/qt-5/qtwidgets-tools-undoframework-example.html
    猜你喜欢
    • 2017-04-02
    • 2012-07-18
    • 2018-02-04
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    • 2018-01-07
    • 1970-01-01
    • 2013-05-29
    相关资源
    最近更新 更多