PyMEL: Hidden frameLayout still takes up vertical space

#### Start up ####

import pymel.core as pm

class TestWin():

    # UI vars
    titleVar = "TEST"

    windowX = 300 # Window width
    windowY = 688 # Window height
    winTestWin = "TestWin_win"

    btnAddX = 36 # Add button (advanced mode)
    btnClrX = 41 # Clear button (advanced mode)
    btnRemX = 54 # Remove button (advanced mode)
    btnW = 61 # Normal button width
    btnW2 = 118 # Large button width
    
    colSpacing1 = 20 # Tab 2 column1 spacing
    colSpacing2 = 40 # Tab 2 column2 spacing
    colSpacing3 = 10 # Tab 2 column3 spacing
    frameMargin = 10 # Frame margin
    objCol = (windowX / 2) # Column width in advanced mode
    objListY = 215 # Height of object list
    radCol1 = 50 # Radio button - column 1 width
    radCol2 = 50 # Radio button - column 2 width

    # Object list
    itemList = []


    ## Initialize
    def __init__(self):

        # Option vars. Create new if they don't exist yet
        if not ( pm.optionVar( exists="TestWinoptVarX" )):
            pm.optionVar( intValue=("TestWinoptVarX", 256) )

        if not ( pm.optionVar( exists="TestWinoptVarY" )):
            pm.optionVar( intValue=("TestWinoptVarY", 256) )

        if not ( pm.optionVar( exists="TestWinoptVarPath" )):
            pm.optionVar( stringValue=("TestWinoptVarPath", "") )

        if not ( pm.optionVar( exists="TestWinoptVarPadding" )):
            pm.optionVar( intValue=("TestWinoptVarPadding", 0) )

        if not ( pm.optionVar( exists="TestWinoptVarFormat" )):
            pm.optionVar( intValue=("TestWinoptVarFormat", 1 ) )

        # Create UI
        self.createUI()
        self.updateUI(-1)


    ## User-interface

    # Close window
    def closeUI(self):
        pm.deleteUI( self.winTestWin )


    ## Create UI layout
    def createUI(self):

        # Check for window duplicate
        if pm.window( self.winTestWin, exists=True ):
            pm.deleteUI( self.winTestWin )

        # Main window
        window = pm.window(
            self.winTestWin,
            maximizeButton=True,
            minimizeButton=True,
            sizeable=False,
            title=self.titleVar,
            widthHeight=(self.windowX, self.windowY)
        )
        
        # Create main form layout
        self.formMain = pm.formLayout()
        self.formFrames = pm.formLayout(parent=self.formMain)

        ## Options frame
        self.frameOptions = pm.frameLayout(
            collapsable=False,
            collapse=False,
            label="Options",
            marginHeight=self.frameMargin,
            marginWidth=self.frameMargin,
            parent=self.formFrames,
            width=self.windowX,
        )
        
        # Options layout
        self.colOptions = pm.columnLayout(
            adjustableColumn=True,
            columnAlign="left",
            rowSpacing=6,
            parent=self.frameOptions,
        )

        # Options controls
        self.outPath = pm.textFieldButtonGrp(
            "filePathField",
            buttonCommand=lambda *args: self.browse(),
            buttonLabel="Browse...",
            changeCommand=lambda *args: self.updateUI(2),
            columnAttach3=["left", "left", "right"],
            columnWidth3=[45, 144, 20],
            label="Path:",
            parent=self.colOptions,
            text=pm.optionVar( query="TestWinoptVarPath" ),
            width=252
        )

        self.mapSizeX = pm.intSliderGrp(
            "sliderX",
            changeCommand=lambda *args: self.updateUI(0),
            columnAttach3=["left", "left", "left"],
            columnWidth3=[45, 35, 45],
            dragCommand=lambda *args: self.updateUI(0),
            field=True,
            fieldStep=32,
            label="Size X:",
            max=8192,
            min=32,
            parent=self.colOptions,
            sliderStep=32,
            step=32,
            value=pm.optionVar( query="TestWinoptVarX" ),
            width=252
        )

        self.mapSizeY = pm.intSliderGrp(
            "sliderY",
            changeCommand=lambda *args: self.updateUI(1),
            columnAttach3=["left", "left", "left"],
            columnWidth3=[45, 35, 45],
            dragCommand=lambda *args: self.updateUI(1),
            field=True,
            fieldStep=32,
            label="Size Y:",
            max=8192,
            min=32,
            parent=self.colOptions,
            sliderStep=32,
            step=32,
            value=pm.optionVar( query="TestWinoptVarY" ),
            width=252
        )

        self.padding = pm.intSliderGrp(
            "sliderPadding",
            changeCommand=lambda *args: self.updateUI(3),
            columnAttach3=["left", "left", "left"],
            columnWidth3=[45, 35, 45],
            dragCommand=lambda *args: self.updateUI(3),
            field=True,
            fieldStep=1,
            label="Padding:",
            max=16,
            min=0,
            parent=self.colOptions,
            sliderStep=1,
            step=1,
            value=pm.optionVar( query="TestWinoptVarPadding" ),
            width=252
        )

        self.fileFormat = pm.optionMenuGrp(
            "fileFormat",
            changeCommand=lambda *args: self.updateUI(4),
            columnAttach2=["left", "left"],
            columnWidth2=[45, 196],
            label="Format:",
            parent=self.colOptions,
            width=241,
        )

        # File format list on Machintosh
        if ( pm.about(macOS=True) ):
            pm.menuItem( label="Maya IFF" )
            pm.menuItem( label="JPEG" )
            pm.menuItem( label="MacPaint" )
            pm.menuItem( label="PSD" )
            pm.menuItem( label="PNG" )
            pm.menuItem( label="Quickdraw" )
            pm.menuItem( label="Quickdraw Image" )
            pm.menuItem( label="SGI" )
            pm.menuItem( label="TGA" )
            pm.menuItem( label="TIFF" )
            pm.menuItem( label="BMP" )

        # File format list on Windows
        else:
            imfKey = ""
            i = 0

            # Query available image formats
            imfPlugins = pm.imfPlugins( query=True )

            # Maya IFF always available
            pm.menuItem( label="Maya IFF" )

            # Display queried image formats
            for i in xrange( 0, len(imfPlugins) ):
                imfKey = pm.imfPlugins( imfPlugins[i], query=True, key=True )

                if ( pm.imfPlugins( imfKey, query=True, writeSupport=True ) and not
                pm.imfPlugins( imfKey, query=True, multiFrameSupport=True ) and
                imfKey != "maya" ):
                    pm.menuItem( label=imfPlugins[i] )

        # Select file format from optionVar
        pm.optionMenuGrp(
            "fileFormat",
            edit=True,
            select=pm.optionVar( query="TestWinoptVarFormat" )
        )

        self.radGrpOptions = pm.radioButtonGrp(
            changeCommand=lambda *args: self.updateUI(-1),
            columnWidth2=[self.radCol1, self.radCol2*2],
            label="Method: ",
            labelArray2=["Simple", "Advanced"],
            numberOfRadioButtons=2,
            parent=self.colOptions,
            select=pm.optionVar["unfoldMethod_NSUV"],
            vertical=True,
        )

        ## Objects frame. Simple mode
        self.frameObjects1 = pm.frameLayout(
            collapsable=False,
            collapse=False,
            label="Objects",
            marginHeight=self.frameMargin,
            marginWidth=self.frameMargin,
            parent=self.formFrames,
            width=self.windowX,
        )

        # Objects list - Simple mode
        self.objListSimple = pm.textScrollList(
            "objListSimple",
            allowMultiSelection=True,
            # deleteKeyCommand=lambda *args: ???(), ## WARN
            height=self.objListY,
            parent=self.frameObjects1,
            width=(self.windowX-self.frameMargin*2),
        )

        # Object buttons - Simple mode
        self.formBtnsSimple = pm.formLayout(parent=self.frameObjects1)

        self.btnAddSimple = pm.button(
            command=lambda *args: self.updateObjList(),
            label="Add",
            parent=self.formBtnsSimple,
        )
        self.btnRemSimple = pm.button(
            command=lambda *args: self.updateObjList(),
            label="Remove",
            parent=self.formBtnsSimple,
        )
        self.btnClrSimple = pm.button(
            command=lambda *args: self.updateObjList(),
            label="Clear",
            parent=self.formBtnsSimple,
        )

        # Layout object buttons form - Simple mode
        pm.formLayout(
            self.formBtnsSimple, edit=True,
            attachForm=[
                (self.btnAddSimple, "left", 5),
                (self.btnAddSimple, "bottom", 5),
                (self.btnRemSimple, "bottom", 5),
                (self.btnClrSimple, "right", 5),
                (self.btnClrSimple, "bottom", 5),
            ],
            attachPosition=[
                (self.btnAddSimple, "right", 3, 33),
                (self.btnRemSimple, "left", 2, 33),
                (self.btnRemSimple, "right", 3, 66),
                (self.btnClrSimple, "left", 2, 66),
            ],
            attachNone=[
                (self.btnAddSimple, "top"),
                (self.btnRemSimple, "top"),
                (self.btnClrSimple, "top"),
            ],
        )

        ## Objects frame. Advanced mode
        self.frameObjects2 = pm.frameLayout(
            collapsable=False,
            collapse=False,
            label="Objects",
            marginHeight=self.frameMargin,
            marginWidth=self.frameMargin,
            parent=self.formFrames,
            width=self.windowX,
        )
        
        # Object lists row layouts - Advanced mode
        self.rowObjLabels = pm.rowLayout(
            columnAttach=[1, "right", 0],
            columnWidth2=[self.objCol/2, self.objCol/2],
            numberOfColumns=2,
            parent=self.frameObjects2,
            width=(self.windowX/2 - self.frameMargin),
        )
        self.rowObjList = pm.rowLayout(
            columnAttach=[1, "right", 0],
            columnWidth2=[self.objCol/2, self.objCol/2],
            numberOfColumns=2,
            parent=self.frameObjects2,
            width=(self.windowX/2 - self.frameMargin),
        )
        self.rowObjBtn = pm.rowLayout(
            columnAttach=[1, "right", 0],
            columnWidth2=[self.objCol/2, self.objCol/2],
            numberOfColumns=2,
            parent=self.frameObjects2,
            width=(self.windowX/2 - self.frameMargin),
        )
        
        # Objects labels - Advanced mode
        self.txtObjLab1 = pm.text(
            align="left",
            label="Lowpoly",
            parent=self.rowObjLabels,
            width=(self.windowX/2 - self.frameMargin),
        )
        self.txtObjLab2 = pm.text(
            align="left",
            label="Highpoly",
            parent=self.rowObjLabels,
            width=(self.windowX/2 - self.frameMargin),
        )

        # Objects lists - Advanced mode
        self.objListAdv1 = pm.textScrollList(
            "objListAdv1",
            allowMultiSelection=True,
            # deleteKeyCommand=lambda *args: ???(), ## WARN
            height=self.objListY,
            parent=self.rowObjList,
            width=(self.windowX/2 - (self.frameMargin) - 2),
        )
        self.objListAdv2 = pm.textScrollList(
            "objListAdv2",
            allowMultiSelection=True,
            # deleteKeyCommand=lambda *args: ???(), ## WARN
            height=self.objListY,
            parent=self.rowObjList,
            width=(self.windowX/2 - (self.frameMargin) - 2),
        )

        # Object buttons form - Advanced mode
        self.formBtns1 = pm.formLayout(
            parent=self.rowObjBtn, 
            width=(self.windowX/2 - (self.frameMargin) - 2),
        )
        self.formBtns2 = pm.formLayout(
            parent=self.rowObjBtn, 
            width=(self.windowX/2 - (self.frameMargin) - 2),
        )
        
        # Object buttons
        self.btnAddAdv1 = pm.button(
            command=lambda *args: self.updateObjList(),
            label="Add",
            parent=self.formBtns1,
            width=self.btnAddX,
        )
        self.btnAddAdv2 = pm.button(
            command=lambda *args: self.updateObjList(),
            label="Add",
            parent=self.formBtns2,
            width=self.btnAddX,
        )
        self.btnRemAdv1 = pm.button(
            command=lambda *args: self.updateObjList(),
            label="Remove",
            parent=self.formBtns1,
            width=self.btnRemX,
        )
        self.btnRemAdv2 = pm.button(
            command=lambda *args: self.updateObjList(),
            label="Remove",
            parent=self.formBtns2,
            width=self.btnRemX,
        )
        self.btnClrAdv1 = pm.button(
            command=lambda *args: self.updateObjList(),
            label="Clear",
            parent=self.formBtns1,
            width=self.btnClrX,
        )
        self.btnClrAdv2 = pm.button(
            command=lambda *args: self.updateObjList(),
            label="Clear",
            parent=self.formBtns2,
            width=self.btnClrX,
        )

        # Layout object buttons forms - Advanced mode
        pm.formLayout(
            self.formBtns1, edit=True,
            attachForm=[
                (self.btnAddAdv1, "left", 0),
                (self.btnAddAdv1, "top", 0),
                (self.btnRemAdv1, "top", 0),
                (self.btnClrAdv1, "top", 0),
                (self.btnClrAdv1, "right", 5),
            ],
            attachControl=[
                (self.btnRemAdv1, "left", 2, self.btnAddAdv1),
                (self.btnClrAdv1, "left", 2, self.btnRemAdv1),
            ]
        )
        pm.formLayout(
            self.formBtns2, edit=True,
            attachForm=[
                (self.btnAddAdv2, "left", 3),
                (self.btnAddAdv2, "top", 0),
                (self.btnRemAdv2, "top", 0),
                (self.btnClrAdv2, "top", 0),
                (self.btnClrAdv2, "right", 0),
            ],
            attachControl=[
                (self.btnRemAdv2, "left", 2, self.btnAddAdv2),
                (self.btnClrAdv2, "left", 2, self.btnRemAdv2),
            ]
        )


        # Main buttons
        self.btnRun = pm.button(
            command=lambda *args: self.createMap(),
            label="Ok",
            parent=self.formMain,
        )
        self.btnClose = pm.button(
            command=lambda *args: self.closeUI(),
            label="Close",
            parent=self.formMain,
        )
        
        # Layout frames
        pm.formLayout(
            self.formFrames, edit=True,
            attachForm=[
                (self.frameOptions, "top", 0),
                (self.frameOptions, "left", 0),
                (self.frameOptions, "right", 0),

                (self.frameObjects1, "left", 0),
                (self.frameObjects1, "right", 0),

                (self.frameObjects2, "left", 0),
                (self.frameObjects2, "right", 0),
            ],
            attachControl=[
                (self.frameObjects1, "top", 10, self.frameOptions),

                (self.frameObjects2, "top", 10, self.frameObjects1),
            ],
            attachNone=[
                (self.frameObjects1, "bottom"),

                (self.frameObjects2, "bottom"),
            ]
        )
        
        # Layout main form
        pm.formLayout(
            self.formMain, edit=True,
            attachForm=[
                (self.btnRun, "left", 5),
                (self.btnRun, "bottom", 5),
                (self.btnClose, "bottom", 5),
                (self.btnClose, "right", 5),
            ],
            attachPosition=[
                (self.btnRun, "right", 3, 50),
                (self.btnClose, "left", 2, 50),
            ],
            attachNone=[
                (self.btnRun, "top"),
                (self.btnClose, "top"),

            ],
        )

        # Display the window
        pm.showWindow( window ) 


    ## Update UI controls - WARN: NEEDS UPDATE
    def updateUI(self, mode):
    
        # Update methods
        if mode == -1:
        
            # Simple mode
            if self.radGrpOptions.getSelect() == 1:
                self.frameObjects1.setVisible(True)
                self.frameObjects1.setLabelVisible(True)
                self.frameObjects2.setVisible(False)
                self.frameObjects2.setLabelVisible(False)

            else: # Advanced mode
                self.frameObjects1.setVisible(False)
                self.frameObjects1.setLabelVisible(False)
                self.frameObjects2.setVisible(True)
                self.frameObjects2.setLabelVisible(True)

        # Update X slider
        elif mode == 0:

            # Query the slider, round to power of two
            optVarVal = pm.intSliderGrp( self.mapSizeX, query=True, value=True )
            optVarVal = self.powerOfTwo(optVarVal)

            # Edit slider and update the optionVar
            pm.intSliderGrp( self.mapSizeX, edit=True, value=optVarVal )
            pm.optionVar( intValue=("TestWinoptVarX", optVarVal) )


        # Update Y slider
        elif mode == 1:

            # Query the slider, round to power of two
            optVarVal = pm.intSliderGrp( self.mapSizeY, query=True, value=True )
            optVarVal = self.powerOfTwo(optVarVal)

            # Edit slider and update the optionVar
            pm.intSliderGrp( self.mapSizeY, edit=True, value=optVarVal )
            pm.optionVar( intValue=("TestWinoptVarY", optVarVal) )


        # Update output path
        elif mode == 2:

            # Query the field
            filePath = pm.textFieldButtonGrp( self.outPath, query=True, text=True )

            # Update the optVar
            pm.optionVar( stringValue=("TestWinoptVarPath", filePath) )


        # Update the padding slider
        elif mode == 3:

            # Query the slider
            paddingVal = pm.intSliderGrp( self.padding, query=True, value=True )

            # Edit slider and update the optionVar
            pm.intSliderGrp( self.padding, edit=True, value=paddingVal )
            pm.optionVar( intValue=("TestWinoptVarPadding", paddingVal) )


        # Update file format optionVar
        elif mode == 4:

            # Query the list
            fileFormat = pm.optionMenuGrp( self.fileFormat, query=True, select=True )

            # Update optionVar
            pm.optionVar( intValue=("TestWinoptVarFormat", fileFormat ) )


        # Else something is wrong
        else:
            print("You are using updateUI() incorrectly!!!")


# Execute everything
TestWin()

Posted this on CGTalk - got no replies. I guess I’ll have to ask the elite :slight_smile:

Clicking the radio buttons switches the visibility of two frames on/off. But for some reason, the first frame still takes up space (10 px in height) despite setVisible(False).

I tried hiding the label as well with setLabelVisible() but that didn’t change a thing. I’ve also tried setting the marginHeight to 0 but that only affects the elements inside the frame.

Why am I getting extra padding like this?

It has been so long since I wrote any GUI’s using Maya’s original implimentation that I cannot help with your actual question. However I would definitely recommend looking at PySide in the future - the fact that you have a visual editor for the interface layout makes life far easier and makes visual updates far simpler.

Apologies for not giving any direct assistence with your current issue though!