Python Maya Setup

From wikinotes



Version reference/Install

Maya2015 Python 2.7.3 https://www.python.org/ftp/python/2.7.3/Python-2.7.3.tgz

Installing specific versions of Python in Unix/Windows is fairly trivial. In cygwin to get a specific version you'll need to compile it yourself which has some dependencies:

### Install:
## libffi-devel, pkg-config

cd /home/src																							## Download/Extract Python Version
curl -#O https://www.python.org/ftp/python/2.7.3/Python-2.7.3.tgz
tar -xvf Python-2.7.3.tgz

curl -#O http://www.tux.org/~mayer/cygwin/python/Python-2.7.3-cygwin.patch.bz2	## Download/Extract CygwinPatch
bzcat Python-2.7.3-cygwin.patch.bz2 | patch -p0


### If pkg-config doesn't detect libffi (if you get a KeyError: 'x86_WIN64'), you can
### create symbolic links so that the compile is possible.
ln -s /usr/lib/libffi-3.0.13/include/* /usr/include


cd /home/src/Python*																					## Compile
./configure --prefix=/usr/local  --with-system-ffi
make



maya.standalone in external interpreter

Conditions that must be met
PYTHONPATH
PYTHONPATH+=C:\Program Files\Autodesk\Maya2015\Python\Lib\site-packages
Maya's site-packages must be appended to pythonpath
MAYA_LOCATION
MAYA_LOCATION=C:\Program Files\Autodesk\Maya2015
Point to maya install
LD_LIBRARY_PATH
LD_LIBRARY_PATH=C:\Program Files\Autodesk\Maya2015\lib
Point to maya's lib folder
import struct; print struct.calcsize("P") * 8 
Arch: (32bit/64bit) must match maya/interpreter
import sys; sys.version_info()
External Python Interpreter's version should match Maya's (UNCONFIRMED, BUT PREFERRED)
## Provided that the above conditions are met, the following should just work
## After which you can run commands through maya.
import maya.standalone 
maya.standalone.initialize( name='python' )
http://knowledge.autodesk.com/support/maya/learn-explore/caas/CloudHelp/cloudhelp/2015/ENU/Maya/files/Python-Python-from-an-external-interpreter-htm.html



PySide

Demonstrate Differences

There are 3 main differences between writing a QT gui for within maya, and for outside. I made a module to allow the creation of new independent windows wpyside.newUI.py that will run both within and outside of maya. For the sake of documentation, here are the differences:

  1. Maya already has a QApplication, so it does not need to be created
  2. Maya doesn't recognize QtGui.QWidget() as a window. use QtGui.QDialog() instead.
  3. Outside of maya, you need to close the python session when the script is done. In maya, it needs to stay open.
#### Pyside in Maya
##
from PySide import QtGui, QtCore
win = QtGui.QWidget()
win.setGeometry( 300, 300, 250, 150 )
win.setWindowTitle( 'Simple Window')	
win.show()




#### Pyside in Terminal
##
from PySide import QtGui, QtCore
try:                   app = QtGui.QApplication('abc')				## 1) Create QApplication if doesn't already exist
except RuntimeError:   app = QtCore.QCoreApplication.instance()

win = QtGui.Qdialog()															## 2) Maya Doesn't Recognize QWidget() as a window,
win.setGeometry( 300, 300, 250, 150 )										 #    use QDialog instead (windowTitle etc all compatible for both)
win.setWindowTitle( 'Simple Window')
win.show()

sys.exit( app.exec_() )															## 3) Exit Process when finished

Getting Maya Root GUI Object

Python does it's own garbage collection. To ensure that a window is not deleted (arbitrarily), you need to parent your windows to maya's root window object. The section below is incomplete. Nathan Horne suggests using sip.wrapInstance rather than shiboken.wrapInstance. I haven't had any problems yet, so I'm sticking with Shiboken.

from PySide import QtCore, QtGui					## Usual PySide Imports
from shiboken import wrapInstance				## Creates a Python wrapper for a C++ object instantiated at a given memory address - the returned object type will be the same given by the user.
import maya.OpenMayaUI as apiUI					## Where we are getting main UI object from
import sys


def getMayaWindow():
    """
    Get the main Maya window as a QtGui.QMainWindow instance
    @return: QtGui.QMainWindow instance of the top level Maya windows
    """
    ptr = apiUI.MQtUtil.mainWindow()
    if ptr is not None:
        return wrapInstance(long(ptr), QtGui.QMainWindow)

 
## Window A
win = QtGui.QWidget( parent=getMayaWindow() )
win.setGeometry( 300, 300, 250, 150 )
win.setWindowTitle( 'Simple Window')
win.show()

## Window B
btn = QtGui.QPushButton( 'testbutton', parent=getMayawindow() )
btn.show()
https://gist.github.com/petfactory/5403877


'Borrowing' Maya's CSS PySide stylesheet

The Default CSS settings vary A LOT from platform to platform, for a consistent look inside/outside of maya you may want to extract the stylesheet settings from maya's QApplication. (someone on the internet already did most of the work!)

from PySide import QtGui
groups = ['Disabled', 'Active', 'Inactive', 'Normal']
roles = ['Window',
        'Background',
        'WindowText',
        'Foreground',
        'Base',
        'AlternateBase',
        'ToolTipBase',
        'ToolTipText',
        'Text',
        'Button',
        'ButtonText',
         'BrightText']


def getPaletteInfo():
    palette = QtGui.QApplication.palette()
    #build a dict with all the colors
    result = {}   
    for role in roles:
        for group in groups:
            qGrp = getattr(QtGui.QPalette, group)
            qRl = getattr(QtGui.QPalette, role)
            result['%s:%s' % (role, group)] =  palette.color(qGrp, qRl).rgba()
    return result
       
def setPaletteFromDct(dct):
    palette = QtGui.QPalette()
    for role in roles:
        for group in groups:
            color = QtGui.QColor(dct['%s:%s' % (role, group)])
            qGrp = getattr(QtGui.QPalette, group)
            qRl = getattr(QtGui.QPalette, role)
            palette.setColor(qGrp, qRl, color)
    QtGui.QApplication.setPalette(palette)