Size policies
If you change the height of the main window of our game, you will note that different widgets are resized in a different way. In particular, buttons retain their original height, and labels gain empty fields to the top and bottom of the text:
This is because each widget has a property called sizePolicy, which decides how a widget is to be resized by a layout. You can set separate size policies for horizontal and vertical directions. A button has a vertical size policy of Fixed by default, which means that the height of the widget will not change from the default height regardless of how much space there is available. A label has a Preferred size policy by default. The following are the available size policies:
- Ignored: In this, the default size of the widget is ignored and the widget can freely grow and shrink
- Fixed: In this, the default size is the only allowed size of the widget
- Preferred: In this, the default size is the desired size, but both smaller and bigger sizes are acceptable
- Minimum: In this, the default size is the smallest acceptable size for the widget, but the widget can be made larger without hurting its functionality
- Maximum: In this, the default size is the largest size of the widget, and the widget can be shrunk (even to nothing) without hurting its functionality
- Expanding: In this, the default size is the desired size; a smaller size (even zero) is acceptable, but the widget is able to increase its usefulness when more and more space is assigned to it
- MinimumExpanding: This is a combination of Minimum and Expanding—the widget is greedy in terms of space, and it cannot be made smaller than its default size
How do we determine the default size? The answer is by the size returned by the sizeHint virtual method. For layouts, the size is calculated based on the sizes and size policies of their child widgets and nested layouts. For basic widgets, the value returned by sizeHint depends on the content of the widget. In the case of a button, if it holds a line of text and an icon, sizeHint will return the size that is required to fully encompass the text, icon, some space between them, the button frame, and the padding between the frame and content itself.
In our form, we prefer that when the main window is resized, the labels will keep their height, and the game board buttons will grow. To do this, open mainwindow.ui in the form editor, select the first label, and then hold Ctrl and click on the second label. Now both labels are selected, so we can edit their properties at the same time. Locate sizePolicy in the property editor (if you're having trouble locating a property, use the Filter field above the property editor) and expand it by clicking on the triangle to its left. Set Vertical Policy to Fixed. You will see the changes in the form's layout immediately.
The buttons on the game board are created in the code, so navigate to the constructor of TicTacToeWidget class and set the size policy using the following code:
QPushButton *button = new QPushButton(" "); button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
This will change both the horizontal and vertical policy of buttons to Preferred. Run the game and observe the changes: