Like all sane people, I hate writing Maya native gui. And like all sane people I also hate QT. Both are necessary but both are extra chatty apis which often smother you in implementation detail.
I hate JavaScript too (starting to see a pattern here…) but I do kind of envy the CSS + HTML ecosystem which does a better job of keeping the layout and structure of a UI separate the implementation. Especially in maya.cmds
this is hard to do!
However, all of the gui calls in cmds
accept the ** form of arguments – you can pass them a dictionary instead of manually specifying a flag, ie
cmds.button(label = "label", width = 100, height = 40)
can be written as
buttonstyle = {'width': 100, 'height': 40, 'label': 'label'}
cmds.button(**buttonstyle)
this is particularly handy because you can mix flags and the dictionaries as long as you don’t overlap them, so
buttonstyle = {'width': 100, 'height': 40} # remove 'label'
cmds.button(label = "button1", **buttonstyle)
cmds.button(label = "button2", **buttonstyle)
But the other nice thing about CSS is that it’s hierarchical – you can pass settings down from one CSS style to another. In the example above you’d have to do that manually. But modern Python includes the often-overlooked collections.ChainMap
, which is basically just a way to layer dictionaries on top of each other. So you can do something like
std_width = {'width': 72}
extra_wide = {'width': 100}
std_height = {'height': 40}
red = {'bgc': (1,0.2, 0.2)}
red_button = ChainMap(std_width , std_height, red)
cmds.button(label = "regular size red button", **red_button)
big_red = ChainMap(extra_wide, red_button)
cmds.button(label = "big red button", **big_red )
plus you can always make little factories to mass produce these:
def styled_control (cmd, style):
def _factory(*args, **kwargs):
final_style = ChainMap(kwargs, style)
return cmd(*args, **final_style)
return _factory
brb = styled_control(cmds.button, big_red)
brb(label = 'a big red button')
brb(label = 'another big red button')
brb(label = 'super big red button', width = 300) # overrides the style's flag
I find this a very handy way to take all off the fiddly little flags out of actual GUI calls and put them in a place where it’s easy to make adjustments.