[Tutor] Tkinter class question
Peter Otten
__peter__ at web.de
Sat Apr 8 03:12:17 EDT 2017
Phil wrote:
> I've progressed a little further but I'm now having a problem knowing when
> to use the "self" reference. In the following code, the function "ckeck"
> is called without the need to press the "check" button. This didn't occur
> before I sprinkled "selfs" into the code and added "array" to the "ckeck"
> function. I found that I needed "self" to point "array" to my list array
> "e" and I think that is where the fault is.
>
> from tkinter import *
>
> class TestGUI:
> def __init__(self, master):
<...>
> self.check_button = Button(master, text="Check",
> command=self.check(self.e))
Think hard about what the expression
command=self.check(self.e)
does. Spoiler:
The check() method is invoked, and the result is passed as the command
argument. But what is that result?
> def check(self, array):
> print("checked")
> array[2][2].insert(0, "4")
No explicit return means the return value is None. Your above code is
equivalent to
# print "checked" and insert "4"
self.check(self.e)
# create a button with no command
self.check_button = Button(master, text="Check", command=None)
To set a command you must define a function or method that takes no
arguments:
class TestGUI:
def check_2_2(self):
print("checked"
self.e[2][2].insert(0, "4")
def __init__(self, master):
...
self.check_button = Button(
master,
text="Check",
command=self.check_2_2 # note there's no () -- the bound method
# is not invoked
)
...
> root = Tk()
> my_gui = TestGUI(root)
> root.mainloop()
If there are a lot of similar commands the command is often constructed by
wrapping a method in a lambda with default arguments. Simple example:
import tkinter as tk
class TestGUI:
def __init__(self, master):
for i in range(5):
button = tk.Button(
master,
text="Button {}".format(i),
command=lambda n=i: self.button_pressed(n)
)
button.grid(row=i, column=0)
def button_pressed(self, n):
print("You pressed button {}".format(n))
root = tk.Tk()
test = TestGUI(root)
root.mainloop()
There's also functools.partial() which can be used to the same effect
command=functools.partial(self.button_pressed, i)
More information about the Tutor
mailing list