Skip to content

Instantly share code, notes, and snippets.

@liorbenhorin
Created December 1, 2017 15:04
Show Gist options
  • Save liorbenhorin/69da10ec6f22c6d7b92deefdb4a4f475 to your computer and use it in GitHub Desktop.
Save liorbenhorin/69da10ec6f22c6d7b92deefdb4a4f475 to your computer and use it in GitHub Desktop.
Simple way to Docking Qt widgets to Maya 2017+
'''
Template class for docking a Qt widget to maya 2017+.
Author: Lior ben horin
12-1-2017
'''
import weakref
import maya.cmds as cmds
import maya.OpenMayaUI as omui
from shiboken2 import wrapInstance
from Qt import QtGui, QtWidgets, QtCore # https://github.com/mottosso/Qt.py by Marcus Ottosson
def dock_window(dialog_class):
try:
cmds.deleteUI(dialog_class.CONTROL_NAME)
logger.info('removed workspace {}'.format(dialog_class.CONTROL_NAME))
except:
pass
# building the workspace control with maya.cmds
main_control = cmds.workspaceControl(dialog_class.CONTROL_NAME, ttc=["AttributeEditor", -1],iw=300, mw=True, wp='preferred', label = dialog_class.DOCK_LABEL_NAME)
# now lets get a C++ pointer to it using OpenMaya
control_widget = omui.MQtUtil.findControl(dialog_class.CONTROL_NAME)
# conver the C++ pointer to Qt object we can use
control_wrap = wrapInstance(long(control_widget), QtWidgets.QWidget)
# control_wrap is the widget of the docking window and now we can start working with it:
control_wrap.setAttribute(QtCore.Qt.WA_DeleteOnClose)
win = dialog_class(control_wrap)
# after maya is ready we should restore the window since it may not be visible
cmds.evalDeferred(lambda *args: cmds.workspaceControl(main_control, e=True, rs=True))
# will return the class of the dock content.
return win.run()
class MyDockingUI(QtWidgets.QWidget):
instances = list()
CONTROL_NAME = 'my_workspcae_control'
DOCK_LABEL_NAME = 'my workspcae control'
def __init__(self, parent=None):
super(MyDockingUI, self).__init__(parent)
# let's keep track of our docks so we only have one at a time.
MyDockingUI.delete_instances()
self.__class__.instances.append(weakref.proxy(self))
self.window_name = self.CONTROL_NAME
self.ui = parent
self.main_layout = parent.layout()
self.main_layout.setContentsMargins(2, 2, 2, 2)
# here we can start coding our UI
self.my_label = QtWidgets.QLabel('hello world!')
self.main_layout.addWidget(self.my_label)
@staticmethod
def delete_instances():
for ins in MyDockingUI.instances:
logger.info('Delete {}'.format(ins))
try:
ins.setParent(None)
ins.deleteLater()
except:
# ignore the fact that the actual parent has already been deleted by Maya...
pass
MyDockingUI.instances.remove(ins)
del ins
def run(self):
return self
# this is where we call the window
my_dock = dock_window(MyDockingUI)
@LucyDimitri
Copy link

Hi,
Thanks for your script !!
Can you help me modify the code to load a Ui file rather than create the interface directly in this code?
Or maybe I can convert my Ui to Py and load it ?

thank you,

@staticnotdynamic
Copy link

Hi,
Thanks for your script !!
Can you help me modify the code to load a Ui file rather than create the interface directly in this code?
Or maybe I can convert my Ui to Py and load it ?

thank you,

It should be straightforward in python, see loadUi
You could also take a look at the previous version of this script. It loaded and parsed .ui files here

@prsfx
Copy link

prsfx commented Dec 24, 2019

Hi,
Thanks for your script !!
Can you help me modify the code to load a Ui file rather than create the interface directly in this code?
Or maybe I can convert my Ui to Py and load it ?

thank you,

If you want to convert *.ui file. You need to use pyuic in console/terminal.

There's 2 type of python bind as I remembered, PyQt and PySide

Maya used PySide2. So in your folder that contain *.ui file right click and use "cmd here"
or..
Open cmd/terminal change directory to your folder then type some command
or...
You can type cmd in folder direction, press enter then type:

#for PyQt5, use:
pyuic5 -x yourUiFilename.ui -o yourUiFileConvertName.py

#if you want to use PySide2:
pyside2-uic -x yourUiFilename.ui -o yourUiFileConvertName.py

So if there's no error in your command you will see *.py extension file inside your folder.

If you don't want to confused yourself to pure PyQt/PySide ui build and just want to build from existing *.ui file and focus on tool development try this https://github.com/prsfx/MayaDockTool

I believed this method way more faster to develope tool. Build HUGE interface is pain in the ass.
If you still confused, I don't know what you want to do with your tool.

Good luck.

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