Plug-in development: UI cleanup problem when Maya exits

I'm new to Maya plug-in development and have a question regarding UI cleanup.  I'm writing a plug-in that creates a new shelf (with various shelfButtons attached to external scripts).  When the plug-in loads and unloads, I want to add or remove this shelf from the Maya UI.  This is working without any issue.  However, I also want to clear my plug-in shelf when Maya exits (if the plug-in is set to Auto-Load it will simply load again on restart...if Auto-Load is not set, I don't want the shelf to appear when Maya starts). 

This should be possible by registering a callback (OpenMaya.MSceneMessage.kMayaExiting) during the 'initializePlugin' method. The following code works without any issues if I attach the callback to a different scene message (such as kAfterSave), but when I use kMayaExiting it doesn't remove the shelf. Strangely, if I do a quick print statement (on exit) to test if the shelf has been removed it appears to have removed it...but when I restart Maya the shelf appears once again (without loading the plugin). I'm not completely sure about the print statement either because the output flies by pretty quickly when Maya exits (is it possible to log the ScriptEditor text to a file when exiting?). Thanks for any help! I've been banging my head against this issue all day. :stuck_out_tongue:

import maya
import maya.OpenMaya as OpenMaya
import maya.OpenMayaMPx as OpenMayaMPx
 
fMayaExitingCB = None
 
# Remove the UI when Maya exits
def removeUI(clientData):        
        maya.cmds.setParent(maya.mel.eval("global string $gShelfTopLevel;$temp = $gShelfTopLevel"))
 
	if maya.cmds.layout("TestPluginShelf", exists=True):
            maya.cmds.deleteUI("TestPluginShelf", layout=True)
 
 
# Initialize the script plug-in
def initializePlugin(mobject):
	mplugin = OpenMayaMPx.MFnPlugin(mobject, "TestPlugin", "1.0", "Any")
 
        # Create shelf and buttons
	maya.cmds.setParent(maya.mel.eval("global string $gShelfTopLevel;$temp = $gShelfTopLevel"))
	if maya.cmds.layout("TestPluginShelf", exists=True) == False:
                maya.cmds.shelfLayout("TestPluginShelf", style="textOnly")
                maya.cmds.shelfButton(image1="scriptIcon.png",
                                                 label="script", annotation="externalScript",
                                                 command="import ExternalScript\nreload(ExternalScript)", sourceType="python")
 
        # Add callback to clean up UI when Maya exits
	global fMayaExitingCB
	fMayaExitingCB = OpenMaya.MSceneMessage.addCallback(OpenMaya.MSceneMessage.kMayaExiting, removeUI)
 
 
# Uninitialize the script plug-in
def uninitializePlugin(mobject):
	mplugin = OpenMayaMPx.MFnPlugin(mobject)
 
        # Cleanup the UI and remove the callback when plug-in is unloaded
	maya.cmds.setParent(maya.mel.eval("global string $gShelfTopLevel;$temp = $gShelfTopLevel"))
	if maya.cmds.layout("TestPluginShelf", exists=True):
            maya.cmds.deleteUI("TestPluginShelf", layout=True)
 
	global fMayaExitingCB
        if (fMayaExitingCB != None):		
		OpenMaya.MSceneMessage.removeCallback(fMayaExitingCB)

Cheers,
Josiah

It turns out this was an issue with user preferences.  If I either set the Shelf Editor options to "Save Only On Request" or uncheck "Save all preferences and settings when Maya exits" in the general Save Actions settings then this works without a hitch.

There doesn't seem to be any other callback that would work in this situation.  The preferences are being saved before kMayaExiting is called. I suppose I could just leave it up to user preferences for now, though parsing and removing the appropriate lines from the userPrefs file is an option (I'd rather not touch that though)...

Its too late, you can not control the timing of events. Unless you want to edit the scritjob thet does the save. Offcourse thats a bit fo a hack so if anybodey else would do this too it would go tits up.

The main problem is that its NOT your shelf. Its the users. So its  a bit fo problematic to delete it for him. You could end up killing something the user has stored for later use. Which is not your intention. You shouldnt really do this as its not your property.

But it is sortof valid, so i will give you a push in the right direction. Theres a very easy way to circumvent this, in way which skips the need to cleanup on exit.

Instead of making a shelf directly parent your own shelf under a different gui layout. this will shortcircuit the saving function to skip your shelf. Better yet you can also make sure nobody adds anything to the shelf.

A second variant s to actually add t the shelf directory structure by pointing maya to an additional shelf dir. Whare you store yoru shelf pref. Now when maya exits it will write thet shlf there, it would become persistent and not load untill you load it later because you ste the search path in your lugin load.