Guides/Window Driver/Layout
layout using grid
If you have a regular two-dimensional layout, you can create it using the grid control.
More complex layouts require the use of bins, which are invisible two-dimensional containers that you create. A bin contains child controls or other bins, and has associated instructions for the spatial relationship between the contents. As the parent is resized, the layout is automatically recalculated.
bin h/bin v/bin z
Implied bin v
Every form has an implied vertical bin, into which all widgets will be placed.
pc form closeok; cc A button cc B button cc C button
Since the container is vertical, widgets inside it will be stacked vertically. Result will look like this:
+-+ |A| |B| |C| +-+
bin h
In order to put them in a horizontal row, put all widgets between bin h and the corresponding bin z, here pc command and cc child parameters are omitted for brevity, indentation added for clarity.
bin h cc A cc B cc C bin z
the result is
+-----+ |A B C| +-----+
To let only the first 2 widgets on the upper row and the other on the lower row, take C out of the bin h/bin z pair so that C is in a row of its own. Again, all rows will be stacked inside the implied vertical bin.
bin h cc A cc B bin z cc C
+---+ |A B| +---+ | C | +---+
bin z
Unlike bin h and bin v which are concrete Qt Widgets (QHBoxLayout and QVBoxLayout), bin z is not a widget or any real object: it is just a syntax element to mark the extent of the preceding bin h or bin v.
nested bin
Its transpose is slightly complicated,
+-+-+ |A| | | |C| |B| | +---+
We imagine A and B are contained inside a vertical bin. This vertical bin and C are contained inside a horizontal bin.
bin h bin v cc A cc B bin z cc C bin z
Here we need an outer horizontal bin, otherwise C will be placed under A and B because of the outer implied vertical bin.
Advanced Example
This scheme is very flexible and very complex placement can be achieved. Take this as an example,
-----------------------+ | +---+ | | |A B| | | +---+ D E | | | C | | | +---+ | +----------------------+ | +-+ +-+-+ | | |F| |H|J| | | | | | |K| M | | |G| |I|L| | | +-+ +-+-+ | +----------------------+
Working either top-down or bottom-up will get the following realization.
bin h bin v bin h cc A cc B bin z cc C bin z cc D cc E bin z bin h bin v cc F cc G bin z bin h bin v cc I cc H bin z bin v cc J cc K cc L bin z bin z cc M bin z
Short Hand
Writing codes this way can be tedious, reminiscent of good old structural programming in Pascal. There is a short-hand that any consecutive bin can be compressed into a single bin command, the space within is optional. Moreover any missing trailing bin z will be supplied by J automatically. So, the above can be simplified to
bin hvh cc A cc B bin z cc C bin z cc D cc E bin zhv cc F cc G bin zhv cc I cc H bin zv cc J cc K cc L bin zz cc M
this is also the style used in various examples and demos codes. This style can be hard to read for the un-initiated, in the same noble tradition of J.
bin s
bin s is not a bin (QLayout) but it is a real space-filling widget. It accepts no widgets inside it and requires no termination bin z command. Its sole purpose is to occupy space that will be otherwise occupied by other widgets.
For example following will produce a row of 3 widgets, each of them will grow to take up all available space inside a form. This is how Qt will manage the size of widgets inside a form. In short, there will be no extra space left, all space are occupied by some widgets.
bin h cc A cc B cc C bin z
----------------- | A B C | -----------------
To make them right-justified, we can put a bin s in the front.
bin hs cc A cc B cc C bin z
There will then be 4 widgets inside the bin h. It will look like this with xxxx representing the space occupied by bin s.
----------------- |xxxxxxxx A B C| -----------------
To left-justify by adding a trailing bin s
bin h cc A cc B cc C bin sz
----------------- |A B C xxxxxxxx | -----------------
To center them, put bin s on both ends.
bin hs cc A cc B cc C bin sz
----------------- |xxxx A B C xxxx| -----------------
For more than 1 bin s, the extra space will be divided equally.
bin hs cc A bin s cc B cc C bin z
----------------- |xxxx A xxxx B C| -----------------
bin s works inside a vertical bin in the same manner.
Stretch Factor
The "hvs" commands can optionally be followed by an integer stretch factor, default 0 (no stretch). Any spaces are ignored.
bin hs1 cc A bin s2 cc B cc C bin z
----------------- | xx A xxxxx B C| -----------------
Note that a bin s (or bin s0) will take no space unless there are no widgets with a non-zero stretch factor in the same layout box.
Experiment what will the following look like,
bin hs1 cc A bin s2 cc B cc C bin sz
bin g
The command bin g sets a grid layout. It must be embedded within an explicit bin h or bin v to set the overall direction (the implied vertical bin doesn't count).
Within the bin g, use wd cc grid ... commands to control the shape and attributes of the grid, and then populate the grid with controls.
Study the grid.ijs code in the Qt demo and Window Driver for its usage.
bin m
The command bin m N sets ContentsMargins and Spacing to N, e.g. bin m8.
This is particularly useful after an earlier use of "flush" when creating a control. This set all ContentsMargins and Spacing to 0, so that the bin command can then override this for the control's children.
bin p
The command bin p N adds a non-stretchable space with size N to the end of this layout, e.g. bin p8.
Size Policy
Each class of controls has its own size policy, eg. push buttons will grow or shrink horizontally but stayed fixed vertically. This can be overridden by set sizepolicy command
For example:
wd 'cc c button; cn "?"; set maxwh 32 32;set c sizepolicy maximum'
creates a square size of button with caption "?"
---
Contributed by Bill Lam