user3473325
user3473325

Reputation: 113

Qt Undo/Redo implementation, can’t connect to a button

I post the question also in the Qt Forum, here

I am trying to implement an undo and redo commands in my application. I have a QTreeWidget and I’d like to let the user undo and redo an action (ex. change a value in a QTreeWidgetItem columns in the QTreeWidget and undo/redo it).

Here part of my code:

class A.h

    class A : public QWidget
{
    Q_OBJECT
public:
    explicit A(...);
    ~A();

    ChangeValueTreeCommand      *commands;
    QUndoStack                  *undoStack;
    QPushButton                 *undoBtn;
    QPushButton                 *redoBtn;
    QString                      newValue;

    void changeItem(QTreeWidgetItem* treeWidgetItemChanged, int col);
};

class A.cpp

A::A(...){
undoStack = new QUndoStack(this);
}

void A::changeItem(QTreeWidgetItem* treeWidgetItemChanged, int col){

     ....
    commands = new ChangeValueTreeCommand(treeWidgetItemChanged, col, newValue);
    connect(undoBtn, SIGNAL(clicked()), commands, SLOT(undo()));
    undoStack->push(commands);

}

class Commands.h

    #ifndef COMMANDS_H
#define COMMANDS_H

#include <QApplication>

#include <QUndoCommand>
#include <QTreeWidgetItem>


class ChangeValueTreeCommand : public QUndoCommand
{
public:
    explicit ChangeValueTreeCommand(QTreeWidgetItem* treeWI = NULL, int c = 0, const QString changedV = "");
    ~ChangeValueTreeCommand();

    QTreeWidgetItem* treeWItem;
    const QString    changedValue;
    int col;

public slots:

    void undo();
    void redo();
};


#endif // COMMANDS_H

class Commands.cpp

    #include "Commands.h"

ChangeValueTreeCommand::ChangeValueTreeCommand(QTreeWidgetItem* treeWI, int c, const QString changedV)
        : treeWItem(treeWI), col(c), changedValue(changedV)

{}

ChangeValueTreeCommand::~ChangeValueTreeCommand(){}

void ChangeValueTreeCommand::undo()
{
    const QString oldValue = treeWItem->text(col);
    treeWItem->setText(col, oldValue);
}

void ChangeValueTreeCommand::redo()
{
    treeWItem->setText(col, changedValue);
}

The problem is that when the user changes the value in the QTreeWidgetItem, it automatically appears the previous value. Moreover, I would like to connect the undo and redo functions to two buttons, but the compiler says that

1543: error: C2664: ‘QMetaObject::Connection QObject::connect(const QObject *,const char *,const QObject *,const char *,Qt::ConnectionType)‘ÿ: cannot convert parameter 3 from ‘ChangeValueTreeCommand *’ to ‘const QObject *’ Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

Can someone help me? Thx

Upvotes: 0

Views: 1834

Answers (1)

Mailerdaimon
Mailerdaimon

Reputation: 6080

Your undo and redo Buttons should call undoStack->undo() / undoStack->redo(). This will move the stack pointer and will call the undo/redo function of the current command.

See the Qt Documentation for a detailed Explanation: http://qt-project.org/doc/qt-4.8/qundostack.html#undo

Escpecially this part:

New commands are pushed on the stack using push(). Commands can be undone and redone using undo() and redo(), or by triggering the actions returned by createUndoAction() and createRedoAction().

QUndoStack keeps track of the current command. This is the command which will be executed by the next call to redo(). The index of this command is returned by index(). The state of the edited object can be rolled forward or back using setIndex(). If the top-most command on the stack has already been redone, index() is equal to count().

Upvotes: 1

Related Questions