Convoluted question

Kirby Urner urner at alumni.princeton.edu
Tue Aug 1 14:54:51 EDT 2000


>I think this comes from the fact that I didn't define the names in varlist
>as variables.  It seems to me that there should be an easy way to assign
>variable names for each check button in an automated way, and an easy way to
>return the status of a check button.  I haven't found either after almost a
>full day of coding and poring over different texts, such as 'Python
>Essential Reference' and 'Python and Tkinter Programming'.  Is what I want
>possible, or do I have to use what seems to me to be a more 'brute force'
>method?
>
>TIA
>
>- Mark

Hi Mark --

Yes, agreed.  As per page 108 of the 'Python and Tkinter' book,
you need to use a subclass of Tkinter's variable class for 
passing to Checkbutton (you can see these subclasses by popping
open the Tkinter.py module).

You may not want to name each of your variables (extra overhead?), 
which, in the case of checkboxes, might be BooleanVar().  Just
stick the variables in an array and consult them by index.  

E.g. you could just have your loop go:

   self.vars = [None]*len(servers)    # initialize list
   for num in range(len(servers)):
       s = servers[num]
       self.vars[num] = BooleanVar()  # populate list with variables
       b = Checkbutton(self.frame, text=s, variable=self.vars[num])

Here's a somewhat over-elaborate example, obtained by tweaking 
SimpleDialog in Lib\lib-tk\.

Output (in response to checkbox checks, and upon hitting Quit
in child window):

 >>> SimpleChecks.test()
 [0, 1, 1]
 [1, 0, 1]
 [0, 1, 0]

Code:  SimpleChecks.py


from Tkinter import *

class SimpleChecks:

    def __init__(self, master,
                 text='', servers=[], title=None):
        self.root = Toplevel(master)
        if title:
            self.root.title(title)
            self.root.iconname(title)
        self.message = Message(self.root, text=text, aspect=400)
        self.message.pack(expand=1, fill=BOTH)
        self.frame = Frame(self.root)
        self.frame.pack()
        self.root.bind('<Return>', self.return_event)
        self.vars = [0]*len(servers)

        for num in range(len(servers)):
            s = servers[num]
            self.vars[num] = BooleanVar()
            b = Checkbutton(self.frame, text=s, variable=self.vars[num])
            b.pack(side=LEFT, fill=BOTH, expand=1)

        b = Button(self.frame, text="Quit", 
                   command=(lambda self=self: self.done()))
        b.pack(side=LEFT,fill=BOTH,expand=1)           
        self.root.protocol('WM_DELETE_WINDOW', self.wm_delete_window)

    def go(self):
        self.root.grab_set()
        self.root.mainloop()
        self.root.destroy()
        return self.values
        
    def done(self):
        self.values = []
        for i in self.vars:
            self.values.append(i.get())
        self.root.quit()

    def return_event(self, event):
        self.done()

    def wm_delete_window(self):
        self.done()


def test():
    root = Tk()
    def doit(root=root):
        d = SimpleChecks(root,
                      text="This is only a test. \n",
                      servers=["Server0", "Server1", "Server2"],
                      title="Servers")
        print d.go()
    t = Button(root, text='Test', command=doit)
    t.pack()
    q = Button(root, text='Quit', command=t.quit)
    q.pack()
    t.mainloop()




More information about the Python-list mailing list