PDA

View Full Version : QAbstractScrollArea forces repainting the whole viewport



Charletes
7th December 2010, 23:49
Hi!

I'm developing a personal project in which I use a QAbstractScrollArea. Its viewport is the parent of another widget (subclass of QWidget) in which the drawing is made. While I was analysing the drawing performance on the viewport, I realized that, whenever I scroll the widget (using move()), the widget gets a paintEvent whose boundingRect is the size of the whole viewport.

The problem with this behaviour is that it forces the widget to redraw the entire visible area every time it is scrolled. If I use a QScrollArea instead (which I can't use because I need a finer-grained control over the viewport), when you scroll the widget moving the bars then the paintEvent which the widget receives has a region() the exact size of the scrolled area, and then the repainting is optimal.

I don't understand what I'm doing wrong, if anyone could help...

Thank you!

wysota
8th December 2010, 00:23
It makes perfect sense to redraw the whole viewport when it is scrolled for an abstract scroll area. The base class doesn't know how much of the viewport actually changes when scroll is requested so it has to update everything unless a subclass says otherwise (probably from within QAbstractScrollArea::scrollContentsBy() - even the docs say so).

Charletes
8th December 2010, 00:32
Hi,

Thanks for your fast answer! And what should I do in order to repaint only the needed areas? If I call viewport()->repaint(the_proper_area) in scrollContentsBy(), the widget is still asked for a viewport-size repaint when being moved from scrollContentsBy :(

wysota
8th December 2010, 00:38
First of all use update() instead of repaint(). Second of all if you move a widget around then how much of it would you like to repaint if the background under it may be changing? I don't know what you are doing or what you are trying to do so it is hard to help you. Foremost I don't understand why you can't use QScrollArea instead of its base class.

Charletes
8th December 2010, 12:37
What I am trying to do is implementing a plain text editor. I need to use a QAbstractScrollArea instead of a QScrollArea because I want it to scroll lines instead of pixels when receiving a wheel event. Moreover, I'd like to have in the viewport another widget which shows line numbers and, when receiving horizontal scroll events, scroll only the widget with the text but not the widget with the line numbers.

I have already that working, but every time I move the widgets I receive paint event the whole size of the viewport. I can't use a QScrollArea because I can't scroll horizontally only part of the widgets shown as I need.

How can I tell the QAbstractScrollArea or the viewport() to update() only the needed parts?

wysota
8th December 2010, 12:57
What I am trying to do is implementing a plain text editor.
And what is wrong with QPlainTextEdit?


I need to use a QAbstractScrollArea instead of a QScrollArea because I want it to scroll lines instead of pixels when receiving a wheel event.
I don't see how QScrollArea is preventing you from doing that.


Moreover, I'd like to have in the viewport another widget which shows line numbers and, when receiving horizontal scroll events, scroll only the widget with the text but not the widget with the line numbers.
That's not how it's done. Use QAbstractScrollArea::setViewportMargins() and place your line counting widget in the blank space left by the viewport.

Charletes
8th December 2010, 13:04
And what is wrong with QPlainTextEdit?

I'd like to be able to implement a column-mode, and as far as I know that can't be done using QPlainTextEditor.



That's not how it's done. Use QAbstractScrollArea::setViewportMargins() and place your line counting widget in the blank space left by the viewport.

I didn't know that it could be done that way. I'll try it, it seems to be easier that way.

Thanks!

wysota
8th December 2010, 13:11
I'd like to be able to implement a column-mode, and as far as I know that can't be done using QPlainTextEditor.
I don't know what "column mode" is but there is a good chance it can be implemented on top of what QPlaintTextEdit offers.

Charletes
8th December 2010, 13:15
What most text editors call column-mode is the posiblity on writing on several lines at once and being able to select a square of text instead of lines. Emacs call it rectangle mode I think.

wysota
8th December 2010, 13:25
I don't see a reason why this couldn't be implemented with QPlainTextEdit.