I just wanted a frame for building basic interfaces in Maya, so jumping into PyQt
import pymel.core as pm
from PySide2 import QtWidgets, QtCore
import maya.OpenMayaUI as omui
from shiboken2 import wrapInstance
def maya_main_window():
main_window_ptr = omui.MQtUtil.mainWindow()
return wrapInstance(int(main_window_ptr), QtWidgets.QWidget)
class BasicWindow(QtWidgets.QDialog):
def __init__(self, parent=maya_main_window()):
super(BasicWindow,self).__init__(parent)
self.setWindowTitle("My Basic Window")
self.setMinimumWidth(200)
self.setWindowFlags(self.windowFlags() ^ QtCore.Qt.WindowContextHelpButtonHint)
self.create_widgets()
self.create_layouts()
self.create_connections()
def create_widgets(self):
#add widgets here later
pass
def create_layouts(self):
#add layout here later
main_layout = QtWidgets.QVBoxLayout(self)
def create_connections(self):
#connect signals and slots here
pass
def show():
ui=BasicWindow()
ui.show()
show()
Breakdown:
Import the necessary modules
import pymel.core as pm
This line gives us access to Maya’s functionality
Python module that gives an object oriented programming approach to Maya’s MEL language
from PySide2 import QtWidgets.QtCore
This line creates our GUI system and handles the elements
The Qt Framework is a comprehensive set of C++ library classes
PySide2 is Qt for Python
QtWidgets contains classes for creating classic desktop-style UIs
QtCore provides non-UI functionality, like signal and slot mechanisms, property systems, ect
import maya.OpenMayaUI as omui
This gives us a reference to maya’s main window
OpenMaya is Maya’s API, and openMayaUI provides access to Maya’s UI system
from shiboken2 import wrapInstance
This is used to wrap Maya’s main window pointer into a PySide2 widget object
Shiboken2 is a binding generator tool used by PySide2
WrapInstance is used to convert C++ pointers to Python objects
Define maya_main_window() function to create a parent for our dialog
This creates an interface which is parented to Maya’s UI interface, ensuring that it is part of the program and abides by its rule set.
As it will be part of the interface, maya will handle things for us like object stacking, keyboard focus and input events are handled properly, lifecycle dialog (it will close when maya closes)
It is also using a wrap instance, to convert this pointer to a PySide2 Widget, giving us that library of UI functionality
Creates a BasicWindow class that inherits from QtWidgets.QDialog
Because BasicWindowe is inheriting from QtWidgets.QDiagog, it has the Qt C++ library functionality
Qt comes with built in functionality like standard button layouts and default closing behaviors
Our __init__(parent) window links us to Maya’s main window
Defines basic window properties
Basic things like title name and width
Defines placeholder methods for creating widgets, layouts and connections
create_widgets():
Individual UI elements that are interactive, such as buttons, text fields, drop down menus, checkboxes, sliders, ect
Examples UI elements you can use
QPushButton
QLineEdit
QComboBox
QCheckBox
QSlider
create_layouts():
Manage the layout and organizaton of widgets (how are they positioned, how do they resize, ect)
Common layouts are things like horizontal, vertial, grid and form
Example Layouts:
QVBoxLayout
QHBoxLayout
QGridLayout
QFormLayout
create_connections()
Connections take user interactions with your widgets and link them to code behavior
This is where you setup signal slot connections, which is how Qt handles events
Like in other programming environments, a signal is what is sent out when a UI event is triggered (like a button click) and and slots are the functions which respond to those events
This is where you would connect widget signals to slots
Provides a “show()” function to add and display the window
Here is a practical application of that script, which overrides the selected NURBS shape’s color override with a set color (the words in bold are what we added to modify the last script for our purposes):
import pymel.core as pm
from PySide2 import QtWidgets, QtCore
import maya.OpenMayaUI as omui
from shiboken2 import wrapInstance
def maya_main_window():
main_window_ptr = omui.MQtUtil.mainWindow()
return wrapInstance(int(main_window_ptr), QtWidgets.QWidget)
class CurveColorUI(QtWidgets.QDialog):
def __init__(self, parent=maya_main_window()):
super(CurveColorUI,self).__init__(parent)
self.setWindowTitle("Set Curve Color")
self.setMinimumWidth(200)
self.setWindowFlags(self.windowFlags() ^ QtCore.Qt.WindowContextHelpButtonHint)
#replace the "self.setWindowFlags" with the below code in italixBold to get rid of the help toggle (it is not setup to do anything)
#flags = self.windowFlags()
#flags &= ~QtCore.Qt.WindowContextHelpButtonHint
#self.setWindowFlags(flags)
self.create_widgets()
self.create_layouts()
self.create_connections()
def create_widgets(self):
self.color_combo = QtWidgets.QComboBox()
self.color_combo.addItems
(["Red","Green","Blue","Yellow","Cyan","Magenta"])
self.apply_btn = QtWidgets.QPushButton("Apply")
def create_layouts(self):
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.addWidget(self.color_combo)
main_layout.addWidget(self.apply_btn)
def create_connections(self):
self.apply_btn.clicked.connect(self.apply_color)
def apply_color(self):
color_name = self.color_combo.currentText()
color_index = {"Red":13, "Green":14, "Blue":15, "Yellow":17, "Cyan":18, "Magenta":20}[color_name]
selected_curves = pm.ls(selection = True, type = 'transform')
for curve in selected_curves:
shapes = curve.getShapes()
for shape in shapes:
if isinstance(shape, pm.nodetypes.NurbsCurve):
shape.overrideEnabled.set(1)
shape.overrideRGBColors.set(0)
shape.overrideColor.set(color_index)
pm.select(selected_curves) #reselect the curves
def show():
ui=CurveColorUI()
ui.show()
show()