我创建了一个能够停靠在Maya主要ui中的工具,但是一旦关闭它我就无法找到一种方法来清理它。问题是如果我创建该工具的多个实例然后将其拖动到位以停靠它,当我右键单击Maya的窗口时它们将全部显示。当工具关闭时,如何正确清理这些?
我已经尝试cmds.deleteUI
,QObject.deleteLater()
,我最多只能清除该工具的内容,但它仍然存在于Maya中。这是我到目前为止的一个例子:
from shiboken import wrapInstance
from PySide import QtGui, QtCore
from maya import OpenMayaUI as OpenMayaUI
from maya.app.general.mayaMixin import MayaQWidgetDockableMixin
class Window(MayaQWidgetDockableMixin, QtGui.QWidget):
def __init__(self, parent = None):
super(self.__class__, self).__init__(parent = parent)
mayaMainWindowPtr = OpenMayaUI.MQtUtil.mainWindow()
self.mayaMainWindow = wrapInstance(long(mayaMainWindowPtr), QtGui.QWidget)
self.setWindowFlags(QtCore.Qt.Window)
if cmds.window('myTool', q = True, ex = True):
cmds.deleteUI('myTool')
self.setObjectName('myTool')
self.setWindowTitle('My tool')
self.resize(200, 200)
self.myButton = QtGui.QPushButton('TEMP')
self.mainLayout = QtGui.QVBoxLayout()
self.mainLayout.addWidget(self.myButton)
self.setLayout(self.mainLayout)
def dockCloseEventTriggered(self):
self.deleteLater()
def run(self):
self.show(dockable = True)
myWin = Window()
myWin.run()
SOLUTION:
在挖掘mayaMixin.py
之后,我设法找到了一个有效的解决方案,我之后的行为!这个想法是你需要挖掘Maya的主窗口并删除它的任何实例。
以下示例将在窗口关闭或创建新实例后干净地删除任何实例。如果它停靠或浮动并不重要,它似乎工作正常。如果您在停靠时不想要删除行为,也可以随时调整行为。我在代码中留下了很多评论,因为有很多"陷阱"。
from shiboken import wrapInstance
from PySide import QtGui, QtCore
from maya import OpenMayaUI as OpenMayaUI
from maya.app.general.mayaMixin import MayaQWidgetDockableMixin
from maya.OpenMayaUI import MQtUtil
class MyWindow(MayaQWidgetDockableMixin, QtGui.QDialog):
toolName = 'myToolWidget'
def __init__(self, parent = None):
# Delete any previous instances that is detected. Do this before parenting self to main window!
self.deleteInstances()
super(self.__class__, self).__init__(parent = parent)
mayaMainWindowPtr = OpenMayaUI.MQtUtil.mainWindow()
self.mayaMainWindow = wrapInstance(long(mayaMainWindowPtr), QtGui.QMainWindow)
self.setObjectName(self.__class__.toolName) # Make this unique enough if using it to clear previous instance!
# Setup window's properties
self.setWindowFlags(QtCore.Qt.Window)
self.setWindowTitle('My tool')
self.resize(200, 200)
# Create a button and stuff it in a layout
self.myButton = QtGui.QPushButton('My awesome button!!')
self.mainLayout = QtGui.QVBoxLayout()
self.mainLayout.addWidget(self.myButton)
self.setLayout(self.mainLayout)
# If it's floating or docked, this will run and delete it self when it closes.
# You can choose not to delete it here so that you can still re-open it through the right-click menu, but do disable any callbacks/timers that will eat memory
def dockCloseEventTriggered(self):
self.deleteInstances()
# Delete any instances of this class
def deleteInstances(self):
mayaMainWindowPtr = OpenMayaUI.MQtUtil.mainWindow()
mayaMainWindow = wrapInstance(long(mayaMainWindowPtr), QtGui.QMainWindow) # Important that it's QMainWindow, and not QWidget/QDialog
# Go through main window's children to find any previous instances
for obj in mayaMainWindow.children():
if type( obj ) == maya.app.general.mayaMixin.MayaQDockWidget:
#if obj.widget().__class__ == self.__class__: # Alternatively we can check with this, but it will fail if we re-evaluate the class
if obj.widget().objectName() == self.__class__.toolName: # Compare object names
# If they share the same name then remove it
print 'Deleting instance {0}'.format(obj)
mayaMainWindow.removeDockWidget(obj) # This will remove from right-click menu, but won't actually delete it! ( still under mainWindow.children() )
# Delete it for good
obj.setParent(None)
obj.deleteLater()
# Show window with docking ability
def run(self):
self.show(dockable = True)
myWin = MyWindow()
myWin.run()
这样就不再污染玛雅的环境了。希望它有所帮助!
答案 0 :(得分:0)
深入研究mayaMixin.py之后,我设法获得了我所追求的行为的有效解决方案!这个想法是,您需要在Maya的主窗口中进行挖掘,并删除其中的所有实例。
关闭窗口或创建新实例后,以下示例将彻底删除所有实例。停靠或浮动都没关系,看起来工作正常。如果您不想在停靠时将其关闭,也可以随时对其进行调整。我在代码中留下了很多注释,因为那里有很多“陷阱”。
from shiboken import wrapInstance
from PySide import QtGui, QtCore
from maya import OpenMayaUI as OpenMayaUI
from maya.app.general.mayaMixin import MayaQWidgetDockableMixin
from maya.OpenMayaUI import MQtUtil
class MyWindow(MayaQWidgetDockableMixin, QtGui.QDialog):
toolName = 'myToolWidget'
def __init__(self, parent = None):
# Delete any previous instances that is detected. Do this before parenting self to main window!
self.deleteInstances()
super(self.__class__, self).__init__(parent = parent)
mayaMainWindowPtr = OpenMayaUI.MQtUtil.mainWindow()
self.mayaMainWindow = wrapInstance(long(mayaMainWindowPtr), QtGui.QMainWindow)
self.setObjectName(self.__class__.toolName) # Make this unique enough if using it to clear previous instance!
# Setup window's properties
self.setWindowFlags(QtCore.Qt.Window)
self.setWindowTitle('My tool')
self.resize(200, 200)
# Create a button and stuff it in a layout
self.myButton = QtGui.QPushButton('My awesome button!!')
self.mainLayout = QtGui.QVBoxLayout()
self.mainLayout.addWidget(self.myButton)
self.setLayout(self.mainLayout)
# If it's floating or docked, this will run and delete it self when it closes.
# You can choose not to delete it here so that you can still re-open it through the right-click menu, but do disable any callbacks/timers that will eat memory
def dockCloseEventTriggered(self):
self.deleteInstances()
# Delete any instances of this class
def deleteInstances(self):
mayaMainWindowPtr = OpenMayaUI.MQtUtil.mainWindow()
mayaMainWindow = wrapInstance(long(mayaMainWindowPtr), QtGui.QMainWindow) # Important that it's QMainWindow, and not QWidget/QDialog
# Go through main window's children to find any previous instances
for obj in mayaMainWindow.children():
if type( obj ) == maya.app.general.mayaMixin.MayaQDockWidget:
#if obj.widget().__class__ == self.__class__: # Alternatively we can check with this, but it will fail if we re-evaluate the class
if obj.widget().objectName() == self.__class__.toolName: # Compare object names
# If they share the same name then remove it
print 'Deleting instance {0}'.format(obj)
mayaMainWindow.removeDockWidget(obj) # This will remove from right-click menu, but won't actually delete it! ( still under mainWindow.children() )
# Delete it for good
obj.setParent(None)
obj.deleteLater()
# Show window with docking ability
def run(self):
self.show(dockable = True)
myWin = MyWindow()
myWin.run()
因此,它不再污染Maya的环境。希望对您有帮助!