简体   繁体   中英

Tkinter Python: how to pass argument with entry function

I have recently started learning Tkinter. I have created two Entry Widgets called 'Name' and 'Password'. After the user enters his name and password, the program should subsequently list it if the user clicks on 'Submit'. 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'

#/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.

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?

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()
    ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM