How QSizePolicy work?
-
From qt documentation
QSizePolicy::Minimum
The sizeHint() is minimal, and sufficient. The widget can be expanded, but there is no advantage to it being larger (e.g. the horizontal direction of a push button). It cannot be smaller than the size provided by sizeHint().
But what we have next Two PushButton
Both QPushButton size are smaller than the size provided by its sizeHint(). Both QPushButton have horizontal SizePolicy set to Minimum and QGridLayout have layoutConstraint set to SetDefaultConstraint. Why am I seeing this result?XML part of code
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Widget</class> <widget class="QWidget" name="Widget"> <property name="enabled"> <bool>true</bool> </property> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>175</width> <height>41</height> </rect> </property> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>100</width> <height>0</height> </size> </property> <property name="sizeIncrement"> <size> <width>0</width> <height>300</height> </size> </property> <property name="windowTitle"> <string>Form</string> </property> <layout class="QHBoxLayout" name="horizontalLayout"> <property name="sizeConstraint"> <enum>QLayout::SetDefaultConstraint</enum> </property> <property name="leftMargin"> <number>14</number> </property> <item> <widget class="QPushButton" name="pushButton"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="layoutDirection"> <enum>Qt::LeftToRight</enum> </property> <property name="text"> <string>Minimum</string> </property> <property name="checkable"> <bool>false</bool> </property> <property name="autoDefault"> <bool>false</bool> </property> <property name="default"> <bool>false</bool> </property> <property name="flat"> <bool>false</bool> </property> </widget> </item> <item> <widget class="QPushButton" name="pushButton_3"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="text"> <string>Expanding</string> </property> </widget> </item> </layout> </widget> <resources/> <connections/> </ui>
-
Hi and welcome
I think sizehint is just a hint.
Can you try setting minimumSize on the buttons and
see what happens? -
Hi, welcome to the forum.
The info about this kind of stuff is in the documentation, although I admit it's scattered across different parts and not that easy to put together if you don't know what to look for.
Note that your parent widget has a
minimumSize
set to 100 (less then the two buttons size hint and margin/spacing).
To put it simply usingminimumSize
overrides the minimum size returned by its layout (which by default returns the combined minimums of the children + margin/spacing). So in this case the size policy of the children is ignored. To make it relevant don't useminimumSize
on the parent. There's also a minimum size of a window defined by the platform, so you won't actually get to 100 (at least with this kind of window frame), but that's the general rule.See minimumSize docs for the relevant info.
-
@Chris-Kawa Thank for you reply. But now I want to see difference between MinimumExpanding and Expanding policy.
In this example no any difference.<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Widget</class> <widget class="QWidget" name="Widget"> <property name="enabled"> <bool>true</bool> </property> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>197</width> <height>41</height> </rect> </property> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>0</width> <height>0</height> </size> </property> <property name="sizeIncrement"> <size> <width>0</width> <height>300</height> </size> </property> <property name="windowTitle"> <string>Form</string> </property> <layout class="QHBoxLayout" name="horizontalLayout"> <property name="sizeConstraint"> <enum>QLayout::SetDefaultConstraint</enum> </property> <item> <widget class="QPushButton" name="pushButton"> <property name="sizePolicy"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="layoutDirection"> <enum>Qt::LeftToRight</enum> </property> <property name="text"> <string>MinimumExpanding</string> </property> <property name="checkable"> <bool>false</bool> </property> <property name="autoDefault"> <bool>false</bool> </property> <property name="default"> <bool>false</bool> </property> <property name="flat"> <bool>false</bool> </property> </widget> </item> <item> <widget class="QPushButton" name="pushButton_3"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Maximum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="text"> <string>Expanding</string> </property> </widget> </item> </layout> </widget> <resources/> <connections/> </ui>
-
Both buttons have an Expanding policy so they will get the same amount of space when the parent grows. As for shrinking - the button with MinimumExpanding policy respects the
sizeHint
as the minimum size. The button with just Expanding policy does not have that restriction so it theoretically could shrink, but QPushButton also implements minimumSizeHint, which, if not overriden by other stuff, indicates the minimum size of the widget. It so happens that QPushButton returns the same value for bothsizeHint
andminimumSizeHint
. If you'd subclass QPushButton and implementminimumSizeHint
to return, say, 0, you would see the difference - the MinimumExpanding button would not shrink belowsizeHint
, but the Expanding one would.If you're learning about layouts, hints and policies I'd suggest to try this stuff on plain QWidgets (you can color them with a stylesheet to see where they are). QPushButton is a specialized class that sets a lot of these properties to non-default values so it's harder to understand what's going on.
-
@Chris-Kawa
Ok. Next problem.
I set layoutSizeConstraint to SetNoConstraint. On image the widget have minimum width. How its width calculated? And why in this example both width of QPushButton can be smaller than sizeHint? About height of widget, I can shrink it to 0. I cannot shrink to 0 the width. Why?XML
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Widget</class> <widget class="QWidget" name="Widget"> <property name="enabled"> <bool>true</bool> </property> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>197</width> <height>41</height> </rect> </property> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>0</width> <height>0</height> </size> </property> <property name="sizeIncrement"> <size> <width>0</width> <height>300</height> </size> </property> <property name="windowTitle"> <string>Form</string> </property> <layout class="QHBoxLayout" name="horizontalLayout"> <property name="sizeConstraint"> <enum>QLayout::SetNoConstraint</enum> </property> <item> <widget class="QPushButton" name="pushButton"> <property name="sizePolicy"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="layoutDirection"> <enum>Qt::LeftToRight</enum> </property> <property name="text"> <string>MinimumExpanding</string> </property> <property name="checkable"> <bool>false</bool> </property> <property name="autoDefault"> <bool>false</bool> </property> <property name="default"> <bool>false</bool> </property> <property name="flat"> <bool>false</bool> </property> </widget> </item> <item> <widget class="QPushButton" name="pushButton_3"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Maximum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="text"> <string>Expanding</string> </property> </widget> </item> </layout> </widget> <resources/> <connections/> </ui>
-
When you set a layout constraint to
SetNoConstraint
it means that the layout ignores any minimum size hints from its widgets. So if parent is smaller than the buttons policy suggests, they will be shrunk anyway.You can shrink the height of the widget to 0 because its layout has a SetNoConstraint set - ignores any content hints.
You can shrink the width of the widget to the minimum size the platform allows. It will usually vary depending on the window frame setup - in your case (the default) the minimum width is the width needed to show the application icon and the three system buttons - minimize, maximize and close. If you set the frame to, for example,setWindowFlags(Qt::CustomizeWindowHint);
, you'll be able to resize the widget to 0 width. -
@Chris-Kawa Oh, you are really guru of Qt. Thank for all.