[Tutor] how to "forget" some checkbuttons on a window
Chris Roy-Smith
chris_roysmith at internode.on.net
Tue May 19 04:53:33 EDT 2020
On 19/5/20 5:52 pm, Alan Gauld via Tutor wrote:
> On 19/05/2020 06:20, Chris Roy-Smith wrote:
>> I am trying to hide some Checkbuttons.
>
> Do you actually want them to become invisible?
> Or just to disable them(grey them out?)
> Most GUIS don;t hide controls they just disable them.
> A changing interface is confusing to users.
Hi Alan, Thank you for your assistance, I was thinking that as these
items would not be of any interest to whoever uses this code once it's
been checked off. Therefore I didn't consider just greying out. The data
in the query behind this routine will not be available once the item is
checked off anyway.
>
>> from tkinter import *
>> testDat=[0,1,2,3,4,5,6,7,8,9]
>> def remove(e):
>> for i in range(9):
>> r=var[i].get()
>> if r==True:
>> e[i].forget()
>
> Notice no return value here so remove() always returns none.
>
>> master=Tk()
>> master.title('experiment')
>>
>> e=[" " for i in range(len(testDat))]
>
> You could just do:
>
> e = [" "] * 10
>
> But given your code below thre is no point since
> you just overwrite the values. You might as well
> use an empty list and append the controls below.
>
>> var=[IntVar() for i in range(len(testDat))]
>> for i in range(len(testDat)):
>> e[i]=Checkbutton(master, text=str(i), variable=var[i],
>> onvalue=True, offvalue=False).grid(row=i, column=0)
>
> You could have created the IntVar here as well
> which would save a little bit of time since
> you'd only have one loop..
>
>
> But, you've fallen into one of the classic traps of Tkinter
> programming.
> You are storing the return value from grid() Which is None.
> You must create and store the control then grid it.
As I said to Peter Otten, I have been caught by this before, but the
person who showed me the flaw in my code didn't explain why there was a
need to separate the grid method from the widget creation. Am I better
off always keeping the two separate? The OLD python (python 2.6!) text I
have been using didn't discuss this at all.
> Rewriting your code above:
>
> var = []
> for i in testDat: # no need for range
> var.append(IntVar())
> e.append(Checkbutton(master, text = str(i),variable = var[-1],
> onvalue = true, offvalue=False))
> e[-1].grid(row=i,column=0)
Is appending preferred to creating lists and lists of lists, if so I'll
try that out in what I have previously done in other projects.
>
>> Button(master, text='remove checked', command=lambda i=e:
>> remove(i)).grid(row=11, column=0)
>
> And here you use grid on the return value of remove, but remove has no
> return value so again you get a none as default.
Knowing why makes things much clearer to me.
>
>> File "./frames.py", line 8, in remove
>> e[i].forget()
>> AttributeError: 'NoneType' object has no attribute 'forget'
>
> NoneType because of the premature grid() call above.
>
>
More information about the Tutor
mailing list