Spacey
Spacey

Reputation: 223

How do you get user choices from a Pymel LayoutDialog?

The following code is taken from the Pymel docs here: https://help.autodesk.com/cloudhelp/2020/ENU/Maya-Tech-Docs/PyMel/generated/functions/pymel.core.windows/pymel.core.windows.layoutDialog.html

Although the example is called checkboxPrompt it doesn't show how the state of the checkbox can be retrieved. The pm.layoutDialog function only returns the choice of button used to dismiss the dialog. The MEL and Maya.cmds docs for the same command don't explain this either. So how is it done?

 
import pymel.core as pm

def checkboxPrompt():
    # Get the dialog's formLayout.
    #
    form = pm.setParent(q=True)

    # layoutDialog's are not resizable, so hard code a size here,
    # to make sure all UI elements are visible.
    #
    pm.formLayout(form, e=True, width=300)

    t = pm.text(l='What do you want to do?')

    b1 = pm.button(l='Abort', c='pm.layoutDialog( dismiss="Abort" )' )
    b2 = pm.button(l='Skip', c='pm.layoutDialog( dismiss="Skip" )' )
    b3 = pm.button(l='Continue', c='pm.layoutDialog( dismiss="Continue" )' )

    cb1 = pm.checkBox(label='Remember my choice')

    spacer = 5
    top = 5
    edge = 5

    pm.formLayout(form, edit=True,
                  attachForm=[(t, 'top', top), (t, 'left', edge), (t, 'right', edge), (b1, 'left', edge), (b3, 'right', edge), (cb1, 'left', edge), (cb1, 'bottom', spacer)],
                  attachNone=[(t, 'bottom'), (b1, 'bottom'), (b2, 'bottom'), (b3, 'bottom'), (cb1, 'right')],
                  attachControl=[(b1, 'top', spacer, t), (b2, 'top', spacer, t), (b3, 'top', spacer, t), (cb1, 'top', spacer, b1)],
                  attachPosition=[(b1, 'right', spacer, 33), (b2, 'left', spacer, 33), (b2, 'right', spacer, 66), (b3, 'left', spacer, 66)])

print pm.layoutDialog(ui=checkboxPrompt)

Upvotes: 1

Views: 361

Answers (1)

Ben Souchet
Ben Souchet

Reputation: 1532

Lot of the time the documentation skip lot of elements to maintain a certain simplicity but because of this we often find ourselves without the solution and/or with very basic examples.

In your case, there is multiple way to get the checkbox value, you can for example:

  • Add a callback on the checkbox with parameters changeCommand or onCommand / offCommand to update a python global variable you created earlier on your code.
  • A simpler way is to set lambda functions to the command parameter (instead of a string) to retrieve the checkbox value and set the proper dismiss value.

Here is the code for the second methods I talk above:

import pymel.core as pm

def checkboxPrompt():
    # Get the dialog's formLayout.
    form = pm.setParent(q=True)
    
    # Function method to query the value of the checkbox
    def getRememberMyChoice(checkbox_id):
        if pm.checkBox(checkbox_id, query=True, value=True):
            return ':Yes'
        return ':No'

    # layoutDialog's are not resizable, so hard code a size here,
    # to make sure all UI elements are visible.
    pm.formLayout(form, e=True, width=300)

    t = pm.text(l='What do you want to do?')

    b1 = pm.button(l='Abort', c=lambda *args: pm.layoutDialog( dismiss="Abort"+getRememberMyChoice(checkbox1) ) )
    b2 = pm.button(l='Skip', c=lambda *args: pm.layoutDialog( dismiss="Skip"+getRememberMyChoice(checkbox1) ) )
    b3 = pm.button(l='Continue', c=lambda *args: pm.layoutDialog( dismiss="Continue"+getRememberMyChoice(checkbox1) ) )
 
    checkbox1 = pm.checkBox(label='Remember my choice')

    spacer = 5
    top = 5
    edge = 5

    pm.formLayout(form, edit=True,
                  attachForm=[(t, 'top', top), (t, 'left', edge), (t, 'right', edge), (b1, 'left', edge), (b3, 'right', edge), (checkbox1, 'left', edge), (checkbox1, 'bottom', spacer)],
                  attachNone=[(t, 'bottom'), (b1, 'bottom'), (b2, 'bottom'), (b3, 'bottom'), (checkbox1, 'right')],
                  attachControl=[(b1, 'top', spacer, t), (b2, 'top', spacer, t), (b3, 'top', spacer, t), (checkbox1, 'top', spacer, b1)],
                  attachPosition=[(b1, 'right', spacer, 33), (b2, 'left', spacer, 33), (b2, 'right', spacer, 66), (b3, 'left', spacer, 66)])

print (pm.layoutDialog(ui=checkboxPrompt))

Executing the code, (check or not the checkbox) then closing by clicking one of the button will print you this:

# First word ("Continue") depends on the button you clicked
# Yes or No (after the ":") is the state of the "Remember my choice" checkbox 
Continue:Yes

Upvotes: 1

Related Questions