Skip to content

Instantly share code, notes, and snippets.

@mottosso
Forked from liorbenhorin/Simple_MayaDockingClass.py
Last active October 13, 2023 09:01
Show Gist options
  • Save mottosso/c853b6fd9fb963e6f3e7c7a4f53b649d to your computer and use it in GitHub Desktop.
Save mottosso/c853b6fd9fb963e6f3e7c7a4f53b649d to your computer and use it in GitHub Desktop.
Simple way to dock Qt widgets to Maya 2017+

Wrapper function to dock any QWidget subclass.

Difference

This fork differs from the original in that it doesn't embed your widgets in the layout provided by Maya's panel. Instead, it embeds your widget into the panel, which means it works with existing widgets and widgets that don't fit in a QLayout; like a QML component. It also addresses a few bugs; e.g. no references to non-existent variables (logger) and no unused imports (QtGui).

Usage

class Example(QtWidgets.QWidget):
    label = "My example"

    def __init__(self, parent=None):
        super(Example, self).__init__(parent)
        self.setWindowTitle(self.label)

        layout = QtWidgets.QHBoxLayout(self)
        layout.setContentsMargins(2, 2, 2, 2)

        label = QtWidgets.QLabel("Hello World!")
        layout.addWidget(label)

Regular instantiation of widget is..

example = Example()

To instantiate it in a docked panel..

example = Dock(Example)

The Dock function is re-entrant; it will prevent multiple instances from overlapping each other, by deleting any existing dock of the same __name__. An optional label class-attribute may be added to control the appearence of the dock in the Maya UI.

from maya import cmds, OpenMayaUI as omui
from Qt import QtWidgets, QtCore, QtCompat
def Dock(Widget, width=300, show=True):
"""Dock `Widget` into Maya
Arguments:
Widget (QWidget): Class
show (bool, optional): Whether to show the resulting dock once created
"""
name = Widget.__name__
label = getattr(Widget, "label", name)
try:
cmds.deleteUI(name)
except RuntimeError:
pass
dockControl = cmds.workspaceControl(
name,
tabToControl=["AttributeEditor", -1],
initialWidth=width,
minimumWidth=True,
widthProperty="preferred",
label=label
)
dockPtr = omui.MQtUtil.findControl(dockControl)
dockWidget = QtCompat.wrapInstance(long(dockPtr), QtWidgets.QWidget)
dockWidget.setAttribute(QtCore.Qt.WA_DeleteOnClose)
child = Widget(dockWidget)
dockWidget.layout().addWidget(child)
if show:
cmds.evalDeferred(
lambda *args: cmds.workspaceControl(
dockControl,
edit=True,
restore=True
)
)
return child
@hannesdelbeke
Copy link

hannesdelbeke commented Jan 26, 2023

Notes: depending on your use, Dock.py might need a few changes:

  • in python 3 you need to use int() instead of long()
  • if using PySide2, instead of from Qt.QtCompat import wrapInstance use from shiboken2 import wrapInstance

tested and working in Maya 2022 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment