假设我有一个
QUndoCommand
用于创建对象和更改颜色。
class ObjectInterface{
QColor color;
}
class CommandCreateObject : public QUndoCommand {
public:
CommandCreateObject(QString const& objectName );
void undo() Q_DECL_OVERRIDE;
void redo() Q_DECL_OVERRIDE;
}
class CommandChangeColor : public QUndoCommand{
public:
CommandCreateObject(QString const& objectName );
void undo() Q_DECL_OVERRIDE;
void redo() Q_DECL_OVERRIDE;
}
现在 CommandCreateObject 创建的对象每次都是不同的类,因为它调用工厂方法。
所以创建的对象本身正在构造函数中设置他的值。假设它将他的颜色设置为蓝色。因为更改颜色本身是一个命令,我也将其称为命令。
// lets also say there is a Model from which all Commands are triggered
class Model {
static QundoStack *undoStack;
static void changeColor(ObjectInterface *target, QColor const& color) {
undoStack->beginMacro("Change Color");
undoStack->push( new CommandChangeColor(target,color));
undoStack->endMacro();
}
staic void createObject(QString const& objectName) {
undoStack->beginMacro("Create Object");
undoStack->push( new CommandCreateObject(objectName));
undoStack->endMacro();
}
}
class BlueObject : public ObjectInterface {
BlueObject() {
Model::changeColor(this,Qt::blue);
};
}
现在解决问题:
如果我创建对象,撤消堆栈看起来像:
比撤消触发的创建:
更改颜色回来
删除对象
然后重做命令
第二次改变颜色是我的问题。所以堆栈中已经有一个,但导致它在构造函数中被第二次调用/创建。
当然,我可以在没有命令堆栈的情况下调用颜色更改,但我喜欢将所有事情都作为命令完成的想法。否则我必须写两次,这看起来有点脏,而且我必须维护两个版本的颜色变化。
颜色变化只是一个例子,我的例子是创建子对象。它还通过 uuid 跟踪每个对象。
那么有没有一种聪明的方法来处理这样的结构呢?
如何对模型类进行一些修改以包含不会添加到撤消堆栈的命令,例如:
static void changeColor(ObjectInterface *target, QColor const& color, bool undoable = true) {
if (undoable) {
undoStack->beginMacro("Change Color");
undoStack->push( new CommandChangeColor(target,color));
undoStack->endMacro();
} else {
QUndoCommand *cmd = new CommandChangeColor(target, color);
cmd->redo();
delete cmd;
}
}
然后你可以这样做:
class BlueObject : public ObjectInterface {
BlueObject() {
Model::changeColor(this,Qt::blue, false); // false to skip adding it to the undo stack
};
}