View Full Version : Fit to width in QScrollArea unstable

11th October 2006, 13:01
I have a nasty problem with QScrollArea.

I draw a document where the width / height ratio is constant. The document has a zoom factor.

I use in widget() the function minimumSizeHint() which give back conforming of the document zoom factor and the parentWidget()->size() the new document size. Because of the fit to width the document size is the same than the parent widget size.

Ok until now all seems ok!

But, if the widget size is too big the document will switch on the vertical scrollbar. But the new widget size (with the vertical scroller) could draw a smaller document which one is enough small to fit in the widget, now the vertical scroll will switch off ... and so on ...

Any one has an idea how to do it ?


11th October 2006, 18:18
Have you tried QScrollArea::setWidgetResizable(true)? It will resize the widget in order to avoid scroll bars where they can be avoided, or to take advantage of extra space. I haven't looked into the sources but I believe QScrollArea in "widget resizable" mode honors it's widget's minimum size hint and the scroll bars appear when the size would be less than that.

12th October 2006, 11:58
It's exactly the problem ... I have set QScrollArea::setWidgetResizable(true)!!

But you have 2 states: one where you need a scroller (because it's too big to fit in) and one where you have a scroller but you don't need one (because it's enough small).

1 resize event -> 2 paint event -> 1 resize event -> 2 paint event ....

All works fine in scroll area if you have a fixed size of widget(), but if your size denpends of the scroll area size.

Ok, after 2 days of fight I have found a solution (not so beautiful :o ) in a derivation of QScrollArea with margins .... during the resize event:

int scroll_pixel = style()->pixelMetric(QStyle::PM_ScrollBarExtent);
QSize size_pixel = size() - 2*QSize(frameWidth(), frameWidth());

qreal zoom_min = size_pixel.width() / doc_size_pixel.width();
qreal zoom_max = (size_pixel.width() - scroll_pixel) / doc_size_pixel.width();

bool need_a_margin = (zoom_min * doc_size_pixel.height() > size_pixel.height());
bool need_a_scroll = (zoom_max * doc_size_pixel.height() > size_pixel.height());

m_zoom = (need_a_margin) ? zoom_max : zoom_min;

setContentsMargins(0, 0, (need_a_margin && !need_a_scroll) ? scroll_pixel : 0, 0);