Reputation: 63
I have created two Entry
widgets called name_entry
and passwd_entry
. After the user enters his name and password, the program should subsequently list it if the user clicks on the Submit button.
Unfortunately this is not working. I'm trying to write it within a class and to pass it as an argument to my submit function.
I receive this error:
File "/usr/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
TypeError: submit() missing 2 required positional arguments: 'var_name' and 'var_passwd'
Code:
#/usr/bin/python3.7
from tkinter import *
class Window (Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
self.master.title("GUI")
self.pack(fill=BOTH, expand=1)
var_name = StringVar()
var_passwd = StringVar()
name = Label(self, text="Name: ")
name.place(x = 0, y = 0)
name_entry = Entry(root, textvariable = var_name)
name_entry.place(x = 90, y =0)
passwd = Label(self, text="Password: ")
passwd.place(x = 0, y = 90)
passwd_entry = Entry(root, textvariable = var_passwd)
passwd_entry.place(x = 90, y = 90)
Knop1 = Button(self, text="Submit", command=self.submit)
Knop1.place(x = 180, y=180)
def submit (self, var_name, var_passwd):
naam = var_name.get()
var_passwd = var_passwd.get()
print("The name is: ", naam)
print("The password is: ", var_passwd)
root = Tk()
root.geometry("500x300")
app = Window(root)
app.mainloop()
Can anyone help me? I'm also looking for a good Tkinter tutorial where OOP is being used.
Upvotes: 1
Views: 1771
Reputation: 385900
As a general rule it's best of the command
of a button calls a function that accepts no arguments. Since you've made a special-purpose function that always operates on the same variables, you can have the directly access the variables.
First, make the variables an attribute of the class:
def init_window(self):
...
self.var_name = StringVar()
self.var_passwd = StringVar()
..
Then, define your function to access those variables:
def submit (self):
naam = self.var_name.get()
var_passwd = self.var_passwd.get()
...
And finally, modify how your button calls this function:
Knop1 = Button(self, text="Submit", command=self.submit)
Note: if you're not using the special properties of a tkinter variable (such as the trace mechanism), you don't need to use StringVar
at all.
Example:
def init_window(self):
...
self.name_entry = Entry(root, textvariable = var_name)
self.passwd_entry = Entry(root, textvariable =var_passwd)
...
def submit (self):
naam = self.name_entry.get()
var_passwd = self.passwd_entry.get()
...
Upvotes: 0
Reputation: 492
You haven't passed the variables to the submit function button. For simple cases like this, you can use a lambda expression as a link between Tkinter and the callback function, otherwise Python will call the callback function before creating the widget: https://effbot.org/zone/tkinter-callbacks.htm
from tkinter import *
class Window (Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
self.master.title("GUI")
self.pack(fill=BOTH, expand=1)
var_name = StringVar()
var_passwd = StringVar()
name = Label(self, text="Name: ")
name.place(x = 0, y = 0)
name_entry = Entry(root, textvariable = var_name)
name_entry.place(x = 90, y =0)
passwd = Label(self, text="Password: ")
passwd.place(x = 0, y = 90)
passwd_entry = Entry(root, textvariable =var_passwd)
passwd_entry.place(x = 90, y = 90)
# Changed this line
Knop1 = Button(self, text="Submit", command=lambda: self.submit(var_name, var_passwd))
Knop1.place(x = 180, y=180)
def submit (self, var_name, var_passwd):
naam = var_name.get()
var_passwd = var_passwd.get()
print("The name is: ", naam)
print("The password is: ", var_passwd)
root = Tk()
root.geometry("500x300")
app = Window(root)
app.mainloop()
To address your question about OOP with tkinter, this question has some good advice: Best way to structure a tkinter application?
Upvotes: 1