Skip to content
bob-white edited this page Jul 24, 2017 · 8 revisions

This tutorial assumes you've gone through the first and second tutorials already

One of the most tedious and time-consuming parts of laying out a gui in Maya is managing the overall structure of a window or layout. The basic layout commands like ColumnLayout and RowLayout are clunky and don't handle resizable elements very well. Maya also provides a much more powerful tool in formLayouts -- but unfortunately the syntax for them is mind-numbing.

mGui supports the formLayout command as the FormLayout class, using the same syntax as other mGui classes. However a much easier set of tools is available in the module mGui.forms. This module makes it much simpler to layout your gui so that it responds properly when users resize windows or panels.

For an overview of all the classes in mGui.forms, see the forms page.

Basic forms

The big advantage of forms is that they handle resizing properly. If you stick with ColumnLayout and RowLayout, for example, it's hard to make even something as simple as a column of checkboxes with followed by an 'accept' and a 'cancel' button which will properly resize:

  ---------------
  |  [] check   |
  |  [] check   |
  | [yes]  [no] | 
  ---------------

in mGui, this would look like this:

from mGui.gui import *
from mGui.forms import *

with Window() as window:
    with FooterForm() as main:
        with VerticalForm() as checkboxes:
            one = CheckBox(label = 'one')
            two = CheckBox(label = 'two')
        with HorizontalStretchForm() as footer:
            yes = Button('yes', width = 60)
            no = Button('no', width = 60)

Here's what's happening in this example:

  1. the FooterForm creates a form which has two children. The first one is expandable, the bottom one will stick to the bottom of the window.
  2. the first child of the footer is a VerticalForm, which is similar to a columnLayout except that its children will resize horizontally as it scales.
  3. in that Vertical form we make two checkboxes
  4. the HorizontalStretchForm is the second child of the FooterForm created in step 1 (you can easily see this from the indents, which are very useful for understanding the structure). Because it's the footer of the FooterForm, it will move and expand with the bottom of the window. And because it's a HorizontalStretchForm(), its children will both stretch to handle expansion in the horizontal direction.

Controlling spacing

Another big advantage of the forms classes is that they make it relatively easy to handle the spacing and layout of the forms themselves. Instead of trying to lay out your controls with manual placement options, nested forms can make it easy to achieve a neat, consistent layout that also works with resizable windows.

If you ran the example above you'll notice that the checkboxes are very snug against the left-hand margin of the window, which does not look very nice. mGui includes a robust set of tools for managing graphic styles in the mGui.styles module. We can use the margin and spacing features of the CSS class to make get those checkboxes into a more attractive location.

Here's the same example, with the addition of CSS to handle the spacing of the checkboxes

from mGui.gui import *
from mGui.forms import *
from mGui.styles import CSS

padding = CSS(None, margin = (24,12))

with Window() as window:
    with FooterForm() as main:
        with VerticalForm(css=padding) as checkboxes:
            one = CheckBox(label = 'one')
            two = CheckBox(label = 'two')
        with HorizontalStretchForm() as footer:
            yes = Button('yes', width = 60)
            no = Button('no', width = 60)

When you run this the VerticalForm containing the checkboxes has a 24 pixel margin on the sides and a 12 pixel margin at the top, which is much more readable.

The CSS class also allows you to specify the spacing between objects in forms. You'll notice that the 'yes' and 'no' buttons are right up against each other. We can fix that with a CSS like this:

padding = CSS(None, margin = (24,12))
btns = CSS(None, margin = (8,8), spacing = (4,0))
with Window() as window:
    with FooterForm() as main:
        with VerticalForm(css=padding) as checkboxes:
            one = CheckBox(label = 'one')
            two = CheckBox(label = 'two')
        with HorizontalStretchForm( css = btns) as footer:
            yes = Button('yes', width = 60)
            no = Button('no', width = 60)

Now the buttons have an 8-pixel margin between them and the window and an 8-pixel buffer (because there are two 4-pixel spacings) in between them. By consistent use of forms and CSS objects you can keep your guis neat with a minimum of effort -- and keep the visual style information disentangled from the logical structure of the gui.

Clone this wiki locally