CheckBox - Disable other checkbox when a checkbox is checked

Say, I have 2 checkBoxes…
How do I create a function such that when Maya cmds.checkBox1 is checked, cmds.checkBox2 and vice-verse, as long only one checkBox is checked and not both?
I tried to hardcode it, but it does not seems to be working. In my code below, when I checked chk1, chk2 is still enabled and checkable…

import maya.cmds as cmds

def test1(self, *args):
   print "User checked option1"
   cmds.checkBox(chk2, query = True, value = True, enable = False)
    
def test2(self, *args):
    print "User checked option2"

w = cmds.window(w=150, h=100, title = "Export Selection" )
cmds.columnLayout( adjustableColumn=True )
form = cmds.formLayout(numberOfDivisions=100)
chk1 = cmds.checkBox( label='option1', onc = test1 )
chk2 = cmds.checkBox( label='option2', onc = test2 )


cmds.formLayout(form, edit=True, attachForm=[\
(chk1, 'top', 15),\
(chk1, 'left', 15),\
(chk2, 'top', 30),\
(chk2, 'left', 15)])

cmds.showWindow( window )

I have found out my mistakes in my original coding…

Still I am wondering if there is a way for me to compile all these 4 functions in one function, if possible? It is still pretty much hardcoded.

Looking forward to hear from you all soon and thanks in advance

def test1On(*args):
   print "User checked option1"
   cmds.checkBox(chk2, edit = True, enable = False)
   
def test1Off(*args):
    print "User un-checked option1"
    cmds.checkBox(chk2, edit = True, enable = True)
    
def test2On(*args):
    print "User checked option2"
    cmds.checkBox(chk1, edit = True, enable = False)

def test2Off(*args):
    print "User un-checked option2"
    cmds.checkBox(chk1, edit = True, enable = True)

Wouldn’t the use of a radio buttons control be the proper choice in this case? Checkboxes, from a UI/UX view, are to allow the user to make one or more choices from the items provided. Radio buttons are for making a single selection from a list of choices. The radio button control itself handles the selection/deselection based on user input to enforce the mutual exclusivity of the choices. While you’ve successfully made multiple checkboxes mimic radio buttons your UI may be confusing to users now - given that they have ingrained expectations on how checkboxes traditionally work. Not only that, but your code would be less complex (to a degree) since a single radio button event handler would cover all cases.

[QUOTE=Jeff Hanna;25852]Wouldn’t the use of a radio buttons control be the proper choice in this case? Checkboxes, from a UI/UX view, are to allow the user to make one or more choices from the items provided. Radio buttons are for making a single selection from a list of choices. The radio button control itself handles the selection/deselection based on user input to enforce the mutual exclusivity of the choices. While you’ve successfully made multiple checkboxes mimic radio buttons your UI may be confusing to users now - given that they have ingrained expectations on how checkboxes traditionally work. Not only that, but your code would be less complex (to a degree) since a single radio button event handler would cover all cases.[/QUOTE]

Hi Jeff, thanks for the advice. I shall try out the radioButton method. Just wondering if you could spare me a few more advices?

Basically this radio button is to capture the selection information - the translation (transX and transY) information for example and it is being depicted within a class. And it would only be captured once the user have clicked on this ‘Confirm’ button…
However, I would need these captured information to be used in another class function.

Is there a better way for me to do so, other than declaring it as global variables?

You could pass the information in via the class constructor if you contruct the other object from your ui object.

Or if its a lot of information you can do the same but pass in the reference for your whole ui object.

[QUOTE=passerby;25866]You could pass the information in via the class constructor if you contruct the other object from your ui object.

Or if its a lot of information you can do the same but pass in the reference for your whole ui object.[/QUOTE]

Hi passerby, just wondering if you mean it in this manner:

  1. Define a class variable - self.variable = [ ], in the first class function
  2. Append any information into this self.variable
  3. If I need to use the information of this self.variable, I will just place it in the second class function?

I think there’s really two things going on in this discussion

  1. Jeff’s right that radio buttons are the correct UI element for mutually exclusive choices. A RadioCollection with a bunch of radioButtons will automatically ensure that only one option from a mutually exclusive group is selected at any time

  2. You can and should share a callback between multiple items. Maya changes the values in widgets before the event is fired, so you can safely poll the values for controls without having a unique callback per item. Maya is pretty inconsistent in the way it uses arguments in callbacks, so you probably will not get the info you need from the callback for free, however you can use a partial or a lambda to add extra data to the call - something you new at GUI creation time which is helpful at runtime.

Here’s a very minimal example



from functools import partial 

class Example():
    def __init__(self):
        self.window = cmds.window(title='example')
        c = cmds.columnLayout()
        self.radios = cmds.radioCollection()   # this handles exclusivity for you
        self.texts = {}                                # this connects radio keys to other gui items
        for item in ("one", "two", "three"):
            cmds.radioButton(item, label = item, cc = partial(self.update_enable, item))     # using a partial instead of lambda because lambda's don't like loops!     
            self.texts[item] =  cmds.textField(item, en = False)
        cmds.showWindow(self.window)
        cmds.radioCollection(self.radios, e=True, sl="one") # force the callback to fire once
        
    def update_enable(self, selected, _):
        for k, v in self.texts.items():   # use the dict to enable the selected and disable all others
            cmds.textField(v, e=True, en = (k == selected))
            
Example()