[PyQt] PyQt's Undo/Redo framework - A Very Short Intro

Mark Summerfield mark at qtrac.eu
Fri Apr 25 07:56:29 BST 2008

On 2008-04-24, Giovanni Bajo wrote:
> On 4/24/2008 12:30 PM, Mark Summerfield wrote:
> > Hi,
> >
> > I've written a very short introductory article on using PyQt's Undo/Redo
> > framework. It is available here:
> >
> > http://www.informit.com/articles/article.aspx?p=1187104
> >
> > (The indentation of the last line of the delete() method is wrong---I've
> > told InformIT so they may have fixed it by now, but if not you'll spot
> > it anyway.)
> >
> > The article has been heavily edited for style so it doesn't read like my
> > usual writing, but the content is fine:-)
> Hi Mark,
> nice article, thanks!
> A couple of caveats about lifetimes issues. In page 3:
> ==============================================================
>      self.undoStack = QUndoStack(self)
> Add this line to create an undo stack. Although it’s an instance
> variable, you still must give it a parent (the dialog box), so that PyQt
> is able to clean it up at the right time when the dialog box is destroyed.
> ==============================================================
> Is this really true? Without a parent, the undo stack would be garbage
> collected whenever the Python instance is garbage collected, which is
> probably right at the moment the dialog is destroyed (or sometimes
> after, but does it really mind?).

If you don't have the parent, i.e.:

      self.undoStack = QUndoStack()

Then when the app terminates, you get this on the console (Python 2.5.1,
Qt 4.3.3, PyQt 4.3.3 on Linux):

QObject::startTimer: QTimer can only be used with threads started with QThread
QObject::startTimer: QTimer can only be used with threads started with QThread
Segmentation fault

So it seems that the parent is needed to me:-)

> Later:
> ==============================================================
>      def redo(self):
>          item = self.listWidget.takeItem(self.row)
>          del item
> ==============================================================
> IMO it's a little confusing because the "del item" isn't really doing
> anything more than it would be done one opcode later when the method
> exits and its locals are destroyed. In fact, calling takeItem() without
> binding its return value to a name achieves the same effect and it is
> clearer.

Good point. I have changed the source code accordingly.

> Thanks again for a nice article!


Mark Summerfield, Qtrac Ltd., www.qtrac.eu

More information about the PyQt mailing list