Important: Please read the Qt Code of Conduct -

Accessing Textedit's undostack

  • Dear QT peoples,

    First time caller here!

    I'm seeking advice on a matter as the solution around my issue seems extreme, which normally means I've gone down the wrong route! Thought I'd ask you lovely people ;-)

    Like most here I have a few widgets in my app. These are all "connected" to my undo system and work perfectly. This is brilliant.

    Problem is one of the other widgets I need to connect to my undo stack is an text editor. Obviously the default undo system is working perfectly by itself but it breaks the 'sync' of my stacks. This is key to my app.

    If this was the ideal world I'd set my undostack into the texteditor when initiated but this doesn't seem to be possible. please be undocumented!

    Looking into the docs of both the textedit and textdocuement I don't have access to the private undostack.

    Is there a clean way accessing or controlling this this?

    ideal work flow:

    text edit undo command  added signal --> myundostack()->push(textEdit->undostack()->getLatestUndo()-->weep with joy

    Currently I'm having to rebuild the entire text edit system undo system to make my own undoCommands. This feels really wrong and needlessly painful.

    Google has bleed me dry.

    Please could I grab a brain or two to aide me in this (I'm writing this in C++ if that matters).

    Many thanks
    (drinks sent out to any victor on this issue!)


  • Lifetime Qt Champion


    What kind of command do you have in mind for the QTextEdit widget ?

  • Hi SGaist,

    Thanks for getting in touch with me. To answer your question, in the ideal world it would be illustrated something like:

    TextEditor::TextEditor(UndoStack * myUndoStack, QWidget *parent ): QTextEdit(parent)
        _textDoc = new QTextDocument(this);

    If there is a signal that allows me to return an QUndoCommand so I can pass it into my undo class.

    Seems crazy I have to rebuild an undo system.

    Please let me know if I'm not being clear enough.

    Many thanks

  • Moderators

    thats just a shot into the dark. What does the following return?

    qDebug() << myTextEdit->findChildren<QUndoStack*>();

    I am not sure if the default undo stack is in the parent-child hierachy.

  • Hi raven-worx,

    Thank you for you suggestion but this is just returning empties, tried on both qtextedit and on the qtextdocument.

    There has to be a way to get this, I know for QTextdocument you have a signal called undoCommandAdded and undoAvailable.
    Whats the point of this if you don't have access to the stack?

    Thanks again

  • Lifetime Qt Champion

    You misunderstood my question, I know you want the replace the undo stack. My question is: why exactly do you want to replace that stack ?

  • My apologies SGaist.

    I have an app that requires all the widgets to be in 'sync'. Its sort of a note taking software so inserting a button in one widget(which is undo-able) inserts and effects the text.

    So undoing the central widget leaves 'unwanted' effects in the text editor. So I want to push it all into one stack so the undos are constant and don't break the app data.

    Is this clearer?

  • Lifetime Qt Champion

    Do you need to undo out of order ?
    say you insert button. Text is changed.
    Then you press undo.
    Your undo system removes the widget and you signal QTextEdit::undo() on textedit to remove the text.

    Maybe Im not getting the exact requirements ?

    And no, there is no way to get access to the stack. ( as i can see)
    It lives in qtextdocument_p.cpp
    class QTextDocumentPrivate : public QObjectPrivate {
    QVector<QTextUndoCommand> undoStack;

    So it seem not possible to use the meta system to get it.

  • Not sure. Really sorry if Im not clearer, long day.

    I'll try and illustrated my needs with flows.

    What I need it to do
    widget 1 -> create btn with custom text.
    -> click this btn -> insert text in text widget.

    text widget -> inserts text.
    -> user starts to write notes.

    now breaks in two ways.
    1st undo in text editor -> removes text -> removes inserted text ->doesn't undo button etc.
    2nd undo through my app -> removes btn. Text is still there. App is now out of sync.

    What I'd love is:

    going forward:
    widget 1->create btn->(text edit)insert text -> user types fresh text.

    (text edit) undoes custom text->undoes inserted text->(widget1) undoes create button.

    Is this clearer?

    I really appreciate this you all. Thanks for hanging in there.

  • Lifetime Qt Champion


    I think i get it now :) (hopefully)

    Lets look at cases and talk what we can do.

    1st undo in text editor -> removes text -> removes inserted text ->doesn't undo button etc.

    If you catch ctrl+z to and call your MasterUndo that
    will call "widget undo" and QTextEdit::undo() then
    its not possible to just undo text.

    I assume it must be in sync meaning undo text will undo button and reverse.

    If you make sure textedit cannot do its undo alone, then wont this work for your use case?

    2nd undo through my app -> removes btn. Text is still there. App is now out of sync.
    But cant your undo just call QTextEdit::undo() also ?

  • @mrjj
    Thank you for your response. I thought of some form of elaborate counting system that would handle this but I felt it might open up to some unyielding complex beast that is very open to breakages.

    Thanks for some input though. I've made headway on the undo system past two days.


  • Lifetime Qt Champion


    Im not sure why you think it would break so easy , i assume there is more details that that i know of.

    IfF you control the textedit undo, then i dont see why you think it can go out of sync. User cant undo only text then.

    If you add a dummy undo to your own stack, meaning Call unto() on text edit it should be in sync.

  • Thanks again @mrjj for your persistence on my matter,

    If there are say 3 undo levels in my main undo stack to get to the point of insert text.
    Then say I have 20 levels of undo into my text edit.

    I'm going to have to monitor each and every undo insert with a counter.

    Then if I hit the core undo app undo I'm going to have to loop through that counter to one hard undo. This will be too 'hard' on the user.

    There are a few other issues that will creep in that will make the user's experience more uncomfortable doing it this way.
    Things like when I go out of 'focus' into another part of the app I will have to probably wipe undostack for the text editor.

    This said I will branch off and have a play around with your method when I get the times.

    Really appreciate the inputs thank you.

Log in to reply