UI in maya using python
Sunday, November 29th, 2009UI is super important. At least if you’re developing tools for anyone other than yourself. And even then, its still a good idea to try and make your tools accessible because sometimes you don’t come back to a tool for months, or occasionally years. And for the record, I’m not even nearly as good as I would like to be (or even should be) at building usable UIs.
Unfortunately maya is fighting you all the way in this regard. Maya is, and lets not be too harsh here, is a piece of steaming turd when it comes to UI – it was great 10 years ago, but it hasn’t changed since… The UI that you can build in mel/python is painfully limiting to use for anything but a bunch of buttons and checkboxes. But unfortunately you have to either live with that, or go through the pain of learning and integrating qtpython/wxpython into your tools – but thats a different (and entirely valid) discussion.
Writing UI using mel is horrible – and pretty well understood because mel is so simplistic and straight forward. Its horrible because its essentially impossible to write UI without hardcoding widget names which makes it impossible to modularize your UI into re-usable chunks, its difficult to store local data on a piece of UI.
But writing maya UI using python is a different story. Python provides you with the ability to abstract the UI code so you can make it more modular, provide widgets and collections of widgets with their own local storage and methods etc. By writing thin wrappers around the existing maya widgets you can “class-ify” them and make them work more like code should in an object oriented language.
Now, I’m pretty new to all this as well, so I’m certainly not claiming anything I say here is the best way to do things. But these ideas have made my life easier and more productive, and more importantly its increased the functionality in the tools I’ve created.
Anyway the wrapper code I work from is here.
As you can see its not terribly complicated – in fact its painfully simple. As you can see the UI classes inherit from the python built-in type “str” – they’re strings. This is because everything in maya is a string, so by inheriting from str, we can pass the actual UI python objects to the maya commands which makes mixing and matching this sort of UI code with older UI code a snap. But because we’re now working with actual objects, we now have local storage for the widget (whether it be a simple button, or a more complicated layout of widgets) plus we can write methods for these widgets. So by doing things this way for example, you can write a “setVisibilty” method on the base class if you wanted to, and now every object has the same interface to hiding and unhiding itself. So we now have local storage and polymorphism.
By using this sort of paradigm you can also extend classes for more complex UI. As you can see here, this makes writing modular UI alot easier as well. This is a great example of some UI that is just not possible to write in mel in a way that makes it this modular. At least not where you can have multiple instances of the UI open at once.
So the mappingEditor example above – it is a generic widget that inherits from the formLayout class (so it knows how to lay itself out) but it adds a heap of other functionality related to mapping two lists to one another. I’ve used this widget in a few tools now (only one of them public) – often many instances of them are on screen at once. This just isn’t possible using mel.




