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.QDialogfor 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()