【问题标题】:How to use QT-Undo framework in constructor如何在构造函数中使用 QT-Undo 框架
【发布时间】:2017-05-18 18:00:05
【问题描述】:

假设我有一个 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 wich 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);
    };
}

现在问题来了:

如果我创建对象,undostack 看起来像:

  1. 创建对象 -> 更改颜色

比撤消触发的创建:

  1. 更改颜色返回

  2. 删除对象

然后重做命令

  1. 创建对象 -> 更改颜色(由构造函数调用)
  2. 改变颜色(从 undostack 调用)

第二次改变颜色是我的问题。所以堆栈中已经有一个,但导致它在构造函数中被第二次调用/创建。

当然,我可以在没有命令堆栈的情况下调用颜色更改,但我喜欢将所有事情都作为命令完成。否则我必须写两次,这看起来有点脏,我必须维护两个版本的颜色变化。

颜色变化只是一个例子,我的例子是它创建 childObject。它还通过 uuids 跟踪每个对象。

那么有没有一种聪明的方法来处理这样的结构?

【问题讨论】:

    标签: c++ qt undo


    【解决方案1】:

    如何对您的模型类添加一些修改以包含未添加到撤消堆栈的命令,例如:

    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
        };
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-20
      • 1970-01-01
      相关资源
      最近更新 更多