Using QT Designer and PySide to create Maya 2014 Ed

Posted on November 26, 2014

 by 

brechtos

As it turns out trying to implement a custom GUI made with an external editor and using Python to interact with them can be quite a pain in Maya 2014.Not because it is a difficult process, but because there is very little information on how to do it to be found. And if you do find information, there are either missing steps in the process or require a certain amount of prior knowledge. So here is a short overview on how to get a custom UI made with QT designer working in Maya 2014.

Some additional info

Most of the tutorials you find online will try to explain how to implement PyQt for Maya 2014 and tell you it is a requirement to be able to implement GUI’s made with QT Designer. There is also an official autodesk explanation on how to do this:Autodesk PyQt tutorial

For most people who just want to add some simple and clean layouts to their scripts this will be the first big hurdle and often be the point where they just give up.You need to download a couple of files, place them in specific locations and then run those scripts. All nice and simple but this is a very annoying and painful configuration where many things often can go wrong. Not only that but you also need a copy of Visual Studio to be able to run these scripts in order to run and compile the plugins.Instead of all of this trouble we will use PySide instead of PyQt as it comes with Maya 2014 and will not require all of that hassle.There will be some syntax difference between the two. But some a quick Google search should often help you adjust for example a tutorial script from PyQt to the equivalent PySide code .

Getting your UI into Maya 2014

Creating a GUI

I am not going to go over this step as this is a rather straight forward part of the whole process. Maya 2014 allready comes with a version of QT designer and can be found under the QT folder of your Maya 2014 install.For more information on how to use QT Designer you can have a look at the official manual: http://qt-project.org/doc/qt-4.8/designer-manual.html

Here is an image of the UI used for the scripts in this tutorial.

When saving this to a .ui file it gives the following result:

 Dialog
 
  
   
    0
    0
    385
    478
   
  
  
   Dialog
  
  
   
    
     30
     240
     341
     32
    
   
   
    Qt::Horizontal
   
   
    QDialogButtonBox::Cancel|QDialogButtonBox::Ok
   
  
  
   
    
     10
     10
     361
     31
    
   
   
    PushButton
   
  
 
 
 
  
   buttonBox
   accepted()
   Dialog
   accept()
   
    
     248
     254
    
    
     157
     274
    
   
  
  
   buttonBox
   rejected()
   Dialog
   reject()
   
    
     316
     260
    
    
     286
     274
    
   
  
 

 

Converting the .ui file to a usable .py file

As you can see is the .ui file nothing more than a xml file describing the different elements of your UI. To be able to use this information inside of Maya we will need to convert this file to a Python script.To make life easier you can place your .ui file in your Maya script folder. The default location for this is:

“C:\Users\Username\Documents\maya\scripts\”

So in our case the complete file path would be:

“C:\Users\Username\Documents\maya\scripts\makeCube.ui”

This will allow Maya to automatically find your script file once converted.If you are planning on making multiple editor scripts using multiple GUI files it can be interesting to set them up as module packages, keeping your project clean and organised. You can find an excellent explanation on how to do this at http://www.chadvernon.com/

Here is a small excerpt from that site explaining the core of setting this up.

“To create a package, create a folder in one of you PYTHONPATH directories like your Maya script directory, then create a file called __init__.py inside of that new folder. The __init__.py can be empty. You can then place your modules into that package and import them as follows.

import packageName.moduleName

You can have packages inside of packages.

import cvtools.rigging.createIkLeg as createIkLeg
createIkLeg('L_leg_joint')

Any code you put in the __init__.py file of a package gets executed with the package. For example, in the above sample package hierarchy, I could have code in scripts/cvtools/__init__.py to create a Maya menu when the package is imported.

import cvtools     # creates a Maya menu

 

But for this example we just place the files in our maya scripts folder. The actual conversion can be done by running the following script inside of the Maya script editor (source: Autodesk reference

) :

import sys, pprint
from pysideuic import compileUi
pyfile = open("[path to output python file]\makeCube.py", 'w')
compileUi("[path to input ui file]\makeCube.ui", pyfile, False, 4,False)
pyfile.close()

In our case we converted the makeCube.ui file to a makeCube.py file. Giving us the following piece of code. Note how you can see all the elements that were part of our UI neatly defined.

 # -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'C:\Users\Username\Documents\maya\scripts\makeCube.ui'
#
# Created: Tue Nov 25 13:01:27 2014
#      by: pyside-uic 0.2.14 running on PySide 1.1.1
#
# WARNING! All changes made in this file will be lost!

from PySide import QtCore, QtGui

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(385, 478)
        self.buttonBox = QtGui.QDialogButtonBox(Dialog)
        self.buttonBox.setGeometry(QtCore.QRect(30, 240, 341, 32))
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandarons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.pushButton = QtGui.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(10, 10, 361, 31))
        self.pushButton.setObjectName("pushButton")

        self.retranslateUi(Dialog)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), Dialog.accept)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton.setText(QtGui.QApplication.translate("Dialog", "PushButton", None, QtGui.QApplication.UnicodeUTF8))

Using the custom GUI from within a PySide Script

Almost there!Now we just need to be able to use our GUI from within a PySide Script as follows:

from PySide import QtCore, QtGui
import makeCube as customUI
from shiboken import wrapInstance
import maya.OpenMayaUI as omui

def maya_main_window():
    main_window_ptr = omui.MQtUtil.mainWindow()
    return wrapInstance(long(main_window_ptr), QtGui.QWidget)

class ControlMainWindow(QtGui.QDialog):

    def __init__(self, parent=None):

        super(ControlMainWindow, self).__init__(parent)
        self.setWindowFlags(QtCore.Qt.Tool)
        self.ui =  customUI.Ui_Dialog()
        self.ui.setupUi(self)

        self.ui.pushButton.clicked.connect(self.someFunc)

    def someFunc(self):
        print 'Hello {0} !'

myWin = ControlMainWindow(parent=maya_main_window())
myWin.show()

Some points of interest

How do we access the UI script?

import makeCube as customUI

This tells us where we can find our UI script. Using customUI we can then access the different UI elements.If you used the Module setup that I mentioned earlier you will need to use the correct namespace importing if applicable. For example:

import UItestScripts.makeCube as customUI

How do we assign the UI class?

self.ui =  customUI.Ui_Dialog()

Using the customUI alias we can access the class that was defined in the makeCube file. To know what class you should use just have a look at the converted .ui file. In this case:

from PySide import QtCore, QtGui

class Ui_Dialog(object):

Initializing the UI

 self.ui.setupUi(self)

After setting up what ui we will be using we call the setupUI function.Notice how this function was also present in the converted .ui script.

How do we use our UI elements?

self.ui.pushButton.clicked.connect(self.someFunc)

This piece of code will determine what will happen when you the “clicked” event gets called on the button with the name “pushButton”.Bellow that we have defined the function to which we are referring.

def someFunc(self):
        print 'Hoozah a working GUI!'

In this case, whenever someone presses the “pushButton” button the console will print the defined text.

Closing words

I hope that this tutorial will be of use to some people. I am not a Maya user myself and this tutorial is the result of me trying to help a friend to get all of this to work. It took us multiple hours and different attempts to find a fully working solution. Going over multiple tutorials and solutions, each either with errors, legacy code, crucial parts missing, no explanation on how to perform certain steps or what you are actually doing.So therefore this complete step by step overview of how we got a QT designer GUI to work inside of Autodesk’s Maya 2014 using PySide.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值