Qt5: Tell QPlainTextEdit to ignore syntax highlighting changes
Asked Answered
G

3

9

I have a QPlainTextEdit widget in my application which has a QSyntaxHighlighter assigned to it. Upon each content change within that text edit area, I need to get a notification (to update the global application save/changed state). However, the signal textChanged() also gets emitted each time the highlighter gets to work, which I need to filter out somehow.

I already had a look at modificationChanged(), but that doesn't seem to work either. It ignores the highlighting changes and successfully notifies me upon the first content change, but not of any subsequent changes. The documentation mentions, that I should be able to reset the internal state with setModified(false) but that method doesn't seem to exist.

Any ideas on how to filter the changes?

Do I have to switch to QTextDocument which seems to have a single contentsChanged() that is said to ignore syntax highlighting changes?

Gates answered 27/3, 2014 at 10:55 Comment(2)
Have you looked at Event filters?Jute
@Jute Can you please elaborate how they might help in my case? I want to get notified of the textChanged signal but just not when caused by the highlighting.Gates
G
9

It turns out I already was on the right track...just not all the way:

I indeed need to listen to modificationChanged signals since they are emitted on content changes (which are the relevant events for my application save state handling).

I however originally did not see a way to reset the internal modification state (e.g. when my application saves its state). The reason was that setModified(bool) does not exist for the QPlainTextEdit, but I realized that each of those objects has a QTextDocument internally which does have that method. So I simply call that each time I need to reset the state to non-modified:

m_pPlainTextEdit->document()->setModified(false);

As a result, when the content is changed the next time, modificationChanged will get emitted again so that I can react to it and for example enable the "Save" icon.

BTW: The signal contentsChanged from QTextDocument is also emitted upon formatting changes, so not helpful in my scenario.

Gates answered 4/4, 2014 at 21:2 Comment(1)
Thanks, also modificationChanged signal has a boolean argument that is useful for enabling and disabling the save button state void Dialog::on_plainTextEdit_modificationChanged(bool arg1) { ui->saveQPushButton->setEnabled(arg1); }Swingeing
J
1

I have not tested it, it is just basically an idea.

When the user modifies the text, it is a QKeyEvent.
When the highlighter does, it is some sort of QInputMethodEvent (?)

What you could do is, check if the event is a QKeyEvent, and if it is not, block it.

You can create a filterobject class, or just define the following method in the class that contains the QTextEdit.

bool MyClass::eventFilter(QObject *o, QEvent *e)
{
    if (e->type() == QKeyEvent) //The user modified the text edit
        return false;
    else
        return true;
}

And you have to install it (for example in the constructor), if you defined it in the class that contains QTextEdit:

myTextEdit->installEventFilter(this);
Jute answered 29/3, 2014 at 12:41 Comment(1)
I will have a more detailed look at your idea, but I fear that it will not work, because it is not the mySyntaxHighlighter that is generating the event/signal but the QPlainTextEdit. And I do want that event in general, just not when caused by the text changes from the highlighter, but only if caused by the user (if he/she edits the text/content).Gates
M
-1

Instead of hooking into modificationChanged(), and resetting the modified flag everytime, you could just hook into textChanged(). It's triggered anytime you make a change to the document, regardless if had been previously changed or not...

Mahdi answered 15/7, 2014 at 13:55 Comment(1)
Yes, but I don't want that event if change was triggered by the QHighlighter. So that doesn't work...Gates

© 2022 - 2024 — McMap. All rights reserved.