[Qt-interest] QScrollArea::resize() does not resize the viewport

Nikos Chantziaras realnc at arcor.de
Mon May 3 14:51:26 CEST 2010


On 05/03/2010 03:22 PM, John McClurkin wrote:
> Nikos Chantziaras wrote:
>> Calling resize() or setGeometry() on a QScrollArea results in the
>> viewport() dimensions not being updated:
>>
>> void foo( QScrollArea* scr )
>> {
>> scr->resize(500, 500);
>> do_some_stuff(scr->viewport()->size());
>> }
>>
>> do_some_stuff() receives a wrong size. Is this normal? For the code to
>> work correctly, I need to do:
>>
>>
>> void foo( QScrollArea* scr )
>> {
>> scr->viewport()->resize(500, 500); // <-- Smells funny
>> do_some_stuff(scr->viewport()->size());
>> }
>>
>> Why is that? When the QScrollArea is resized with the mouse, the
>> viewport changes accordingly. When it's resized by code (like above),
>> the viewport doesn't change.
> After setting the object size with resize from code, you need to let the
> event loop run to actually do the resize. You can try putting
> QApplication::processEvents() after scr->resize. Alternately, send a
> signal after scr->resize and calling do_some_stuff in a slot connected
> to that signal.

Though I didn't mentioned it in my OP, I've tried processEvents(), but I 
recently discovered that the problem was due to 'scr' not being visible 
yet (that is, I never called scr->show()).  That's why the viewport size 
didn't change; it seems Qt only resizes visible widgets; on non-visible 
ones, all resize requests are simply queued together and executed only 
when the widget becomes visible.

The problem with this is that the "resize(500, 500)" is preliminary. 
It's the largest size the widget can have and the final size is not 
known yet; other code will adapt that size.  Calling show() and then 
keep resizing it and calling processEvents() results in visible ugliness 
as the widget keeps quickly changing size on screen before it settles down.

It seems that the following kludge actually works nicely:

   void foo( QScrollArea* scr )
   {
      scr->resize(500, 500);
      scr->show();
      scr->hide();
      do_some_stuff(scr->viewport()->size());
   }

Calling show() and immediately hide() again, without doing 
processEvents(), will resize the viewport correctly and without visible 
artifacts.



More information about the Qt-interest-old mailing list