PyQt Stylesheets, Maya, and Python Oh MY!

Written by mattanimation. Posted in Maya, pyQT, Python, Tutorials, UI

Ok, so you have some tools built and you have a basic understanding of Python and Maya but you want to start customizing things a bit more, maybe the ‘plastique’ style UI just isn’t as cool as it used to be and you want your tools to have a uniform or unique style to them. This is where stylesheets come into play.

No doubt if you have searched Google you have found the post in TAO that Yasin Uludag started where he released his “darkorange” stylesheet. This is a great resource to get started, but I think there are some details still missing on how to get it setup and working so I decided to make a simple tutorial on how to get a basic application started. This tutorial features the following:

  • How to create a simple PyQt application
  • How to create and compile a .qrc file for icons
  • Edit Yasin’s stylesheet to create your own style
  • Have the application set some options to send to mayapy and create a maya file
  • maybe create your own app to compile .qrc files to .py files easier
Part 1

Part 2

QRC Code:

<RCC>
  <qresource>
    <file>images/checkbox.png</file>
    <file alias="down_arrow.png">images/down_arrow.png</file>
    <file>images/handle.png</file>
  </qresource>
</RCC>

Shell Script:

pyrcc4 icons.qrc -o icons.py

Python:
References:

http://nathanhorne.com/?p=451
http://lateral.netmanagers.com.ar/stories/BBS49.html

Rigging Dojo Week 3

Written by mattanimation. Posted in Maya, pyMel, pyQT, Python, Rigging

So during week 3 it came down to finish up the base skinning and figuring out how I was going to tackle the corrective shapes and/or helper joints. My mentor showed me a video of some tools he uses that I found to be very useful so did my best to re-create them. While doing so I came up with these two tools.

Tools

  • Skin Weight Slider – I really just wanted to get out the idea that was in my head. I have seen nudge tools in the past, but as I was working I visualized a graph with colors to represent the weight values, and sliders to control them, the sliders would update as other influences changed. In a way it is just more simplified and interactive component editor. Still needs some tweaking to make the calls to get the weights smoother. It also has a button to show the influenced verts of the selected joint.
  • UV Pose Driver  – This one is like a simplified PSD tool. It creates a shape on a joint that reads the point on surface where the joint above is in relation to, by keeping a 0-1 value the info from the uv co-ords can be used to drive a corrective shape. Still updating this one as I go as well. The way the tool works is:
    • Select a blend shape from list (updates blend target list)
    • Select a blend target
    • Give pose a name
    • Create it, then position it at the angle where you want the values to be driven.
    • rinse and repeat.

 

Black Box Animation Toolset

Written by mattanimation. Posted in Maya, pyQT, Python, Rigging, UI

Well I figured I should just go ahead and start displaying what I have been working on in my secret lab the past little while in the hopes that putting it out there will actually make me finish the thing. Also to post a history of my workflow and some tips about things I have learned on the way. What is this “Black Box” you say? At first it was to be my custom modular rigging tool, and now it has become a mini character animation pipeline so to speak. The idea behind the name is to have a tool that plugs into everything so the modules are built in a way that allows changes to be made to the rig after it is deemed “complete” which never happens which is why a feature like this is important. Some features include:

  • Modular character rigging
  • Template saving and loading
  • custom character GUI layout built in
  • pose library built in
  • other TD tools for common tasks that tie into the rigs

Aside from this I plan to add a facial rigging portion dubbed “Gray Skull” that will allow for a standardized joint based rigging approach for most characters. The final tool I plan to add to this dubbed “Chop Shop” is a modular vehicle/mechanical rigging portion that will be used for..well…vehicles and stuff, it will focus more on dynamics and plugin development.

