Python-当用户在自定义maya UI窗口外单击时,如何删除该窗口?

Python-当用户在自定义maya UI窗口外单击时,如何删除该窗口?,python,user-interface,window,maya,Python,User Interface,Window,Maya,我有一个自定义窗口,当用户点击货架上的物品时,它基本上就是一个弹出窗口 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", w

我有一个自定义窗口,当用户点击货架上的物品时,它基本上就是一个弹出窗口

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()))
窗口正确显示,所有按钮都执行它们应该执行的操作,每当按下按钮时,我都会删除窗口。一切都很好

我试图做的是检测用户何时单击窗口外的任何位置,以便我可以删除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窗口,重新实现焦点函数,或者安装一个几乎不回避的事件过滤器

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)
原版

这是我自己的一段代码,我用它连接到窗口的销毁信号。 你可以做同样的丢失窗口焦点

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")

谢谢@cronicryo,但假设我对widget、pyside和Qt知之甚少。什么叫onUIDelete?这是一个内置的事件函数,在特定事件发生时自动触发,还是您必须明确地调用它,在这种情况下,如何/在哪里?谢谢,@croncryo我编辑了我的问题以反映您的答案…并提出了更多问题!:)@TheMsika打印语句帮助很大!如果您注意到过滤器中有一个持续打印,而它没有打印。Qt的所有面向对象,因为它是基于C++的,为什么它不运行?因为fltr变量在run function中不再存在并被删除,所以只需在def run下面的第一行添加行“global fltr”。第二个问题是,您将遇到一个对象试图在其仍在运行时删除自身,并将无限期地使maya崩溃。您将需要一些超时,然后删除它,而不必了解线程的细节,您可以查看QTimer