Skip to content

Instantly share code, notes, and snippets.

@leixingyu
Forked from mottosso/Dock.py
Last active July 16, 2022 15:56
Show Gist options
  • Save leixingyu/83358dedd008f6a51e7f7b2b14d2fb34 to your computer and use it in GitHub Desktop.
Save leixingyu/83358dedd008f6a51e7f7b2b14d2fb34 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.

❗ Worthy Note

During testing, I found that resizing the docked widget to a larger width and then re-launching the widget will prevent it to go back to the original width (so, the tool can only get wider and wider).

A workaround is to un-dock the tool, then re-launch it and dock it back, now the widget can resize properly

from builtins import int
from shiboken2 import wrapInstance
from maya import cmds, OpenMayaUI as omui
from Qt import QtWidgets, QtCore
from Qt import _loadUi
def Dock(Widget, show=True):
name = Widget.__class__.__name__
label = getattr(Widget, "label", name)
try:
cmds.deleteUI(name)
except RuntimeError:
pass
dockControl = cmds.workspaceControl(
name,
tabToControl=["AttributeEditor", -1],
widthProperty="preferred",
label=label
)
dockPtr = omui.MQtUtil.findControl(dockControl)
dockWidget = wrapInstance(int(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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment