Search code examples
pythontkinter

Tkinter input taken after enter key pressed


I'm new to tkinter as I usually work in C. I wrote a simple code in tkinter, and I'd like to make it so on this snippet the input is stored in the variable name after the enter key is pressed, and that the input box disapears (probably using destroy.()).

import tkinter as tk
from tkinter import *

root = tk.Tk()
root.title = 'Shit game v1.0'
root.geometry('600x400+50+50')

label = tk.Label(text = "Name?: " ,foreground = "green", background = "black")
entry = tk.Entry(root, fg="green", bg="black", width=50)
label.pack()
entry.pack()

#name = entry.get()


# place a label on the root window
message = tk.Label(root, text=
 "What is your name?",
foreground = "green",
background = "black",
width = 1000,
height = 1000)

message.pack()

if entry == True:
    name = entry.get()
    message2 = tk.Label(root, text=
    f"Welcome {name}! Let's begin!",
    foreground = "green",
    background = "black",
    width = 1000,
    height = 1000)

    message2.pack()





root.mainloop()

I tried:

def get_name(event):
    name = entry.get()
if entry == True:
    name = entry.get()
    message2 = tk.Label(root, text=
    f"Welcome {name}! Let's begin!",
    foreground = "green",
    background = "black",
    width = 1000,
    height = 1000)

    message2.pack()

entry.bind('<Return>', get_name)


Solution

  • You can accomplish this with a pretty minimal setup like so (note that I've removed some of the styling to keep things simpler)

    import tkinter as tk
    
    
    root = tk.Tk()
    root.title = 'Shit game v1.0'
    root.geometry('600x400+50+50')
    
    msg_label = tk.Label(root, text='What is your name?')  # create a label
    msg_label.pack()  # add the label to the UI
    
    name_entry = tk.Entry(root)  # create an Entry to accept user input
    name_entry.bind(  # bind the enter key shortcut
        '<Return>',
        lambda _: [  # you can call a sequence of functions w/ a lambda like this...
            # update the label's text
            msg_label.config(text=f"Welcome {name_entry.get()}, let's begin!"),
            # remove the Entry widget
            name_entry.pack_forget()
        ]
    )
    name_entry.pack()  # add the Entry to the UI
    
    root.mainloop()
    

    As Bryan Oakley has pointed out, it's usually better practice to define functions for more complex tasks, rather than adding a bunch of things to a single lambda, so here's how to accomplish this using that approach:

    import tkinter as tk
    
    
    def accept_name() -> None:
        """
        Collect the user's name, update the message label, 
        and hide the name entry widget
        """
        # update the label's text
        msg_label.config(text=f"Welcome {name_entry.get()}, let's begin!"),
        # remove the Entry widget
        name_entry.pack_forget()
    
    
    root = tk.Tk()
    root.title = 'Shit game v1.0'
    root.geometry('600x400+50+50')
    
    msg_label = tk.Label(root, text='What is your name?')  # create a label
    msg_label.pack()  # add the label to the UI
    
    name_entry = tk.Entry(root)  # create an Entry to accept user input
    # bind the enter key shortcut
    name_entry.bind('<Return>', lambda _: accept_name())
    name_entry.pack()  # add the Entry to the UI
    
    root.mainloop()
    

    Also, it's worth noting that the lambda now only serves to absorb the event parameter generated by the binding to '<Return>' (represented by the underscore _). You can do this instead:

    name_entry.bind('<Return>', accept_name)
    

    ...if you update the definition of accept_name to accept the incoming argument (even if you aren't going to use it)

    def accept_name(_event=None) -> None: ...