Python Forum

Full Version: Setting interdependencies between checkboxes
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Aim is to show the user that he shouldn't check some items if he already has chosen others.
(He should be able to do so, just get a hint, maybe even a warning.)

But how to do that?
My first idea was to couple a CheckListBox with a Tree-State-Checkbox. However, it seems to be impossible to set a CheckBox in a CheckListBox into the "third state" by code. (One can do so for simple CheckBoxes, but not if they are part of a list, as one cannot pass the index of the item in question.)

It's not that a third state would be mandatory; if I could 'grey out' the item strings, that would do the same thing (carrying some information to the user). But I found no way to influnce those strings, the only way would then be to destroy the CheckListBox completely and make a new one (and even then I'm not sure whether I could influence the text color, but I didn't check for that until now).

So, I changed to ListBoxes that are created due to a list.

But now I met the problem that I need something to 'adress' the single boxes, indicated in the code here by '***'. (The code cannot work in this version, of course.)

# -*- coding: cp1252 -*-

import wx

tliste = ["a", "b", "c", "d"]
states = {}

class Mainframe(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)

        self.mainbox = mainbox = wx.BoxSizer(wx.VERTICAL) 
        
        for tafn in tliste:
            choname = "cho" + tafn
            states[choname] = {"st": "", "afn": tafn}
            self.*** = wx.CheckBox(self, wx.ID_ANY,
                    label = tafn,
                    style = wx.CHK_3STATE|wx.CHK_ALLOW_3RD_STATE_FOR_USER)
        
            self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox, self.***)

            mainbox.Add(self.***)
            
        self.SetSizer(mainbox)

        self.Show()

    def EvtCheckBox(self, event):
        for chon in states.keys():
            chosenind = self.***.Get3StateValue()
            print "chosenind of ", chon, ": ", chosenind
            
if __name__ == "__main__": 

    app = wx.App(0)
    preframe = Mainframe(None, -1, "Anfangsauswahl")   
    app.MainLoop() 
Is there any possibility to create some identifier in such a case? Or are there other options to change the behavior of CheckBoxes depending on what other CheckBoxes are set to a given state?
I think this could be what you are looking for, keep the checkbox controls in a list as shown below.
# -*- coding: cp1252 -*-

import wx

tliste = ["a", "b", "c", "d"]
# states = {}


class Mainframe(wx.Frame):

   def __init__(self, parent, id, title):
       wx.Frame.__init__(self, parent, id, title)

       self.mainbox = mainbox = wx.BoxSizer(wx.VERTICAL)
       self.checkboxes = []

       for tafn in tliste:
           #             choname = "cho" + tafn
           #             states[choname] = {"st": "", "afn": tafn}
           checkbox = wx.CheckBox(
               self, wx.ID_ANY, label=tafn,
               style=wx.CHK_3STATE | wx.CHK_ALLOW_3RD_STATE_FOR_USER)

           self.Bind(wx.EVT_CHECKBOX, self.on_evt_checkbox, checkbox)

           mainbox.Add(checkbox)
           self.checkboxes.append(checkbox)

       self.SetSizer(mainbox)

       self.Show()

   def on_evt_checkbox(self, event):
       for checkbox, chon in zip(self.checkboxes, tliste):
           chosenind = checkbox.Get3StateValue()
           print "chosenind of {0}: {1}".format(chon, chosenind)

if __name__ == "__main__":

   app = wx.App(0)
   preframe = Mainframe(None, -1, "Anfangsauswahl")
   app.MainLoop()
That works perfectly  Smile !

Thanks a lot!