Qt::QUndoCommand 问题和可能的解决方案。
我们正在开发 Qt 中的 3D 编辑应用程序。
我们需要实现一个“操作堆栈”,允许用户在他的操作上调用 undo-redo。
我们将 QUndoStack 与 QUndoCommand Qt 类一起使用。
该应用程序基于 MVC 模式,因此 View (QGLWidget) 知道如何绘制场景结构。
我们有滑块(QSlider)来平移/旋转/缩放 3D 对象(网格),我们需要实时显示变换的效果。
例如,如果我选择了一个对象并且我正在移动“X 平移滑块”,我希望在拖动滑块时看到该对象沿 X 轴移动。问题是让实时编辑与操作堆栈一起工作。事实上,应该被压入堆栈的“可撤消”操作是整个滑块移动(从按下到释放滑块)。
我们发现了两种方法:
当我拖动滑块时(在每个 valueChanged 信号处),转换将应用于模型,并且 QGLWidget 在每个滑块滴答后立即更新。在释放滑块时,必须将命令推入堆栈。当一个命令被推送时,QUndoStack 会自动调用 QUndoCommand::redo() 动作。为防止操作执行两次(第一次授予实时效果,第二次在 QUndoStack::push() 调用时),在调用 QUndoStack::push() 之前应用逆变换对象(从总滑块移动中获得),然后我将命令推送到堆栈。
当调用 QUndoCommand::Id() 得到相同的结果时,QUndoStack 会尝试合并命令。当我拖动滑块时(在每个 valueChanged 信号处)生成一个 QUndoCommand 并立即推送到堆栈上,如果它们具有相同的 Id(),堆栈会将其与顶部的命令合并,然后堆栈调用 redo( ) 对于正在插入的命令,则 QGLWidget 更新并获得实时效果。
对于第二个,每个滑块刻度都会生成一个“命令”类的实例,而对于第一个,实时操作会被还原,只是为了推送一个命令并保持一致的状态。
就“良好的编程”而言,哪种解决方案更好?在性能方面哪种解决方案更好?