pythonmayamel

Maya add shelf separator: everything gives errors or doesn't work how as I expect it


Trying to create a shelf separator on Maya 2020 on Linux into any currently open shelf (which happens here to be named Custom but I want a thing that works on any shelf). I have tried a few things so far:

1. When using addShelfSeparator(); in the MEL commandline or as a shelf button in the shelf I want the separator:
// Error: file: /s/apps/packages/cg/maya/2020.4.9-45.0/platform-linux/scripts/startup/shelf.mel line 594: Object's window not found.
2. When using separator -width 12 -height 35 -style "shelf" -hr false; as in the shelf.mel at line 594 while the Attribute Editor is open:
// Error: line 1: Object's window not found.
3. Same as the above, but with the Attribute Editor closed:

It creates a separator in the Attribute Editor's lower half:

enter image description here

// Result: AttributeEditor|MainAttributeEditorLayout|formLayout52|AEmenuBarLayout|separator91
4. With the following code:
import maya.cmds as cmds
import maya.mel as mel

gShelfTopLevel = mel.eval("global string $gShelfTopLevel; $temp = $gShelfTopLevel;")
currentShelf = cmds.tabLayout(gShelfTopLevel, q=True, st=True)

cmds.separator(currentShelf, width=12, height=35, style="shelf", hr=False)

I get this error:

global string $gShelfTopLevel; $temp = $gShelfTopLevel;
// Result: Shelf|MainShelfLayout|formLayout17|ShelfLayout // 
# Error: Object's window not found.
# Traceback (most recent call last):
#   File "<maya console>", line 7, in <module>
# RuntimeError: Object's window not found. # 

Why addShelfSeparator(); isn't working in the first place? It's supposed to be the "official" tool to do that.


Solution

  • You were really close with your code! It doesn't seem like there's any documentation on what separator takes as a positional argument, but you would just need to pass the shelf as the parent keyword argument of separator like so:

    cmds.separator(width=12, height=35, style="shelf", hr=False, parent=currentShelf)
    

    Alternatively, you can set the default UI parent first, like so:

    cmds.setParent(currentShelf)
    cmds.separator(width=12, height=35, style="shelf", hr=False)
    

    If you query the parent, you might see that the Attribute Editor is the default parent, which is why the separator goes to that location.

    cmds.setParent(query=True)
    # Result: 'AttributeEditor|MainAttributeEditorLayout|formLayout52|AEmenuBarLayout'
    

    You can see in shelf.mel that the loadShelf proc runs setParent on the shelf name as well, which is probably why addShelfSeparator has no need to set it itself and acts the way it does.

     59 global proc loadShelf(int $index)
     60 {
        ...
     79                 setParent $shelfName;