Alright! What is a fixed argument?
Its onre that is the same every time the function is called.
The lambda construct above is equivalent to the following which may
make it clearer:
def button_clicked(aButton):
# do something with aButton here
# that uses a lot of code and
# we want to reuse for any button
Now we want to use that function as an event handler, but the function
passed as the command in tkinter is not allowed to take an argument.
So we create a very short function that takes no arguments but calls
button_clicked with a fixed argument. And we do this for two buttons
so that they can both use the button_clicked
def button1_clicked():
> button_clicked(buttonOne)
def button2_clicked():
> button_clicked(buttonTwo)
and we can use these whehn creating our buttons:
buttonOne = Button(parent, command=button1_clicked, ....)
buttonTwo = Button(parent, command=button2_clicked, ....)
Now a shorter way of doing that, which avoids writing lots of these very
small functions is to use lambda, which is an operator that returns a
function as a value.
Thus
def add2(x): return x+2
can be written
add2 = lambda x: x+2
And if we don't really care about the name - which is
true for the button commands we can put lambda directly
into the widget creation:
buttonOne = Button(parent,
command=lambda b=buttonOne: button_clicked(b), ....)
buttonTwo = Button(parent,
command=lambda b=buttonTwo: button_clicked(b), ....)
Note that this works because the lambda defines a default argument for
the command. Thus Tkinter can call the function with no arguments and
Python will insert the default value at runtime.
This was a lot of new information for me so it might take some time for it
to sink in.
Thanks for the information!
While its perfectly legal Python to create a class inside a method its
very unusual in practice and very restricting in the use of the class.
Why is it restricting?
Because the class is only available inside the function. You cannot
create objects of that class anywhere outside the class.
And that is not good because you want to be able to create objects of a
class
outside the class mostly?
Note you are setting text to '01' in every case. Thats probably not what
you want?
No, that is not what I want. The text should be 1 for button one, 2 for
button two and so
on. I managed to solve that, but your solution above seems like a better
alternative to
solving that problem.
def create_widgets(self):
list_chair=[(0, 0), (0, 1), (0, 3), (0, 4), (1,0)]
for row, column in list_chair:
button = tk.Button(self)
command = partial(button_clicked, button)
button["command"] = command
button.grid(row=row, column=column)
command()
As stated above this will result in every chair being green
and having the text '01' It would be better to put the initial colour
and text in your data list and configure each button directly:
Is there any difference between a list and a data list?
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)
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.
This is one of the good habits in programming. Do it step by step. Get
one thing working first before trying to add more features. Its a lot
easier to debug code when you know what you changed to stop it working.
Thanks for the suggestions.
Yes, but lets get the UI all done first, then we can add the button
features.
UI means user interface, right?
You should only ever have one Tk() object in a Tkinter program.
Why is that?
Because thats how Tkinter expects to work! It builds a tree of all the
windows and widgets in your program. If you have two trees in the same
program it can get very confused about which widget is doing what to
which other widgets, especially if they wind up in different trees!.
Alright, I understand. Thanks a lot for the help.
Mic
_______________________________________________
Tutor maillist - [email protected]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor