4
votes

This is driving me nuts. I have a custom menu class that, when set visible, shows a list of items located in a particular folder. When a hardware button is pressed, my application gets the latest list of items, populates the menu with them, and returns.

The menu displaying these items uses a QListWidget filled with custom widgets. Each of the widgets contains one or more QLabels in a horizontal layout, and is created at the time the menu is shown. In order to adjust the text displayed based on the menu width available, I need to get the size of the QLabel AFTER it has been resized according to the layout, but before the menu becomes visible to the user. The problem is, my layout does not get updated until all of the functions constructing my list return.

I have tried QApplication::ProcessEvents() and the layout update functions, but none of them have updated the values of my QLabels before returning. I can set a QTimer when the button is initially pressed, and have it show the menu, update the items, and stop itself, but that seems like a terrible solution.

Any help would really be appreciated! I've spent most of a day on this.

Marlon

4
This may not be the best solution, but what I ended up doing was showing the menu right before attempting to get the size of the labels in the layout. Qt doesn't seem to update the geometries of items in a layout unless the items are visible.user672033
Please amend your question with the requirements, otherwise this smells like an X-Y problem. I'm not convinced you should be using QLabels in a horizontal layout at all. One hint that it's not the right way to go rests with the fact that you can't get it to work: the API is telling you something :)Kuba hasn't forgotten Monica

4 Answers

7
votes

I had this exact problem and could not find an answer anywhere on the Internet. Calling Layout.update(), Layout.activate(), or widget.adjustSize() (all suggested in various places) all did not work.

I had a widget with a vertical layout that I wanted to add a QLabel to and then immediately use the size of the QLabel.

The only thing that worked reliably was

layout->addWidget(myLabel);
myLabel->show();
size = myLabel->size();

It would seem that layouts will just not recalculate until you either return from a function and allow the Qt event loop to progress or manually call show() yourself.

6
votes

How to update a QLayout and get the new dimensions before returning?

Don't. You're not meant to do that. It'll drive you "nuts" because you're doing it backwards. Layout updates are handled asynchronously from the event loop. Instead of getting layout dimensions right away, set yourself up to be part of the system. Some options are:

  1. Implement a custom widget that will interact properly with the layout, growing to fill the available width of the layout. Perhaps all you need is a size policy and a way to elide text?

  2. Make a custom layout that takes the special properties of your use case into account.

3
votes

You want to call QWidget::adjustSize() on your parent widget. This will force the layout recalculations.

2
votes

Have you tried using layout()->update(); ?