Joe Hultgren - Technical Artist
  • Blog
  • Demo reel
  • About Me
  • Maya Scripts (bitbucket)

Mixing Maya UI elements into a Qt Designer interface

10/25/2013

0 Comments

 
Joint Orient UI using qt designer and maya elements
One of the nice things in Maya is being able to make interfaces for tool using Qt and Qt Designer. Unfortunately not everything in Qt has a corresponding UI element in maya, even for some things that you think there would be. One most glaring omissions is that a Qt float spinbox doesn't get mapped to a maya float field.

While recreating the Comet Joint Orient tool over to python I ran into this issue while trying to replicate the world up and tweak vector fields. If you just want to get the value from a float spinbox you can by routing its information into something maya does know how to talk to, usually a line edit, using Qt signals/slots mechanism. However the comet version of the tool has buttons that set the field to a given preset vector and I couldn't get away with only reading the values. The obvious solution to that is to try creating float fields in maya and add them to the Qt interface.

In order to add new elements to the interface we need to know which layout to we want to put things in. For this tool we have two layers of nested layouts in Qt Designer, horizontal layouts for each row of elements and a vertical layout that hold all the horizontal layouts. If we take the Show Axis button for example and ask it what layout its in we would expect something like JointOrient|verticalLayout|horizontalLayout1. Lets see what we get.

 win_name = pm.loadUI(uiFile='path/to/ui/file')
# get buttons in interface
buttons = [x for x in pm.lsUI(type='button') if win_name in x]
print next(x for x in buttons if 'show_axis' in x).getParent()
# Result
JointOrient|verticalLayout
Wait a minute were is our horizontal layout? So it turns out when you have nested layouts maya decides to only see the parent layout. This obviously causes us a problem when we are trying to find a specific layout, so what do we do. 

The answer to this problem is to organize our interface using widgets instead of layouts, at least in the places where we want to add things after loading the ui file. Once we have a widget we can set it to have a horizontal layout for the things we add.
PictureInterface as seen in Qt Designer
Now with our widget layout lets try the same thing that we did with the show axis button. Make a button inside the widget to look for. We are expecting something like JointOrient|verticalLayout|widget.

 win_name = pm.loadUI(uiFile='path/to/ui/file')
# get buttons in interface
buttons = [x for x in pm.lsUI(type='button') if win_name in x]
print next(x for x in buttons if 'world_placeholder' in x).getParent()
# Result
JointOrient|verticalLayout|horizontalLayout_5
Alright so now we have a horizontalLayout but why didn't our widget show up in the path?  Whats going on is that maya doesn't see the widget, but since it sees the top layout in a widget we can still get what we want. Since we have a reference to the layout from our place holder button we can just delete the button and use the reference as the parent for the new elements we add.
 win_name = pm.loadUI(uiFile='path/to/ui/file')
# get buttons in interface
buttons = [x for x in pm.lsUI(type='button') if win_name in x]

# get location for where world vector goes and get rid of placeholder
world_placeholder = next(x for x in buttons if 'world_placeholder' in x)
world = world_placeholder.getParent()
pm.deleteUI(world_placeholder)

# make floatFields and buttons using normal ui commands
pm.text(label='World Up Dir:', p=world)
world_x = pm.floatField(v=1.0, p=world, pre=2)
world_y = pm.floatField(v=0.0, p=world, pre=2)
world_z = pm.floatField(v=0.0, p=world, pre=2)
pm.button(label='X', p=world, c=set_world_x)
pm.button(label='Y', p=world, c=set_world_y)
pm.button(label='Z', p=world, c=set_world_z)
If you want the finished version of this script you can find it here: https://bitbucket.org/jhultgre/maya-scripts/src/b2b5a7c61c7c56a4ed02624e75c2efb5538e8ad0/tools/jointOrient.py?at=default

The ui file can be found here: https://bitbucket.org/jhultgre/maya-scripts/src/b2b5a7c61c7c56a4ed02624e75c2efb5538e8ad0/ui%20files/jointOrient.ui?at=default

Or go to the maya scripts link in the sidebar for all  of my maya tools.
0 Comments

Tools reel

10/20/2013

0 Comments

 
I've created an updated tools reel that you can watch here or on my demo reel page.

Joe Hultgren Maya Tools Reel from Joe Hultgren on Vimeo.

0 Comments

    Archives

    September 2017
    February 2017
    April 2016
    October 2013
    September 2013
    August 2013
    March 2012
    February 2012
    August 2011
    July 2011
    May 2011
    April 2011
    February 2011
    October 2010
    August 2010
    July 2010
    June 2010
    April 2010
    January 2010
    October 2009
    July 2009
    June 2009

    Categories

    All
    Art
    Blender
    Code
    Flash
    Free
    Maya
    Personal
    Pymel
    Python
    Rig
    School
    Siggraph
    Vancouver
    Vfs
    Website
    Work

    RSS Feed

    View my profile on LinkedIn
Powered by Create your own unique website with customizable templates.