当前位置: 首页 > 面试题库 >

使用PySide清理Maya中的可停靠窗口

荣俊杰
2023-03-14
问题内容

我创建了一个可以停靠在Maya主ui中的工具,但是我想不出一种方法来关闭它。问题是,如果我创建该工具的多个实例,然后将其拖动到适当位置以将其停靠,则在我右键单击Maya的窗口时,它们将全部显示。工具关闭后,如何正确清理这些东西?

我已经尝试过了cmds.deleteUIQObject.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()

问题答案:

在研究了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的环境了。希望能帮助到你!



 类似资料:
  • 我正在用PySide和Python2.7编写一个程序。 这段代码显示一个工作任务栏图标和一个iconmenu。现在,当我点击“Show Window”时,我想在图标的相同位置加载一个停靠到任务栏的Widget/Windows。 如果我会使用几何学,这将永远不会工作,因为有些人的任务栏在顶部,或在屏幕的侧面。 如何用pyside将窗口/小部件停靠到任务栏? 谢谢。

  • wxAui是一个包含在wxWidgets API中的高级用户界面库。 Wx.aui.AuiManager是AUI框架中的中心类。 AuiManager使用wx.aui.AuiPanelInfo对象中的每个面板信息管理与特定帧关联的窗格。 让我们了解PanelInfo对象控件对接和浮动行为的各种属性。 将可停靠窗口放在顶层框架中涉及以下步骤 - 首先,创建一个AuiManager对象。 self.m

  • 环境再贴现2.8。17 我们已经使用与redis文档中描述的模式类似的模式在RPOPLPPUSH下实现了可靠队列 然而,考虑到其阻塞性质,我们使用BRPOPLPUSH,而LPUSH用于确保FIFO顺序。 生产者:使用LPUSH推送项目的多个线程(来自多个服务器)。 消费者:使用BRPOPLPUSH处理项目的多个线程(来自多个服务器)。 如文件所述,redis从队列“q”中弹出项目,同时将它们添加到

  • 问题内容: 我正在编写脚本程序,并且在UI方面有些挣扎。我已经制作了几个UI,所有这些UI似乎都可以单独正常工作,但是我不知道如何将在UI中输入的数据用于其他功能。我正在尝试获取Gun类型(由用户在中选择),然后影响随后调用哪个UI。每种枪支类型均需要不同的滑块值集,因此我为每种滑块创建了不同的UI。我认为我需要将从BSG中选择的数据传递到函数中,以调用正确的(第二个)UI,但是运行它总是会跳转到

  • 我对docker比较陌生。我想建立一个postgres数据库,但我想知道如果我重新创建容器,如何确保数据不会丢失。 然后我偶然发现了命名卷(不是绑定卷)以及如何使用它们。但是...在Dockerfile中,您不能使用命名卷。例如data:/var/lib等。正如我使用Dockerfile所理解的那样,它总是一个匿名卷。所以每次我重新创建一个容器时,它都会得到自己的新卷。 所以我的问题来了: 首先:

  • 我有一个小的Spring Boot API在docker中运行。下面显示的是我用来升级容器的命令。 然后,我有一个停靠的JMeter,我使用下面的命令来启动它 但是所有的测试都失败了,请求没有被发送到API。这就是JMeter的CLI的外观 请求的测试配置: 协议:htttp 服务器:localhost 端口:8080 方法:GET 路径:/api/factorial 完整的bash文件如下所示:

  • 海蓝(navy blue)是最为大众所接受的颜色之一。采用这种颜色的色彩组合可解释成可靠、值得信赖的色彩。这类组合也带有不可置疑的权威感。警官、海军军官或法官都穿着深色、稳定的海军蓝,以便在值勤时表现出统率、支配的权威感。 当海军蓝用红和金色来强调时,会变得较不严肃,但仍表达出坚定、有力量的感觉。 补色色彩组合 原色色彩组合 单色色彩组合 21 65 17 65 33 1 65 67 70 65

  • 我搜索了很多,但对“ReentrantLock”和正常的“synchronized”的过程感到困惑。 例如(1): 示例(2) 我的问题是: 在示例1中:保证使用synchronized关键字获取对象的锁。 但是 例2:是否保证使用锁获取锁。lock()方法??或者线程会继续执行下一行吗??没有锁。 我对此表示怀疑,因为使用线程多次给我带来了意想不到的结果。