Results 1 to 6 of 6

Thread: Undo edit of QListWidgetItem?

  1. #1
    Join Date
    Jun 2014
    Posts
    98
    Thanks
    43
    Thanked 4 Times in 4 Posts
    Platforms
    Windows

    Default Undo edit of QListWidgetItem?

    Note this is a repost of a question at Stack Overflow that I just put a bounty on:
    http://stackoverflow.com/questions/2...tem-in-qt-pyqt

    Short version

    How do you implement undo functionality for edits made on QListWidgetItems?

    Details

    I am using a QListWidget to learn my way around PyQt's Undo Framework (with the help of an article on the topic: http://www.informit.com/articles/article.aspx?p=1187104). I am fine with undo/redo when I implement a command myself (like deleting an item from the list). Below is a full code example that shows a list, lets you delete items,and undo/redo such deletions. The application displays the list on the right, and the undo stack on the left.

    The problem is, I also want to make the QListWidgetItems in the widget editable. This is easy enough: just add the ItemIsEditable flag to each item. But how do I push such edits onto the undo stack, so I can then undo/redo them?

    Simple working example
    Qt Code:
    1. from PySide import QtGui, QtCore
    2.  
    3. class TodoList(QtGui.QWidget):
    4. def __init__(self):
    5. QtGui.QWidget.__init__(self)
    6. self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
    7. self.initUI()
    8. self.show()
    9.  
    10. def initUI(self):
    11. self.todoList = self.makeTodoList()
    12. self.undoStack = QtGui.QUndoStack(self)
    13. undoView = QtGui.QUndoView(self.undoStack)
    14. buttonLayout = self.buttonSetup()
    15. mainLayout = QtGui.QHBoxLayout(self)
    16. mainLayout.addWidget(undoView)
    17. mainLayout.addWidget(self.todoList)
    18. mainLayout.addLayout(buttonLayout)
    19. self.setLayout(mainLayout)
    20. self.makeConnections()
    21.  
    22. def buttonSetup(self):
    23. #Make buttons
    24. self.deleteButton = QtGui.QPushButton("Delete")
    25. self.undoButton = QtGui.QPushButton("Undo")
    26. self.redoButton = QtGui.QPushButton("Redo")
    27. self.quitButton = QtGui.QPushButton("Quit")
    28. #Lay them out
    29. buttonLayout = QtGui.QVBoxLayout()
    30. buttonLayout.addWidget(self.deleteButton)
    31. buttonLayout.addStretch()
    32. buttonLayout.addWidget(self.undoButton)
    33. buttonLayout.addWidget(self.redoButton)
    34. buttonLayout.addStretch()
    35. buttonLayout.addWidget(self.quitButton)
    36. return buttonLayout
    37.  
    38. def makeConnections(self):
    39. self.deleteButton.clicked.connect(self.deleteItem)
    40. self.quitButton.clicked.connect(self.close)
    41. self.undoButton.clicked.connect(self.undoStack.undo)
    42. self.redoButton.clicked.connect(self.undoStack.redo)
    43.  
    44. def deleteItem(self):
    45. rowSelected=self.todoList.currentRow()
    46. rowItem = self.todoList.item(rowSelected)
    47. if rowItem is None:
    48. return
    49. command = CommandDelete(self.todoList, rowItem, rowSelected,
    50. "Delete item '{0}'".format(rowItem.text()))
    51. self.undoStack.push(command)
    52.  
    53. def makeTodoList(self):
    54. todoList = QtGui.QListWidget()
    55. allTasks = ('Fix door', 'Make dinner', 'Read',
    56. 'Program in PySide', 'Be nice to everyone')
    57. for task in allTasks:
    58. todoItem=QtGui.QListWidgetItem(task)
    59. todoList.addItem(todoItem)
    60. todoItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
    61. return todoList
    62.  
    63.  
    64. class CommandDelete(QtGui.QUndoCommand):
    65. def __init__(self, listWidget, item, row, description):
    66. super(CommandDelete, self).__init__(description)
    67. self.listWidget = listWidget
    68. self.string = item.text()
    69. self.row = row
    70.  
    71. def redo(self):
    72. self.listWidget.takeItem(self.row)
    73.  
    74. def undo(self):
    75. addItem = QtGui.QListWidgetItem(self.string)
    76. addItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
    77. self.listWidget.insertItem(self.row, addItem)
    78.  
    79. if __name__ == "__main__":
    80. import sys
    81. app = QtGui.QApplication(sys.argv)
    82. myList=TodoList()
    83. sys.exit(app.exec_())
    To copy to clipboard, switch view to plain text mode 
    Last edited by neuronet; 14th March 2015 at 19:44.

  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 edit of QListWidgetItem?

    Have you seen [wiki]Using Undo/Redo with Item Views[/wiki]?
    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
    Jun 2014
    Posts
    98
    Thanks
    43
    Thanked 4 Times in 4 Posts
    Platforms
    Windows

    Default Re: Undo edit of QListWidgetItem?

    Quote Originally Posted by wysota View Post
    Have you seen [wiki]Using Undo/Redo with Item Views[/wiki]?
    Yes about a week ago, and was very excited to see it (I posted here about it: http://www.qtcentre.org/threads/6146...ght=undo+model). ) Unfortunately I got utterly confused in the sudoku model by the c++. So I suppose what I am trying to do falls under the following in your article:
    Implementing such a pattern is a minor effort in most cases. However, main drawback is that if something calls your model directly without interfacing through the undo/redo framework, the undo stack will lose coherence and won't be able to bring the model back to a desired state---some changes will be ignored and some will be overwritten with those stored in the undo stack.
    That said, I got lost before implementing the model above in my original post, so perhaps now I will understand it better and will be able to follow your c++ code. Would be great to translate your example to PyQt. I am not sure I am able, unfortunately.
    Last edited by neuronet; 14th March 2015 at 19:52.

  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 edit of QListWidgetItem?

    You can repeat the process for a much simpler model, e.g. one containing a list of strings which you can add, remove or modify.
    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
    Jun 2014
    Posts
    98
    Thanks
    43
    Thanked 4 Times in 4 Posts
    Platforms
    Windows

    Default Re: Undo edit of QListWidgetItem?

    Wysota yes that is the goal. I did it first for the simple case because of the article already available for PyQt. I will also try to do it with this simple example using the technique you recommend. I'll try to translate to PyQt/PySide and post somewhere...

  6. #6
    Join Date
    Jun 2014
    Posts
    98
    Thanks
    43
    Thanked 4 Times in 4 Posts
    Platforms
    Windows

    Default Re: Undo edit of QListWidgetItem?

    Follow-up: I got a very instructive answer to this question at SO:
    http://stackoverflow.com/a/29166218/1886357

Similar Threads

  1. QTableView line edit clears the text on edit
    By PlasticJesus in forum Qt Programming
    Replies: 5
    Last Post: 14th March 2015, 20:06
  2. Replies: 0
    Last Post: 21st January 2014, 07:05
  3. Syncing QTextDocument's undo stack with custom undo stack
    By Dini Selimović in forum Newbie
    Replies: 0
    Last Post: 24th June 2012, 14:11
  4. Replies: 3
    Last Post: 26th August 2010, 09:57
  5. Character encoding in text edit and llne edit
    By greenvirag in forum Qt Programming
    Replies: 3
    Last Post: 20th January 2009, 09:45

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.