Python - 当用户在自定义 Maya UI window 外部单击时,我该如何删除它?

Python - How do I go about deleting a custom maya UI window when the user clicks outside of it?

我有一个自定义 window,它基本上在用户单击货架项目时充当弹出窗口。

def drawUI(): 
    mouse_pos = QtGui.QCursor().pos()
    print 'mouse x: %d y: %d' % (mouse_pos.x(), mouse_pos.y())
    if cmds.window("SET_SELECTION_UI", exists = True):
        cmds.deleteUI("SET_SELECTION_UI", window=True)

    cmds.window("SET_SELECTION_UI", title = "Example", wh = (102, 300), rtf=True, mnb = False, mxb = False, tb = False, sizeable = False, tlc=(mouse_pos.y(),mouse_pos.x()))
    cmds.columnLayout()
    cmds.button(label = "Set 00",   w = 100, command=button00)
    cmds.button(label = "Set 10",   w = 100, command=Button10)
    cmds.button(label = "Set 25",   w = 100, command=Button25)
    cmds.separator( height=10, style='double' )
    cmds.button(bgc=[1,1,1], label = "Cancel", w = 100, command=DeleteButton)
    cmds.showWindow() #shows window

    cmds.window("SET_SELECTION_UI", edit=True, tlc=(mouse_pos.y(),mouse_pos.x()))

window 正确显示,所有按钮都按预期执行,每当按下按钮时,我都会删除 window。一切都很好,花花公子。

我想做的是检测用户何时单击 window 之外的任何地方,以便我可以删除 UI(很像弹出菜单的工作原理) .

谢谢!

回答

我已经将 Cronicryo 的脚本和建议整合到我自己的脚本和建议中,现在可以完美运行了!这是:

from PySide import QtGui, QtCore
import maya.OpenMayaUI as omui
import pymel.core as pm
from shiboken import wrapInstance

fltr    = None
qtObj   = None
_WINDOW_NAME_ = "SET_SELECTION_UI"

class FilterObj(QtCore.QObject):
    def eventFilter(self, obj , event):
        print event.type()
        if event.type() == event.WindowDeactivate:
            print "focused out"
            pm.window(_WINDOW_NAME_,edit=True,visible=False)
            return True #must return a bool set False to allow normal events to pass through or True to stop any further events
        else:
            return False

def run(): 
    global fltr
    global qtObj

    if qtObj:
        del qtObj

    mouse_pos = QtGui.QCursor().pos()
    print 'mouse x: %d y: %d' % (mouse_pos.x(), mouse_pos.y())
    if pm.window(_WINDOW_NAME_, exists = True):
        pm.deleteUI(_WINDOW_NAME_, window=True)

    win = pm.window(_WINDOW_NAME_, title = "Set Select", mnb = False, mxb = False, tb = False, sizeable = False)
    pm.columnLayout()
    pm.button(label = "Do nothing",   w = 100)
    pm.separator( h=15, w=100, style='doubleDash' )
    pm.button(bgc=[1,1,1], label = "Cancel", w = 100, command=DeleteButton)
    pm.showWindow(win) #shows window

    pm.window(_WINDOW_NAME_, edit=True, wh = (102, 245),tlc=(mouse_pos.y(),mouse_pos.x()))

    qtObj = wrapInstance(long(omui.MQtUtil.findControl(_WINDOW_NAME_)), QtGui.QWidget)
    fltr = FilterObj()
    qtObj.installEventFilter(fltr)

def DeleteButton(*args):
    pm.deleteUI(_WINDOW_NAME_)

编辑

我看了一下,好像没有发出聚焦信号。似乎唯一的方法是制作自定义 qt window 并重新实现焦点功能或安装几乎无规避的事件过滤器

import maya.OpenMayaUI as omui
import pymel.core as pm
pysideSupport = True
try:
    from PySide import QtGui
    from shiboken import wrapInstance
except:
    pysideSupport = False

win = pm.window("aaa")
win.show()

from PySide import QtCore

class FilterObj(QtCore.QObject):
    def eventFilter(self, obj , event):
        print event.type()
        if event.type() == event.WindowDeactivate:
            print "focused out"
            return False #must return a bool set False to allow normal events to pass through or True to stop any further events
        else:
            return False


qtObj = wrapInstance(long(omui.MQtUtil.findControl("aaa")), QtGui.QWidget)
fltr = FilterObj()
qtObj.installEventFilter(fltr)

ORIG:

这是我自己的代码片段,我用它来连接到 window 的销毁信号。 你可以做同样的事情来失去 window 焦点

import maya.OpenMayaUI as omui
pysideSupport = True
try:
    from PySide import QtGui
    from shiboken import wrapInstance
except:
    pysideSupport = False


def onUIDelete(uiName, function):
    """
    extends mayas ui by being able to run a function when the ui gets deleted
    this requires maya to have PySide

    """
    if pysideSupport:
        if isinstance(uiName, pm.ui.PyUI):
            uiName = uiName.name()
        qtObj = wrapInstance(long(omui.MQtUtil.findControl(uiName)), QtGui.QWidget)
        qtObj.destroyed.connect(function)
    else:
        pm.error("Maya doesn't have PySide Support")