The entry value is just simply doesn’t get passed into the function, whatever I do.
class Registration(tk.Frame): def __init__(self, parent, controller): name_var = tk.StringVar() name_entry = ttk.Entry(self, textvariable=name_var) name_entry.grid(row=1, column=1) button1 = ttk.Button(self, text="Registration", command=self.RegFunction(name_var.get())) button1.grid(row=4, column=4) def RegFunction(self, name) print(name)
Edit:
I just realized, if I add a variable to the function, it gets called as soon as I run the program, and it doesn’t care about the button; but if I don’t give it a variable, it works as it should, only when I push the button.
Here is the whole code
import tkinter as tk from tkinter import ttk class ToDoList(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) container = tk.Frame(self) container.pack(side="top", fill="both", expand=True) container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) self.frames = {} for F in (LogIn, Registration): frame = F(container, self) self.frames[F] = frame frame.grid(row=0, column=0, sticky="nsew") self.show_frame(LogIn) def show_frame(self, cont): frame = self.frames[cont] frame.tkraise() class LogIn(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) # label of frame Layout 2 label = ttk.Label(self, text="Log In") label.grid(row=0, column=4, padx=10, pady=10) username_label = ttk.Label(self, text="Username :") username_label.grid(row=1, column=1) password_label = ttk.Label(self, text="Password:") password_label.grid(row=2, column=1) usrname_entry = ttk.Entry(self) usrname_entry.grid(row=1, column=2) password_entry = ttk.Entry(self) password_entry.grid(row=2, column=2) button2 = ttk.Button(self, text="Registration", command=lambda: controller.show_frame(Registration)) button2.grid(row=4, column=1, padx=10, pady=10) class Registration(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) label = ttk.Label(self, text="Registration") label.grid(row=0, column=4, padx=10, pady=10) name_label = ttk.Label(self, text="Username:") name_label.grid(row=1, column=0) pass1_label = ttk.Label(self, text="Password:") pass1_label.grid(row=2, column=0) pass2_label = ttk.Label(self, text="Password again:") pass2_label.grid(row=3, column=0) name_var = tk.StringVar() name_entry = ttk.Entry(self, textvariable=name_var) name_entry.grid(row=1, column=1) pass1_entry = ttk.Entry(self) pass1_entry.grid(row=2, column=1) pass2_entry = ttk.Entry(self) pass2_entry.grid(row=3, column=1) k = 12 button1 = ttk.Button(self, text="Registration", command=self.RegFunction(k)) button1.grid(row=4, column=4, padx=10, pady=10) button2 = ttk.Button(self, text="Back to Login", command=lambda: controller.show_frame(LogIn)) button2.grid(row=4, column=0, padx=10, pady=10) def RegFunction(self, x): print("Something", x) app = ToDoList() app.mainloop()
Advertisement
Answer
There’s a difference between calling a function and passing in a function’s name so it can be called later on. The ttk.Button
command=
expects a function name (or reference) to be passed in, so that the named or referenced function can be called later. You are calling the function rather than passing in its name, so things go awry.
Change:
button1 = ttk.Button(self, text="Registration", command=self.RegFunction(name_var.get()))
to:
button1 = ttk.Button(self, text="Registration", command=lambda: self.RegFunction(name_var.get()))
and you’ll be closer to your goal. The lambda
tells Python not to call the function but rather just return a reference to it that can be used to call it later.
Once you do that, you’ll see that you have a typo in your function definition — you’re missing a colon at the end of the def
statement. So, change:
def RegFunction(self, name)
to:
def RegFunction(self, name): # colon added at end