Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Don't understand the benefit of QUndo. Can anyone explain?
Forum Updated to NodeBB v4.3 + New Features

Don't understand the benefit of QUndo. Can anyone explain?

Scheduled Pinned Locked Moved Unsolved General and Desktop
qundostackqgraphicsviewqgraphicsscenec++qt
2 Posts 2 Posters 218 Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    StudentScripter
    wrote on 26 Feb 2025, 22:06 last edited by
    #1

    So i have an graphicsscene where i let the user scale, rotate, translate some graphicsitems in single or in groups.
    I've created a QMap that saves <QGraphicsitem, QVector> together so the item is the key and the vector holds the Qtransformation. This way i can roll back an forth between all states of the QGraphicsitem even accross sessions.

        QMap<QGraphicsRectItem*, QVector<QTransform>> itemTransforms;
    

    Would there be any benefit using QUndo? (explanation in german would be preferred, but englisch is fine too.)

    Here is my current implementation:

       #ifndef MGRECTITEMTRANSFORMDATA_H
    #define MGRECTITEMTRANSFORMDATA_H
    
    #include <QGraphicsRectItem>
    #include <QTransform>
    #include <QVector>
    #include <QMap>
    #include <QPointer>
    #include <QDataStream>
    #include <QDebug>
    
    class MGRectItemTransformData {
    public:
        // Gibt die einzige Instanz zurück (Singleton)
        static MGRectItemTransformData& instance() {
            static MGRectItemTransformData instance;
            return instance;
        }
    
        // Löscht Kopier-/Zuweisungsoperatoren (damit keine Kopien erstellt werden können)
        MGRectItemTransformData(const MGRectItemTransformData&) = delete;
        MGRectItemTransformData& operator=(const MGRectItemTransformData&) = delete;
    
        // Fügt eine Transformation für ein bestimmtes QGraphicsRectItem hinzu
        void addTransform(QGraphicsRectItem *item, const QTransform &transform) {
            if (!item) return;
    
            // Transformation hinzufügen
            itemTransforms[item].append(transform);
    
            // Index der hinzugefügten Transformation
            int index = itemTransforms[item].size() - 1;
    
            // Werte der Transformation
            qreal m11 = transform.m11();
            qreal m12 = transform.m12();
            qreal m21 = transform.m21();
            qreal m22 = transform.m22();
            qreal m31 = transform.m31();
            qreal m32 = transform.m32();
    
            // Ausgabe des Indexes und der Werte
            qDebug() << "Transformation hinzugefügt für Item:" << item;
            qDebug() << "Index der Transformation:" << index;
            qDebug() << "Werte der Transformation:";
            qDebug() << "m11:" << m11 << "m12:" << m12;
            qDebug() << "m21:" << m21 << "m22:" << m22;
            qDebug() << "m31:" << m31 << "m32:" << m32;
    
    
        }
    
    
        // Gibt die Transformation an einer bestimmten Position für ein Item zurück
        QTransform getTransform(QGraphicsRectItem *item, int index) const {
            if (!item || !itemTransforms.contains(item)) {
                qWarning() << "Item nicht gefunden!";
                return QTransform();
            }
    
            const QVector<QTransform> &transforms = itemTransforms[item];
    
            if (index < 0 || index >= transforms.size()) {
                qWarning() << "Index außerhalb des gültigen Bereichs!";
                return QTransform();
            }
    
            return transforms.at(index);
        }
    
        // Wandelt eine Transformation in einen QVector<qreal> um
        static QVector<qreal> transformToVector(const QTransform &transform) {
            return { transform.m11(), transform.m12(), transform.m21(),
                    transform.m22(), transform.m31(), transform.m32() };
        }
    
        // Wandelt einen QVector<qreal> zurück in eine Transformation
        static QTransform vectorToTransform(const QVector<qreal> &values) {
            if (values.size() < 6) {
                qWarning() << "Der Vektor enthält nicht genügend Werte!";
                return QTransform();
            }
            return QTransform(values[0], values[1], values[2],
                              values[3], values[4], values[5]);
        }
    
        // Serialisierung: Speichert eine Transformation als Binärdaten
        static QDataStream &serialize(QDataStream &out, const QTransform &transform) {
            out << transform.m11() << transform.m12() << transform.m21()
            << transform.m22() << transform.m31() << transform.m32();
            return out;
        }
    
        // Deserialisierung: Stellt eine Transformation aus Binärdaten wieder her
        static QDataStream &deserialize(QDataStream &in, QTransform &transform) {
            qreal m11, m12, m21, m22, m31, m32;
            in >> m11 >> m12 >> m21 >> m22 >> m31 >> m32;
            transform = QTransform(m11, m12, m21, m22, m31, m32);
            return in;
        }
    
    
    
    
    private:
        // Privater Konstruktor (sodass keine Instanzen außerhalb der `instance()` Methode erzeugt werden können)
        MGRectItemTransformData() {}
    
        // Map von QGraphicsRectItem-Pointern zu Transformations-Historien
        QMap<QGraphicsRectItem*, QVector<QTransform>> itemTransforms;
    
    };
    
    #endif // MGRECTITEMTRANSFORMDATA_H
    
    
    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 2 Mar 2025, 19:39 last edited by
      #2

      Hi,

      Well, the undo framework allows you to go back and forth in a controlled fashion. You can have multiple different commands based on your various workflows that can be handled by a single stack. There's a model that you can visualize while developing the feature.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0

      2/2

      2 Mar 2025, 19:39

      • Login

      • Login or register to search.
      2 out of 2
      • First post
        2/2
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved