Results 1 to 8 of 8

Thread: Undo/redo for moving QGraphicsLineItem

  1. #1
    Join Date
    Aug 2014
    Posts
    13
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Undo/redo for moving QGraphicsLineItem

    I am moving different entities like point, line, circle and ellipse in my scene. I am implementing undo-redo using the Undo-Redo Framework provided in Qt. I get correct coordinates for point when it is moved from one position to another i.e. I get its scene coordinates.

    When I move onto other entities, I get coordinates in the stack in the terms of their local coordinates, not the scene coordinates. How do I get the scene coordinates of other entities?

    My move command is defined as:

    Qt Code:
    1. class CommandMove : public QUndoCommand
    2. {
    3. public:
    4. CommandMove(QGraphicsItem *item, qreal fromX, qreal fromY,
    5. qreal toX, qreal toY)
    6. {
    7. m_item = item;
    8. mFrom = QPointF(fromX, fromY);
    9. mTo = QPointF(toX, toY);
    10. setText(QString("Point move (%1,%2) -> (%3,%4)").arg(fromX).arg(fromY)
    11. .arg(toX).arg(toY));
    12. }
    13.  
    14. virtual void undo()
    15. {
    16. m_item->setPos(mFrom);
    17. }
    18.  
    19. virtual void redo()
    20. {
    21. m_item->setPos(mTo);
    22. }
    23.  
    24. private:
    25. QGraphicsItem *m_item;
    26. QPointF mFrom;
    27. QPointF mTo;
    28. };
    To copy to clipboard, switch view to plain text mode 

    What should be added/edited in this piece of code so that I get the scene coordinates for all entities?

    Also I have set the position of point in mousePressEvent using:

    Qt Code:
    1. setPos(mouseEvent->scenePos);
    To copy to clipboard, switch view to plain text mode 

    For line, I do using setLine() function but it doesn't give the scene coordinates of the end points of the line. Help me solve this issue.

    Thanks in advance!

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Undo/redo for moving QGraphicsLineItem

    If part of the process of moving items is reparenting them to an item that is underneath then you will need to store the parent item as well as the position relative to that item. So the whole move operation will consist of changing {par1, pos1} to {par2, pos2}. If moving items does not change their parents then I'm not sure what is the problem you are having as moving the item would not result in changing the parent and again using pos() and setPos() should be enough.

    For completeness -- there is QGraphicsItem::scenePos() to reed the position relative to the scene and there is a family of mapTo*() and mapFrom*() (including QGraphicsItem::mapFromScene()) to map coordinates between different systems.

    By the way -- if you have a "delete" among the commands you handle in your undo/redo system, be sure that you think twice how to handle that in combination of storing pointers to items in other commands -- if you really delete an item, its pointer will become invalid and all other stored commands dealing with that item will contain dangling pointers.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Aug 2014
    Posts
    13
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: Undo/redo for moving QGraphicsLineItem

    Quote Originally Posted by wysota View Post
    If part of the process of moving items is reparenting them to an item that is underneath then you will need to store the parent item as well as the position relative to that item. So the whole move operation will consist of changing {par1, pos1} to {par2, pos2}. If moving items does not change their parents then I'm not sure what is the problem you are having as moving the item would not result in changing the parent and again using pos() and setPos() should be enough.
    There is nothing like changing parents in my implementation.

    For completeness -- there is QGraphicsItem::scenePos() to reed the position relative to the scene and there is a family of mapTo*() and mapFrom*() (including QGraphicsItem::mapFromScene()) to map coordinates between different systems.
    I have also come across this. But I am not able to produce the expected results.

    By the way -- if you have a "delete" among the commands you handle in your undo/redo system, be sure that you think twice how to handle that in combination of storing pointers to items in other commands -- if you really delete an item, its pointer will become invalid and all other stored commands dealing with that item will contain dangling pointers.
    Ah! Thank you for pointing this out.

    I will soon be posting a minimal example to show my implementation so that the problem can be rectified after scrutinizing.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Undo/redo for moving QGraphicsLineItem

    Quote Originally Posted by Kamalpreet View Post
    There is nothing like changing parents in my implementation.
    I don't know what the following means then:

    Quote Originally Posted by Kamalpreet View Post
    When I move onto other entities, I get coordinates in the stack in the terms of their local coordinates, not the scene coordinates.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Aug 2014
    Posts
    13
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: Undo/redo for moving QGraphicsLineItem

    I have managed to obtain the old and updated coordinates of line using line().

    In my move command, I have defined my undo() and redo() as follows:

    Qt Code:
    1. virtual void undo()
    2. {
    3. m_item->setLine(oldStart.x(), oldStart.y(), oldEnd.x(), oldEnd.y());
    4. qDebug() << m_item->line();
    5. }
    6.  
    7. virtual void redo()
    8. {
    9. m_item->setLine(newStart.x(), newStart.y(), newEnd.x(), newEnd.y());
    10. qDebug() << m_item->line();
    11. }
    To copy to clipboard, switch view to plain text mode 

    The debugging gives me correct coordinates, both old and new. However, the line stays at the same position in the graphics scene. Does undo() and redo() update the position using setPos() only?
    What kind of implementation can be done in the case of line so that it is updated in the scene?

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Undo/redo for moving QGraphicsLineItem

    setLine() does not modify the item's position! It only modifies the line (and implicitly the bounding rect) the item represents. The item is still "anchored" where it was (by default at (0,0) in its parent's coordinate system).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Aug 2014
    Posts
    13
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: Undo/redo for moving QGraphicsLineItem

    Quote Originally Posted by wysota View Post
    setLine() does not modify the item's position! It only modifies the line (and implicitly the bounding rect) the item represents. The item is still "anchored" where it was (by default at (0,0) in its parent's coordinate system).
    So for undo(), redo() I can use only setPos()? Is it so? I am unable to figure out an alternative.

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Undo/redo for moving QGraphicsLineItem

    It really depends on your application logic. I always opt for adjusting item position to implement the "move" operation. Of course often you have to adjust the bounding rect too.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. Undo/Redo Functionality
    By Gurjot in forum Newbie
    Replies: 2
    Last Post: 10th October 2014, 10:45
  2. Replies: 0
    Last Post: 21st January 2014, 07:05
  3. qt undo/redo
    By giugio in forum Qt Programming
    Replies: 1
    Last Post: 12th November 2012, 17:31
  4. QTextEdit undo/redo
    By Derf in forum Qt Programming
    Replies: 1
    Last Post: 6th August 2009, 10:12
  5. Implement Undo Redo
    By ankurjain in forum Qt Programming
    Replies: 5
    Last Post: 28th March 2006, 14:17

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.