c++ - QGraphicsScene : How to map item movements into QUndoCommand?

标签 c++ qt

我正在尝试创建一个 QUndoCommand 的子类,它表示一个或多个 QGraphicsItem 的移动。如果一次移动多个项目(首先选择它们),这应该表示为 QUndoStack 中的单个命令。

由于整个移动逻辑(包括选择)已经由 QGraphicsScene 实现,我不确定创建撤消命令的最佳位置。

Qt提供的undoframework实例子类QGraphicsScene并覆盖mousePressEvent()/mouseReleaseEvent()来执行一些手动 HitTest 。这真的是要走的路吗?

恐怕这种方法可能会遗漏一些特殊情况,例如生成的撤消命令不会完全反射(reflect)内部 Qt 实现所执行的相同 Action 。例如,某些项目可能未设置 ItemIsMovable 标志。此外,当一次移动多个项目时,最好只存储增量移动而不是新旧位置。

如果您能提供一些简短的示例代码/草图以进行说明,那就太好了。

最佳答案

我个人会包装和封装 QGraphicsScene 并在那里实现撤消/重做。这允许定义您自己的和更清晰的界面,摆脱所有您不需要的功能的困惑。如果将来出现这种需要,它还可以更轻松地用另一个 API 替换 QGraphicsScene,并使您的核心内容更具可移植性。

Qt 中的许多高级类,尤其是那些用于图形的类,并不完全是我所说的“前沿”,这同样适用于 Qt 为它们提供的基本示例。有几个使用 Qt 的专业图形应用程序,但没有一个使用像 QGraphicsScene 这样的东西。我想这样做的原因也是我根据自己使用 Qt 的经验推断的原因——尽管它可能是一个框架,但有很多东西缺失了,而且很多东西并没有真正发挥作用人们对专业软件的期望方式,甚至是此类工作流程中的通用逻辑。 Qt 是由非常优秀的程序员开发的,但他们似乎没有在实际图形应用程序工作流程方面有经验的人来指导他们。

专注于具有所需功能的包装器,并使其与 QGraphicsScene 一起使用,而不是直接使用它。这样你就不太可能错过一些东西,你的设计也更加独立和干净。这同样适用于撤消 API,不要觉得必须使用 Qt,我自己已经尝试过并最终实现了我自己的,因为我发现 Qt 提供的那个相当“僵硬”。

在一次移动多个项目的情况下 - 是的,这应该创建一个撤消条目,它将撤消选择组的移动,该选择组将包含所有选定的项目。您是使用增量还是头寸 - 这完全取决于您。当您移动多个选定项目时,delta 确实更有意义,因为选择组并不是真正具有位置的项目。

另一个考虑因素是,如果您计划让历史在不同的 session 中保持持久 - 您不能依赖指针,因为每次运行应用程序时它们都是任意的。我的策略是实现一个唯一的整数 ID 和一个存储每个项目的 ID 和指针的关联注册表。然后您使用历史记录的 ID,这将在内部映射到实际项目的指针。

关于c++ - QGraphicsScene : How to map item movements into QUndoCommand?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32973326/

相关文章:

c++ - 我应该在 C++11 中显式声明转换运算符吗?

c++ - 如何像winhex一样直接读/写usb(磁盘)?

c++ - 如何为 QPushButton 分配快捷方式?

qt - 使用 fontconfig 支持为 Linux x86 构建 Qt

python - 在 QT 中运行应用程序时防止 Python 内核崩溃

python - 防止长 QComboBox 向上移动

c++ - Gearman 客户端在网页中失败,但在命令行界面中成功?

c++ - 使用 C++ 读取 HTML 文本

qt - 在 CLion 中,Qt Console 和 Qt Widgets Executable 项目模板有什么区别

c++ - 为什么 T const&& 不是转发引用?