Skip to main content

Ralsina.Me — Roberto Alsina's website

How to implement "replace all" in a QPlainTextEdit

This is not in­ter­est­ing for al­most noone, but since my google-­fu did­n't let me find it and it was a bit of a pain to do:

This is how you im­ple­ment 're­place al­l' in a QPlain­TextE­d­it (or a QTextE­d­it, for that mat­ter) us­ing PyQt (sim­i­lar for C++ of course).

def doReplaceAll(self):
    # Replace all occurences without interaction

    # Here I am just getting the replacement data
    # from my UI so it will be different for you
    old=self.searchReplaceWidget.ui.text.text()
    new=self.searchReplaceWidget.ui.replaceWith.text()

    # Beginning of undo block
    cursor=self.editor.textCursor()
    cursor.beginEditBlock()

    # Use flags for case match
    flags=QtGui.QTextDocument.FindFlags()
    if self.searchReplaceWidget.ui.matchCase.isChecked():
        flags=flags|QtGui.QTextDocument.FindCaseSensitively

    # Replace all we can
    while True:
        # self.editor is the QPlainTextEdit
        r=self.editor.find(old,flags)
        if r:
            qc=self.editor.textCursor()
            if qc.hasSelection():
                qc.insertText(new)
        else:
            break

    # Mark end of undo block
    cursor.endEditBlock()

There are oth­er, eas­i­er ways to do it, but this one makes it all ap­pear as a sin­gle op­er­a­tion in the un­do stack and all that.

Andrés / 2010-02-15 23:42:

Typo en el título ;)

Roberto Alsina / 2010-02-15 23:49:

Corrigiendo...

JoeNotCharles / 2010-02-16 01:01:

Doesn't this break if old is a substring of new? (ie. if you replace "abc" with "abc123", won't it repeatedly expand "abc123", "abc123123", "abc123123123", etc?)

Roberto Alsina / 2010-02-16 01:12:

No because it only does one pass from the cursor position forward.

Scott / 2010-02-16 02:17:

I'm curious to learn as to why you didn't using a QRegExp in place of the while loop?

Roberto Alsina / 2010-02-16 02:25:

This way the code is trivial. With a regexp I need to escape the text I want to replace, and still need to loop since QTextDocument.find only finds the first time it appears (unless I am reading the docs wrong)

Thomas / 2010-02-16 07:23:

Curious; what (programming) language is this?

Roberto Alsina / 2010-02-16 09:41:

That is Python (http://www.python.org) using a library called PyQt

mat / 2011-02-23 13:07:

void Editor::SlotReplaceAll(QString findString, QRegExp findExpr, bool isExpr, QString replaceString, bool caseSensitively, bool wholeWords)
{
QTextDocument *doc = document();
QTextCursor cursor = textCursor();
cursor.beginEditBlock();
cursor.movePosition(QTextCursor::Start);
QTextCursor newCursor = cursor;
quint64 count = 0;

QTextDocument::FindFlags options;
if (caseSensitively) options = options | QTextDocument::FindCaseSensitively;
if (wholeWords) options = options | QTextDocument::FindWholeWords;

if (!findString.isEmpty())
{
while (true)
{
if (isExpr)
newCursor = doc->find(findExpr, newCursor, options);
else
newCursor = doc->find(findString, newCursor, options);

if (!newCursor.isNull())
{
if (newCursor.hasSelection())
{
newCursor.insertText(replaceString);
count++;
}
}
else
{
break;
}
}
}
cursor.endEditBlock();
QMessageBox::information(this, tr("ReplaceAll"), tr("%1 occurrence(s) were replaced.").arg(count));
}

phone number lookup / 2011-12-03 22:20:

this is really interesting viewpoint on the subject i might add

phone number lookup / 2011-12-03 22:30:

this is really interesting viewpoint on the subject i might add

employment background check / 2011-12-27 23:23:


Hi very nice article

employment background check / 2011-12-27 23:28:

Man ... Beautiful . Amazing ... I will bookmark your website and use the your RSS feed also

cell phone lookup / 2012-01-17 05:52:


Your blog has the same post as another author but i like your better

cell phone lookup / 2012-01-17 05:53:


Your blog has the same post as another author but i like your better


Contents © 2000-2020 Roberto Alsina