View Full Version : QTextEdit optimization

5th November 2007, 10:29

I wanted to optimize a QTextEdit control by highlighting only the visible part of it.

I got the start/end cursor positions of the QTextEdit's viewport. But what can I do after to call the viewport's painter to redraw only the visible part ?

Any help will be appreciated, thanks in advance.

5th November 2007, 11:01
It already does that - redraws only the visible part.

5th November 2007, 11:28
Hi wysota,

thanks for your answer, but I found it rather slow when I have an highlighter full of keywords and regexp based state rules. Is that a normal behaviour ?
I also noticed that loading/pasting a long file takes a long time for QTextEdit.
I'm working with Python, but I don't think the problem lies here.


5th November 2007, 11:32
Depends on the complexity and structure of your highlighter. Normally it should be called for a single paragraph at a time, so it also depends on the structure of your document. I suggest you use a profiler to find the bottleneck of your application.

5th November 2007, 11:56
Thanks for clarifying this point wysota : is it called by paragraph (group of lines separated by a blank one or more) or by line ?

Edit : it seems it is called by paragraph, right ?

5th November 2007, 13:57
Yes, one paragraph at a time.

5th November 2007, 14:21
In a Qt Quarterly http://doc.trolltech.com/qq/qq21-syntaxhighlighter.html article it is said that :

QSyntaxHighlighter makes this possible through its "state" mechanism. When we finish highlighting a line, we can associate a state with the line (e.g., "Inside C-Style Comment"), which we can retrieve when we start highlighting the following line. The state is stored as an int.

The article is talking about lines, not paragraphs.

So, let's suppose I wanted to highlight comments like this :

### a comment
, maybe on several lines ###

Here 'text' is the QString argument of my highlightBlock method. I put inside some print statements for debugging purpose.

When I call it, having typed : "### a comment", highlightBlock's text returns "### a comment".

After pressing enter and typing the second line : ", maybe on several lines ###", highlightBlock's text returns :", maybe on several lines ###".

So it confuses me : its not a paragraph but the second line only. I expected :
"### a comment\n, maybe on several lines ###".

I must miss something here, but don't know what exactly.

5th November 2007, 17:59
In QTextDocument (when you load from *.txt files) a paragraph is a line. Maybe that is what's confusing for you.

Now I have a question:
Does anyone know how to query the syntax highlighter for it's state? I want to know the state at a random offset of some random paragraph.

5th November 2007, 18:09
Thanks elcuco,
for the state, you can use QSyntaxHighlighter::currentBlockState.

5th November 2007, 18:47
Does anyone know how to query the syntax highlighter for it's state? I want to know the state at a random offset of some random paragraph.

I don't think you can do that. The state is probably saved within the text document itself by using custom user data (probably using QTextBlockUserData). You can check the source code, maybe the data is accessible there, but I wouldn't bet on it. To me the highlighter is only called when appropriate and has no control (nor knowledge) about what happens when it's not called.

6th November 2007, 19:38
Ok, I started looking at the code:

int QSyntaxHighlighter::previousBlockState() const
Q_D(const QSyntaxHighlighter);
if (!d->currentBlock.isValid())
return -1;

const QTextBlock previous = d->currentBlock.previous();
if (!previous.isValid())
return -1;

return previous.userState();

and d->currenltBlock is defined as:

class QSyntaxHighlighterPrivate : public QObjectPrivate
QTextBlock currentBlock;

And I do see that QTextBlock::userState() is public, which means you can know the state of the beginning of a paragraph. Much simpler then I thought of :) ... even tough it's "not good enough for me".

6th November 2007, 21:57
I'd say it's a bit stupid, because the docs say that setUserState() saves an integer that can be for example used for syntax highlighting. This suggests it can be used for something else effectively breaking the highlighter.

I just read your question again - you wanted the state of a position inside a paragraph. I don't think there is such concept. The state is defined for the position between two paragraphs. I think that instead you can query for the char format of a specified position. It probably won't do you much good either, but maybe you can work something out with it. What is the purpose of such interest?

6th November 2007, 23:28
Yes, it seems a bug in the Qt4 API, it should be documented that this is 'too fragile" to mess with.

I am toying with the idea of using the syntax highlighter code to know the state of each word in a paragraph. This will help me (for example) knowing which words can I send to a spell checker (only words inside comments or strings for example).

Yes, the variable I showed before only gives me the state in the beginning (or end) or each paragraph.