This is way too much for one to handle! Why are you doing this dummy, it has been done before!? Originally this whole thing was thought up a few years back when buddy of mine and some other friends from school were going to make a short film. I had started a rigging tool and then that dream was abruptly cut short after loosing my job (darn you federal reserve and bailouts that cause layoffs!) so it had to go on hold while I acquired some kind of vocation to support the fam, but enough sob story. I heard more about these ‘modular rigging’ things and found out, hey I need to learn Python since MEL ain’t gonna cut it anymore (although still alive just not useful outside of Maya). Needless to say, the root of this comes from a DVD by Steve Twist that is a doozy for a beginner at Python but I had somewhat of a coding background so it wasn’t too crazy, just time consuming. As of recently I have been slowly coming to the conclusion that the current system in place needs a lot of work although it works for now, much more is to be done. I think I want to convert it to PyMel as I have not yet made that jump, no time better than now right? Basically I want a tool that allows me to be my own little studio if a decent size freelance comes up I can handle it. I’ve even got a Kinect now and plan on adding a mo-cap layer in there somewhere.

So! On to the learning stuff, first stages:

  1. Think About it sit down and figure out what you are trying to accomplish and make goals
  2. Make a features list list all the “wish list” items you can think of, even if you have no idea how to do it
  3. Always Sketch the UI Before Implementation, show it to others before you get started for feedback as well.

Here are my initial sketches part of what it looks like in Maya so far:

One thing to note is all of this is still subject to change. Don’t limit yourself to just one design because it might be more work to redo it. Which brings me to my next point…keep your UI separate from your main code and other modules, this way if there IS a change then it will only affect this one file since the functionality should not be affected by the users interaction with the interface. I think this a good first post, more to come.

Some Qt Tips

Written by mattanimation. Posted in Maya, pyQT, Python

I’ve been jumping back into using Qt recently, this time in Maya and although there are many resources out there to help get started (I will be posting some below) there are a few things I ran into that might help others on the way.

  • Scroll Areas

QtGui.QScrollArea  this is interesting, even if you are in Qt Designer you can’t seem to get a preview of it working. To get this to work you need to first make a widget and a layout, set the layout of that widget to the newly created layout. Now create the QScrollArea and there is a method called “setWidget”, you want to pass the widget you first created into this method. Next you should add the scrollArea to whatever layout it’s going to be sitting in. When you want to add something to the scroll area you need to add it to the layout of the widget you first created. A little strange but makes sense once you do it once or twice, see code below.


# create a scroll area for the modules to load
myLayout = QtGui.QVBoxLayout()
scrollingWidget = QtGui.QWidget()
scrollingWidget.setLayout(myLayout)

myAwesomeScrollArea = QtGui.QScrollArea()
myAwesomeScrollArea.setWidgetResizable(True)
myAwesomeScrollArea.setEnabled(True)
myAwesomeScrollArea.setMaximumSize(375, 300)  # optional

myAwesomeScrollArea.setWidget(scrollingWidget)
scrollParentLayout.addWidget(myAwesomeScrollArea)

# add item to the scroll area
myLayout.addWidget(widgetIWantToAdd)

  • Button Click Methods

Let’s say you wanted to have a method run when you click a QPushButton, you would write something like this:


myBtn = QtGui.QPushButton('Click Me')
myBtn.clicked.connect(someMethod)

def someMethod(self, *args):
    """
    some comments
    """
    print 'something'

That works just fine and I’m happy with that. Now what if I needed to pass some values to a method when that button is clicked? If you try to add them like this:


myBtn = QtGui.QPushButton('Click Me')
myBtn.clicked.connect(someMethod(arg_1, arg_2))

def someMethod(self, knight, phrase, *args):
    """
    some comments
    """
    print 'ni!'

You will get an error! You do not want this guy –>    hanging around your code, believe me. So how to remedy this troublesome citizen? We have 2 options, “partial” and “lambda“. Partial is a module that needs to be imported from functools and it allows you to specify a method call followed by the arguments you wish to pass it all in a single line. It runs as a single function thereby letting the button do it’s thing and you can continue on your merry way. Lambda? what is this lambda you speak of? In a nutshell its a syntax in python that lets you create a function on thy fly, so we can can create a quick single function that just runs our method call with arguments passed inside. Here are your jolly examples.

