[Tutor] Shortening the code
Peter Otten
__peter__ at web.de
Sat Nov 26 13:20:41 CET 2011
Mic wrote:
[Alan Gauld]
> >def create_widgets(self):
> >list_chair=[(0, 0, '01'), (0, 1, '02'),
> (0, 3, '03'), (0, 4, '04'),
> (1, 0, '05')]
> >for row, column, name in list_chair:
> >command = partial(button_clicked, button)
> >button = tk.Button(self, color='green',
> >command=command, text=name)
> >button.grid(row=row, column=column)
[Mic]
> This solution was better than mine since it is possible
> to place the widgets where you want, which I couldn't do.
>
>
> So, using your suggestions I get this:
>
> import tkinter as tk
> from functools import partial
>
> def button_clicked(button):
> if button["bg"] == "green":
> button.configure(bg="red")
> else:
> button.configure(bg="green")
>
> class Window(tk.Frame):
> def __init__(self, master):
> super (Window, self).__init__(master)
> self.grid()
> self.create_widgets()
>
> def create_widgets(self):
> list_chair=[(0, 0, '01'), (0, 1, '02'),
> (0, 3, '03'), (0, 4, '04'),
> (1, 0, '05')]
> for row, column, name in list_chair:
> command = partial(button_clicked, button)
> button = tk.Button(self, color='green',
> command=command, text=name)
> button.grid(row=row, column=column)
>
>
>
>
> root = tk.Tk()
> root.title("Test")
> root.geometry("200x200")
> app = Window(root)
> root.mainloop()
>
> However, nothing happens when I run the program.
Nothing? That's bad. You should see something like
$ python3 tmp.py
Traceback (most recent call last):
File "tmp.py", line 32, in <module>
app = Window(root)
File "tmp.py", line 14, in __init__
self.create_widgets()
File "tmp.py", line 21, in create_widgets
command = partial(button_clicked, button)
UnboundLocalError: local variable 'button' referenced before assignment
Read the last line carefully. At that point in the program flow button is
not yet defined. However, if you just swap the lines
button = tk.Button(self, color='green', command=command, text=name)
command = partial(button_clicked, button)
you'll quickly run into another problem: command is not yet defined when you
create the button. Try it before you read on!
The only way out of the dilemma is to split the task into three steps:
- create the button
- create the callback
- link the callback to the button
button = tk.Button(self, color='green', text=name)
command = partial(button_clicked, button)
button["command"] = command
Now you're almost done. There's still one bug left, but it's an easy one and
after reading the traceback carefully you should be able to fix it yourself.
More information about the Tutor
mailing list