2
votes

I'm having a problem where I cannot deterministically tell when a layout takes place.

Simplified example:

I have a widget with two sub-widgets.

  • Top widget has expanding width and fixed height. Let's say the fixed height defaults to 50.
  • Bottom widget has expanding height and width
  • There's a vertical layout set up.

Let's say there's a button somewhere i can click to run code. The button is not on the widget itself to make things simple...

When the button is clicked, i do the following:

  1. I measure the height of the bottom expandable widget. The height is 100.
  2. I then "topWidget->SetMaximumHeight(100)", and "topWidget->SetMinimumHeight(100)"
  3. I measure the height of the bottom expandable widget again. The height is still 100

But I see the bottom expandable widget change height!

this means that when I do step #3, the layout hasn't taken place yet. No matter what I do, update(), updateGeometry() - I cannot get the bottom widget to change height between step #2 and step #3.

The only way for me to resolve this is to have a timer wait, say 250ms, and then measure the height of the bottom widget -- and then It's always correct - meaning the re-layout took place correctly

This is a crazy/dirty solution, but I don't have another. Is there an API I am missing to allow me to deterministically, synchronously change the layout and query for the new size of affected widgets right after?

1
Try calling QApplication::processEvents() between steps #2 and #3 (it should do what the timer allow the event loop to do).alexisdm
Try to call activate() on your layout.Pavel Strakhov
So the top widget doesn't resize before you recheck the size of the bottom? Maybe you could try checking for the resize event coming from the top widget, and do step #3 after you have received the signal. According to the doc, " When resizeEvent() is called, the widget already has its new geometry." qt-project.org/doc/qt-5.0/qtwidgets/qwidget.html#resizeEventkrb686
I am using QT 4.8.5,and no, I can swear that resizeEvent called on the top widget is sometimes called BEFORE the actual change is made to the geometry. querying for "geometry()" in the "resizeEvent" code on the internal bottom widget gives the old height, and for sure the lower widget changes its height later. I caught this behavior with exact logging.JasonGenX
QApplication::processEvents() did the job. If you post your tip as an answer I'll credit you for it.JasonGenX

1 Answers

0
votes

from user: alexisdm

Try calling QApplication::processEvents() between steps #2 and #3 (it should do what the timer allow the event loop to do)