PDA

View Full Version : restorGeometry() is not working... or maybe a contained Widget/layout causes resize?



davethomaspilot
19th September 2015, 19:56
I'm using saveGeometry/saveState and restorGeometry/restoreState as documented here:

http://doc.qt.io/qt-4.8/restoring-geometry.html

When I start the application, the QMainWindow has the same width as when it was closed, but its height grows so that the bottom part of the widget is not visible. I resize the window and exit, but the new height is not restored on the next application start-up.

If I set a maximum size on the QMainWindow, this can be avoided. But, I don't want to do that since at a different screen resolution, a bigger QMainWindow height wouldn't be an issue.

Can a layout or widgets inside a QMainWindow cause it to grow in size after its geometry is restored?

If not, what else might be causing this?

anda_skoa
19th September 2015, 21:14
Depends on when you restore the geometry.

When it is done before the layouts have done their work, then the window might grow if the current size is smaller than the overall preferred size.

Cheers,
_

davethomaspilot
20th September 2015, 02:23
So, when have the layouts done their work? After the MainWindow::show()?

So, when have the layouts done their work? After the MainWindow::show()?

Added after 1 51 minutes:

So, I'm trying to figure out what's causing the MainWindow to resize. While fiddling with the various controls, I found something I don't understand that I think is important.

The QMainWindow has a QCanvas which has a QLabel in it. A pixmap from a .png file is loaded for the QLabel.

The size of the QLabel when the image as reported by QLabel::height() and QLabel::width() is what I expected-- larger than the ScrollArea size as reported by QScrollArea::height and QScrollArea::width() So, I figured scrollbars would appear on the QScrollArea.

But, even though the size as reported by QLabel::height() and QLabel::width() is LARGER than the QScrollArea height/width, the label fits within the ScrollArea!. It's like the units reported by the QLabel::height() and QLabel::width() are different than that returned by QScrollArea::height(), and QScrollArea::width()? Pixels versus something else?

Other than the pixmap appearing smaller than I expected and inconsistent with the canvas reported width and height, everything works as you'd expect--if I make the QMainWindow small enough, scrollbars show up on the QScrollArea and work fine. Sizing the QMainWindow big enough, and there's empty space in the QCanvas around the QLabel pixmap.

I know I could scale the pixmap to make it bigger, but there are so many "degrees of freedom" in widget size policies, adjustSize enablement, etc., that it can quickly get to be a mess if I don't really understand what's happening--and I don't!

Any help would be appreciated!

Thanks

anda_skoa
20th September 2015, 10:29
The setup is too complicated to discuss in just words.

Maybe you can create a minimal exmaple that shows the behavior?

Cheers,
_

davethomaspilot
20th September 2015, 23:37
Good suggestion. I'll do that and/or post a screen shot, but maybe it's something simpler...

Investigating further, I've found the image pixmap in the label is somehow getting cropped by the ScrollArea that contains it.

I've verified the image in the .png file is NOT cropped using a separate image viewer. The QImage sizes to match the QPixmap and the QLabel adjusts its size to fit the Pixmap. The QImage is the expected size (1292x964) after loading the pixmap into the QLabel, the label size is also 1292x964. Everything seems fine.

The QScrollArea is reported as 635x424 (QScrollArea::width() and QScrollArea::height(). So, I would expect the ScrollArea would present scrollbars on the cropped QLabel's pixmap, but they don't show up unless the ScrollArea size is made smaller.

So, the QScrollArea is cropping the QLabel QPixmap without presenting scrollbars. It still does provide scrollbars, if the QScrollArea it is sized smaller than the cropped image.

Good suggestion. I'll do that and/or post a screen shot, but maybe it's something simpler...

Investigating further, I've found the image pixmap in the label is somehow getting cropped by the ScrollArea that contains it.

I've verified the image in the .png file is NOT cropped using a separate image viewer. The QImage sizes to match the QPixmap and the QLabel adjusts its size to fit the Pixmap. The QImage is the expected size (1292x964) after loading the pixmap into the QLabel, the label size is also 1292x964. Everything seems fine.

The QScrollArea is reported as 635x424 (QScrollArea::width() and QScrollArea::height(). So, I would expect the ScrollArea would present scrollbars on the cropped QLabel's pixmap, but they don't show up unless the ScrollArea size is made smaller.

So, the QScrollArea is cropping the QLabel QPixmap without presenting scrollbars. It still does provide scrollbars, if the QScrollArea it is sized smaller than the cropped image.

Added after 27 minutes:

So, I reread the QScrollArea documentation yet again and found:


If a standard QWidget is used for the child widget, it may be necessary to call QWidget::setMinimumSize() to ensure that the contents of the widget are shown correctly within the scroll area.

I used QtDesigner and dragged a QLabel into a QScrollArea. In QtDesigner, the ObjectInspector shows the QScrollArea doesn't simply contain the QLabel widget. Instead it contains a "scrollAreaWidgetContents" QWidget. The QLabel is contained within that scrollAreaWidgetContents widget.

So, I set the minimimum size of the scrollAreaWidgetContents widget, and now things are working as I expected. The image is cropped to the ScrollArea size, but scroll bars are presented so you scroll to move the ScrollArea over the image area of interest.

So, I'm wondering if I did something "wierd" to create that extra level of hierarchy, or whether that's the way its supposed to work, at least when using QtDesigner? I don't see anything about that in the QScrollArea documentation.

Also, this will only work with a fixed image size, since I have to set a fixed minimum size. If the image size is larger than the minimum set, the image will be cropped. Not sure what will happen if the image is smaller--have to check that.

anda_skoa
21st September 2015, 09:00
So, I'm wondering if I did something "wierd" to create that extra level of hierarchy, or whether that's the way its supposed to work, at least when using QtDesigner? I don't see anything about that in the QScrollArea documentation.

This is just how designer works.
It also creates a "central widget" widget when designing a main window and puts the developer's content into that.



Also, this will only work with a fixed image size, since I have to set a fixed minimum size. If the image size is larger than the minimum set, the image will be cropped. Not sure what will happen if the image is smaller--have to check that.

You might need a QLabel subclass so you can adjust minimumSize according to the image that is being loaded/shown.

Cheers,
_

davethomaspilot
22nd September 2015, 22:57
Thanks!

Actually, since it's easy to get the size of the QLabel, I'll just use the size to programmatically set the size of the scrollAreaWidgetContents.

Should work, but it still "smells" like something isn't quite right. Simple enough to do, once you figure out you need to do it, I guess.