Python Tools - Session 11B

Qt Designer Integration - Shapes Tool

March 26, 2020

Session Navigation

Overview

This session introduces Qt Designer as a visual UI builder for Maya tools. Instead of building interfaces entirely in code, Qt Designer lets you visually lay out widgets and save them as .ui files. The Python script then loads the .ui file at runtime using PySide2's QUiLoader. This is Part 1 of the Qt Designer workflow - the .ui file contains a simple form with a "Create Shape" button.

Key Concepts

  • Qt Designer for visual UI creation - designing interfaces visually instead of writing layout code
  • Loading .ui files with PySide2 and QUiLoader - using QtUiTools.QUiLoader() to load designer files at runtime
  • QDialog as a base class for tool windows - inheriting from QtWidgets.QDialog for custom tools
  • shiboken2 wrapInstance for Maya window parenting - connecting Qt widgets to Maya's main window
  • Separating UI layout (.ui) from logic (.py) - keeping visual design and code separate
  • Getting the script directory with os.path for relative file paths - using os.path.abspath(__file__) to locate companion files
Qt Designer UI File

This session uses a companion shapes.ui file created in Qt Designer. The .ui file defines a simple form (426×199 px) with a single QPushButton named btnCreateShape with the label "Create Shape". In practice, you would create this file visually in Qt Designer and save it alongside your Python script.

Code

The shapes tool script (shapes.py):

"""
#############################################################################
filename    shapes.py
author      Matt Osbond 
dP email    m.osbond@digipen.edu
course      CS115
Brief Description:
    Session 11B - Thursday Mar 26th
    Part 1 of building our first UI in Qt Designer
#############################################################################
"""

import pymel.core as pm
import os

from PySide2 import QtCore
from PySide2 import QtWidgets
from PySide2 import QtUiTools

from shiboken2 import wrapInstance

import maya.OpenMayaUI as omui

def get_maya_window():
    """Return the main Maya window
    """
    main_window_ptr = omui.MQtUtil.mainWindow()
    return wrapInstance(long(main_window_ptr), QtWidgets.QWidget)

def get_script_dir():
    """Returns the directory where the current script lives
    """
    script_file = os.path.abspath(__file__)
    return os.path.dirname(script_file)

class ShapesUI(QtWidgets.QDialog):

    def __init__(self, parent=get_maya_window()):
        # Run the initialization on the inherited QDialog class
        super(ShapesUI, self).__init__(parent)

        # Set the window title
        self.setWindowTitle('Shape Creator')

        # Assemble the file path for the ui file
        ui_file_path = os.path.join(get_script_dir(), 'shapes.ui')

        # Creat a QFile object form the file path
        qfile_object = QtCore.QFile(ui_file_path)

        # Open the QFile object
        qfile_object.open(QtCore.QFile.ReadOnly)

        # Create a QUI Loader
        loader = QtUiTools.QUiLoader()

        # Load the file as save it to a property
        self.ui = loader.load(qfile_object, parentWidget=self)

        # Close the file handle
        qfile_object.close()

        # Show the UI
        self.show()

ShapesUI()
← Prev Next ->