PyQT in Houdini & Maya. (Basic Program) / by Bilal Malik

(This is the method I used when making my first applications work within Houdini/Maya, it may or may not be the ideal way but it works for me. (hopefully for you too.))

This guide assumes you can use Python somewhat already (aka you understand some coding concepts).

While using code to plan out your User Interface can be more enticing for some, it can be a hassle when starting out or if you just want to get a good interface without the trouble of writing it all manually. However the Qt framework can offer more features within it that you might not get from vanilla python that comes installed.


Getting Started with Qt.

First of all, you need to have access to the Qt module. As Houdini and Maya both use a separate version of python within its own environment, you need to point the Qt module to the system path to allow it access to be used. Link (https://github.com/mottosso/Qt.py). The installed modules must be compatible with python 2 as Houdini and Maya as of writing this ship with python 2 and not python 3. I should point out I am Using Windows 10 as platform of choice but with minor changes to paths, the code should be the same.

To create a GUI for the user to interact with you can use Qt Designer to create a XML file which you can read from within the hosting application (Houdini/Maya). You may also convert the ‘*.ui’ to a python module to be used later on.

Qt Designer

First of all you can get Qt Suite from the official site (https://www.qt.io/download). This is a key step :).

When Inside designer it is a drag and drop task to create the UI your project requires. For this posts purpose we’ll be using a simple form with a button and a label. (This is similar to a .NET framework application if you have ever used Visual Studio forms (VB.net and C#))

First Drag the ‘pushbutton‘ onto the form from the toolbar left of the screen followed by the ‘label‘. You can edit the bounds of the objects you’ve placed to fit your aesthetic. After this please make sure you change the name of the object so you can recognise what that object is placed for.

QT Designer with the window we should’ve made.

QT Designer with the window we should’ve made.

Now after that is done we can export the UI to a file on Disk we can use within our chosen platform.

To Export go-to the top menu bar in QT and click (File->Save As… )and save the file somewhere accessible to you and python that will read it later on (I would recommend creating a folder for the project you are working on to place in).

The File should be exported with the extension (.ui) , this is an XML file that is somewhat human readable with a test editor/viewer. This file can be re-opened in QT Designer to be modified at a later date.


Houdini

When opening Houdini you have two options;

  • Create a Shelf tool

  • Create a Python Panel

What I like to do it use the Python panel to create a working version of the application and move it to work as a shelf tool.

To create a shelf tool go to the top menu bar in Houdini and click ‘Window’ and choose the python panel option. A secondary way is show below. (My preferred way xP)

Houdini 17.5, Creating a Python panel from Tabs. (Animated GIF)

Houdini 17.5, Creating a Python panel from Tabs. (Animated GIF)

After this you can start to code. Now I find it difficult to code inside the editor in Houdini so I use Sublime to write the code and then transfer it back, There is a way to use an external editor but I prefer this way as its cleaner and safer for me. The only downside is that sometimes you can get random additional tabs when copying and pasting code which you can fix in a more advanced text editor like Sublime which is what I use as it has more rich interface to show code.


Maya

In Maya you can use the script editor to write code your program. You can also use the shelf tool shown and it is recommended you create a shelf tool from the code you write from this guide.

To open the script editor go-to the top Maya menu and click in the following order. Windows-General Editors-Script Editor. Or you can click the little icon at the bottom right of your window to open it depending on what work space you are using. I find Maya has a better editor than Houdini but it has more problems with syntax and ‘ghost tabs’ that can be infuriating. Lucky you can open .py files externally so you can write the whole code out in an other editor.

Open the script editor in Maya (Animated GIF)

Open the script editor in Maya (Animated GIF)


Code

Most of the code can be copied for both Maya and Houdini with some subtle changes.

To start we need the modules linked at the top of the page here is a reminder of where to get them ((https://github.com/mottosso/Qt.py)). The contained folder should be extracted to a folder where you can access it via the programs version of Python. Ideally you should make a folder for the project you are working on somewhere like your Houdini folder in documents. (e.g. C:\User\Documents\houdini17.5 or C:\User\Documents\maya) I would recommend creating scripts folder inside this folder to host your projects in unless something forbids you.

IMPORTANT NOTE (HOUDINI ONLY):

While using the Python Panel form you must have a function that creates the UI at the bottom of your code.

#Create Interface
def onCreateInterface():
    my_window = MyWindow()
    my_window.show()
    return my_window

What if my code is designed for a shelf tool? (HOUDINI AND MAYA)

Do not worry, if your tool is a shelf tool, just add the following code instead of the one above. This code tries to close a window if it exists so you dont get two conflicting windows. (You can find the dimensions of your program window by looking at its properties in QT Designer. )

You MUST do this for the program to show in Maya.

    try:
        my_window.close()
    except:
        pass
    my_window = MyWindow()
    #This is optional you can resize the window if youd like.
    my_window.resize(471,577)
    my_window.show()

We can now return to the top of the code to continue.

First of all we need to point the path of the extracted modules to our new-to-be program, we can do this by importing the ‘sys’ and ‘os‘ modules from python. (As a core module it is already installed.)

import sys, os

#Point this Path to the Qt.py-1.2.0.b3 folder.
sys.path.insert(0,("Path to modules folder"))

Now to test this we can hit the apply button under the python panel editor. If this works you should get no white-screen error in your python panel.

If all is well we can start to import the Qt module by appending the following code:

from Qt import QtWidgets, QtGui, QtCompat

Now if we run the code and no error is showing in the panel window you are in luck and now we can focus on creating the class to create our UI. This involves creating a class object with a initialisation function.

class MyWindow(QtWidgets.QMainWindow):

    #Initialization Fucntion.
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)

        #Load in your UI file.
        file_interface = os.path.join("Path to .ui File")
        self.main_widget = QtCompat.loadUi(file_interface)
        self.setCentralWidget(self.main_widget)
        self.setWindowTitle("My Tool")

        #Inherit Houdinis Style Sheet. Only do This if you use Houdini
        stylesheet = hou.qt.styleSheet()
        self.setStyleSheet(stylesheet)

Now at this stage there should be a UI visible in your panel with the two object we added in our form. We can now add our own code to display a message when the button is pushed. (How exiting,:) )

Now I called my button: bttn_main. This will be used to refer to the object inside Houdini.

In the same __init__ function we can append the following code:

#Button Assingment
self.main_widget.bttn_main.clicked.connect(self.setText)

What we are doing here is adding an event on when the button is clicked, it will execute the function we link to it. In this case it is a function called ‘setText’. You can call it whatever you like. We now have to define this function inside the class. so under the def __init__, create a new function with the same name as the one linked inside the assignment. I will call it setText like i mentioned.

Then we can add code to set the label to change to what we want it to say.

    def setText(self,*args):
        self.main_widget.OUT_label.setText('Hello World')

If everything was successful, when hitting apply and then hitting the your button on the panel should result in the message changing to say ‘Hello World’. Now we have completed this basic program and look, its running inside of another one, wonderful.


RAW CODE:

import sys, os
#Point this Path to the Qt.py-1.2.0.b3 folder.
sys.path.insert(0,("Path Here"))
from Qt import QtWidgets, QtGui, QtCompat

class MyWindow(QtWidgets.QMainWindow):
        #Initialization Fucntion.
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
                #Load in your UI file.
        file_interface = os.path.join("Path Here")
        self.main_widget = QtCompat.loadUi(file_interface)
        self.setCentralWidget(self.main_widget)
        self.setWindowTitle("My Tool")
                #Button Assingment
        self.main_widget.bttn_main.clicked.connect(self.setText)
        
    def setText(self,*args):
        self.main_widget.OUT_label.setText('hello World')

#Create Interface
try:
	my_window.close()
except:
	pass
my_window = MyWindow()
my_window.resize(392,639)
my_window.show()

Whats Next?

Now you know how to create a UI inside of Houdini, you can use these valuable guides to help you along different parts of the QT framework. This first site is amazing for getting code snippets and learning about the different things that can be used with QT.

https://www.tutorialspoint.com/pyqt/index.htm

And lastly we have the official Qt documentation site for everything about the framework.

https://doc.qt.io/qtforpython/index.html

Thanks for reading and hope this helped you create your program with Qt.