Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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);

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...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top