Qt :: QUndoCommand问题和可能的解决方案。

我们正在开发Qt中的3D编辑应用程序。

我们需要实现一个“操作堆栈”,该堆栈允许用户对其操作调用undo-redo。

我们正在将QUndoStack与QUndoCommand Qt类一起使用。

该应用程序基于MVC模式,因此视图(QGLWidget)知道如何绘制场景结构。

我们有滑块(QSlider)来平移/旋转/缩放3D对象(网格),并且我们需要实时显示变换的效果。

例如,如果我选择了一个对象,并且正在移动“ X平移滑块”,则我想看到该对象在拖动滑块时沿X轴移动。
问题是要使实时编辑与操作堆栈一起使用。实际上,应该推入堆栈的“不可撤消”操作是滑块的总移动量(从压紧到释放滑块)。

我们发现了两种方法:


当我拖动滑块(在每个valueChanged信号处)时,
转换应用于模型并更新QGLWidget
在每个滑块刻度之后立即移动。释放滑块时,
必须将命令压入堆栈。 QUndoStack自动调用
按下命令时执行QUndoCommand :: redo()操作。阻止
该操作要执行两次(第一次授予
实时效果,在QUndoStack :: push()调用中的第二个)
调用QUndoStack :: push()进行逆变换
到对象(从滑块的总移动量获得),然后我
将命令推入堆栈。
QUndoStack尝试在结果相同时尝试合并命令
从对QUndoCommand :: Id()的调用。当我拖动滑块(在
每个valueChanged信号)都会生成一个QUndoCommand,
立即将其推入堆栈,堆栈将其与
如果它们具有相同的Id(),则在顶部命令,然后堆栈调用
要插入命令的redo(),然后是QGLWidget
更新并获得实时效果。


对于第二个,每个滑块滴答都会生成“ Command”类的实例,而对于第一个,实时操作的返回将还原为仅按命令并保持一致状态。

在“良好的编程”方面哪种解决方案更好?在性能方面哪种更好?

最佳答案

我认为您正在寻找QUndoStack::beginMacro()QUndoStack::endMacro()

可以用来合并撤消堆栈中的一系列命令,使它们作为原子操作完成/撤消。

09-06 18:06