One of the things that always annoyed me was making UIs for Maya - writing the UI line-by-line in MEL or Python was agonizing, and heaven forbid you need to change the layout later, it just wasn't fun or exciting.
Then I was introduced to QT Designer, which is an amazing tool for making UIs which comes with PyQt when you install it. But still the problem remained - the conventional wisdom appeared to be converting that .ui file into python and working from there. Any time the UI required an update, I had to reconvert the .ui file into python code and replace entire chunks within my python file. While this did make it easier to create and modify the user interface, it still wasn't fun to modify the UI and replace giant blocks of code between files.
Finally, after plenty of trial and error, digging through countless Google results, and piecing things together I had what I desired: a proper implementation of .ui files within Maya 2016. The resulting setup involves two files: a main .py script file that is run within Maya, and the .ui file which is read by the python file.
Part 1: Getting a .ui file from QT Designer to Maya
After making a simple UI window in QT Designer, which comes with PyQT, I wrote a basic python class file to load and show this UI inside of Maya.
1) The first part of the file contains:
Within this first part of the code, the major parts that relate to the UI are:
PySide - An implementation of QT available within Maya 2016 by default.
shiboken - Used to create a python reference to Maya's UI, lets us parent our UI to Maya.
maya.OpenMayaUI - Used by shiboken to get Maya's main window..
The remainder of the header is to store the script location for relative pathing and other standard libraries used elsewhere.
2) The next portion is a function to load a .ui file:
This function loads and returns the UI within the .ui file, the code of which is from a stackOverflow response by BarryPye. The arguments of this function includes the .ui file's path, and what we want to attach this .ui file to.
3) This class below is the bare minimum UI object class:
We can call this class inside of Maya, and it will open our UI. Within the __init__ function, we make references to:
mainUI- the .ui's location, which should be within a subfolder named /templateUI/ placed in the same folder as the .py file.
MayaMain- a reference to the Maya window, so that we may parent our UI to the Maya application.
self.MainWindowUI - a class variable that stores the reference to the UI window and its contents. We go through this to connect any buttons or any text.
While the class is now capable of running in Maya, it is a bit deceitful in that you actually can't fully close the window. If you hit the 'x' in the top right of the window in an attempt to close it, it will simply hide the window, destroying none of its contents.
4) In order to properly close the window, we must make some additions and changes:
With this new setup, we are now setting QtGui.QMainWindow as the parent class of our UI object. This expands the functionality of our UI, letting us properly delete it when closed ( line 11 ). Also, while not necessarily required, we can call a specific function to run when we do close our UI ( line 12 ).
With these changes, the UI can now be opened and closed properly within Maya, the last real aspect is my personal preference to prevent opening multiple windows, a wrapper function to call the class:
5) Wrapper function to call the UI:
If I call this function instead of the class object itself, I can prevent multiple instances of this UI from being open in Maya. The only prerequisite for this function is knowing the objectName of the top-most object within my .ui file. In order to find the objectname, within QT Designer I look for the top-most object's name in the Object Inspector. This will be the window's name inside of Maya - in my case it's demoUI.
Wrapping up the basic concept!
With a .ui file made in QT Designer, it is very possible and relatively easy to open this .ui file within Maya, removing the need to convert the .ui file into python, or writing the UI by hand in MEL or Python. The python file is also relatively small all things considered, we really just need a proper function to parse the .ui file and a proper class structure to open and close the .ui file correctly. The following posts on the subject discuss expanding the functionality.
Demo Files ( .zip )
To use the demo files:
1 ) Close Maya if it's open
2) Extract the contents of this.zip into your maya/scripts/ folder
3) Open Maya
4) in Maya, create a python shelf script with the following code:
Press the shelf icon and it should open up!