using partial


from functools import partial

myBtn = QtGui.QPushButton('Click Me')
myBtn.clicked.connect(partial(someMethod, arg_1, arg_2))

def someMethod(self, knight, phrase, *args):
    """
    some comments
    """
    print 'ni!'

using lambda


myBtn = QtGui.QPushButton('Click Me')
myBtn.clicked.connect(lambda : someMethod('brave sir robin', "I don't know that"))

def someMethod(self, knight, phrase, *args):
    """
    some comments
    """
    print 'aaarrrggg!'

Here are some other links to get started using PyQt in Maya:
Kristine Middlemiss

David Coleman

There are more links in older posts as well.

QStringList in Python3.x

Written by mattanimation. Posted in pyQT, Python

I decided to start going through Yasin’s awesome MVC programming tutorials in PyQt(actually doing it instead of just watch) and ran into a little snag when on the first lesson. I entered in all the same code but in the IDE I was using got an error that said:
'module' object has no attribute 'QStringList'

So after digging around and searching I found the answer and wanted to share it. I was using python ver 3.1 and according to what I read on stack overflow here , if you are using PyQt4 and python 3 then you don’t need to use QStrings, in fact that aren’t in the library which is what that error means. so if you are getting that same error simply use a python string list like this:

data = ['one', 'two', 'three', 'four', 'five']

and all should be well and dandy.

QT Interfaces in Maya

Written by mattanimation. Posted in Maya, pyQT, Python, UI

There are a many sites that have information about how to setup/create a user interface in Maya using the QT frameworks components, specifically using Qt designer. Here are a couple of links I found especially useful:

http://ivoxelstudios.com/blog/?p=51

Now this one is pretty cool because Chris covers something that I have found to be kind of annoying to with loading a UI which is wanting to be able to grab the controls from the UI.

http://www.chris-g.net/2011/06/24/maya-qt-interfaces-in-a-class/

Another great resource is from John Neumann that covers creating a UI and loading it in Maya and then adding functionality using MEL.

http://www.animateshmanimate.com/2010/07/19/maya-andqt-tutorial/

Here is a video tutorial straight from Autodesk.

http://area.autodesk.com/blogs/stevenr/maya_2011_highlight_qt_user_interface

I just wanted to add to the resource results in google and put the most basic information needed to get started which is, what do I need to do to see my interface after I have created it?

well here is the most basic code I could strip it down to(python version of course):

import maya.cmds as cmds

pathToFile = 'path/to/your/file.ui'
qtWin = cmds.loadUI(uiFile=pathToFile)
cmds.showWindow(qtWin)

Now, if that’s not easy and straight forward I don’t know what is.
But now how do you edit your components? Well, whatever you named the object in QTDesigner will be the name of the object in Maya, just refer to it in string form, for example, if I had a textScrollList in my UI I would type something like the following to add an item to it:

cmds.textScrollList('nameOfMyWidget', e=True, a='smellyFeet')

So as you can see it’s easy to type the names of widgets and edit them, but wouldn’t it be nice to have all of them stored in a dictionary somewhere for easy reference? The link to Chris G’s blog post talks about this is is a must read.

One last thing worth mentioning is the docking ability to the interface, since this IS one of those features that everyone wants at least try one time even if it’s not always necessary. This information is at the end of the autodesk video but it’s nice to just have the code you need on had right, plus google can’t really search the video for code right?

so add this to the code above and comment out the cmds.showWindow part

dockLayout = cmds.paneLayout(configuration='single', parent=qtWin)
cmds.dockControl(allowedArea='all', area='right', floating=True, content=dockLayout, label='Custom Dock')
cmds.control(qtWin, e=True, parent=dockLayout)

and thats it! You can play with some of the args to get the functionality right, like if you set “floating” to false it will start out as docked to the right side of your layout in Maya. Good Luck!