Search code examples
pythonmaya

Maya python delete button from layout with popup menu


I would like to remove a button with a right click popup menu.
My current setup crashes maya at the cmds.deleteUI...

import maya.cmds as cmds
import functools

class MayaWindow():
    def __init__(self):
        self.WINDOW_NAME = "Maya Window"
        if cmds.window(self.WINDOW_NAME, exists=True):
            cmds.deleteUI(self.WINDOW_NAME, window=True)
        self.window = cmds.window(self.WINDOW_NAME)

        #-- Create some buttons that needs to be deleted with a popupmenu
        cmds.frameLayout(label='Buttons')
        for i in range(10):
            button = cmds.button(label=str(i))
            cmds.popupMenu()
            cmds.menuItem( label='Delete Button', command=functools.partial(self.deleteButton, button))

        cmds.showWindow(self.window)
    
    def deleteButton(self, button, *args):
        print("Execute some code...")

        #-- How to delete the button without crashing?!
        print("Now delete the button please..")
        #cmds.deleteUI( button, control=True ) # <<-- This crashes maya

MayaWindow()

I have found the "evalDeferred" function but I am not sure how to use it in this setup.


Solution

  • The problem is that when the command is executed, Maya is trying to delete the UI element while it's still being used, causing the crash. You pretty much had it figured out. Here's your the code with evalDeferred executing the deleteUI expression.

    import maya.cmds as cmds
    import functools
    
    class MayaWindow():
        def __init__(self):
            self.WINDOW_NAME = "Maya Window"
            if cmds.window(self.WINDOW_NAME, exists=True):
                cmds.deleteUI(self.WINDOW_NAME, window=True)
            self.window = cmds.window(self.WINDOW_NAME)
    
            #-- Create some buttons that need to be deleted with a popupmenu
            cmds.frameLayout(label='Buttons')
            for i in range(10):
                button = cmds.button(label=str(i))
                cmds.popupMenu()
                cmds.menuItem(label='Delete Button', command=functools.partial(self.deleteButton, button))
    
            cmds.showWindow(self.window)
        
        def deleteButton(self, button, *args):
            print("Execute some code...")
    
            print("Now delete the button please..")
            cmds.evalDeferred(lambda: cmds.deleteUI(button, control=True)) # <<-- This should no longer crash Maya
    
    MayaWindow()