So I know about the dockControl command inside maya to dock a UI, but i want to go a bit deeper and dock my UI’s at a lower level using the addDockWidget method on QMainWindows.
I can create a QDockWidget and it will Dock to the Maya UI - however, it’s docking below the existing UI, instead of replacing the UI in the dock. In other words, when I dock my new UI, it’s splitting the dockable region into an upper and lower half.
Basically it looks like when I add my new widget to the region, I am too high up in Maya’s UI heirarchy - I need to walk down a few layouts until I get to the attribute editor/channel box area.
I am looking for advice on walking the Maya Qt Heirarchy until I find the right place to dock my widget.
Thanks for the reply. The pymel/dockControl stuff is useful, but I am intentionally, (and perhaps foolishly), going deeper to the Qt level to perform the docking operations.
it seems the problem I am running into is the Attribute Editor/Channel Box/ etc. is a Tabbed Layout with Dock Widget, and when I add my new Dock Widget it is not going into the Tabbed Layout, but instead splitting the RightDock Area into two vertical sub sections.
seems like i need to get my new dock widget into the tabbed widget.
Did you ever manage to solve this? I’ve gotten pretty far with the core Qt stuff, but I’m stuck with trying to force dock my window. Calling addDockWidget on the MayaWindow for my dockwidget does nothing. I can dock it manually, just not through code.
Also, that code from Jason, that nezus linked is a bit ‘dirty’ if you ask me; mixing the pm controls with Qt controls and doing a bunch of workarounds isn’t great. It’s also much harder to use that code in a clean system that doesn’t delete and recreate your UI every time (but rather shows and hides it).
Hey, well that’s kind of what i want to avoid, having to use things like cmds.dockControl.
We looked into it a bit further, and it seems like it’s a bug within Pyside:
passing in a pure QdockWidget with mayawindow.addDockwidget() works fine.
My class however, inherits from Qdockwidget and expands it. passing that into the same function, does not work. Doesn’t make any sense!
Here’s some code to test if anybody cares:
UI file to load/inherit (save as Windowtest.ui on C: if you don’t want to modify the other code):
from PySide import QtGui, QtCore
import shiboken as qtBindingGenerator
from cStringIO import StringIO
import xml.etree.ElementTree as xml
def loadUiType(uiFile):
import pysideuic
#Pyside lacks the "loadUiType" command, so we have to convert the ui file to py code in-memory first
#and then execute it in a special frame to retrieve the form_class.
parsed = xml.parse(uiFile)
widget_class = parsed.find('widget').get('class')
form_class = parsed.find('class').text
with open(uiFile, 'r') as f:
o = StringIO()
frame = {}
pysideuic.compileUi(f, o, indent=0)
pyc = compile(o.getvalue(), '<string>', 'exec')
exec pyc in frame
#Fetch the base_class and form class based on their type in the xml from designer
form_class = frame['Ui_%s'%form_class]
base_class = eval('QtGui.%s'%widget_class)
return form_class, base_class
def getTopWindow():
'''
Gets maya top window
'''
import maya.OpenMayaUI as apiUI
ptr = apiUI.MQtUtil.mainWindow()
if ptr is not None:
return qtBindingGenerator.wrapInstance(long(ptr), QtGui.QMainWindow)
else:
print "No window found"
#UI File is defined and loaded here
uiFile = "C:/WindowTest.ui" #change to wherever your UI file is located.
pform, pbase = loadUiType(uiFile)
class WindowTest(pform, pbase):
def __init__(self, parent=getTopWindow()):
super(WindowTest, self).__init__(parent)
self.setupUi(self)
self.show()
def TestDockingCustom():
'''
This creates the custom UI element and tries to dock it
'''
docktest = WindowTest()
getTopWindow().addDockWidget(QtCore.Qt.LeftDockWidgetArea , docktest)
def TestDockingStandard():
'''
This creates a vanilla QDockWidget and tries to dock it
'''
docktest = QtGui.QDockWidget()
getTopWindow().addDockWidget(QtCore.Qt.LeftDockWidgetArea , docktest)
TestDockingCustom()
TestDockingStandard()