Created
December 1, 2017 15:04
-
-
Save liorbenhorin/69da10ec6f22c6d7b92deefdb4a4f475 to your computer and use it in GitHub Desktop.
Simple way to Docking Qt widgets to Maya 2017+
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.