Closing a Tkinter Entry Box in Python - python

I am trying to create a simple popup text entry for the user in which a user enters a text and hits submit (a button). Upon clicking submit, I want the popup entry box to close off and continue on with the rest of the code. Following is a sample code for display that I borrowed from an old post here:
from Tkinter import *
root = Tk()
nameLabel = Label(root, text="Name")
ent = Entry(root, bd=5)
def getName():
print ent.get()
submit = Button(root, text ="Submit", command = getName)
nameLabel.pack()
ent.pack()
submit.pack(side = BOTTOM)
root.mainloop()
print "Rest of the code goes here"
I don't have much experience with Tkinter so I am not sure where and how exactly to call the appropriate functions for closing the entry box after the user hits 'Submit'. My guess is it would have to be inside the getName() function?

If I understand you correctly, then all you need to do is call the root window's destroy method at the end of the getName function:
def getName():
print ent.get()
root.destroy()
Doing so is equivalent to manually clicking the X button in the corner of the window.

Alternate method:
since there isn't much to your popup you could also eliminate several lines of code in your GUI, save some CPU and get pretty much the same output with this:
submitvariablename=raw_input('Please enter a Name')
same functionality and much faster, cleaner.
Just a thought.

Related

Tkinter: Changing a label text

I'm writing a python program with a GUI. For the GUI I use tkinter. In my main window is a button and a label. If the button is pressed I want to change the label and start a request (In the code below, the request is represented as the for loop).
Unfortunally, when trying to change the label on the Button press the API/For-Loop has to finish. After they have finished the label changes it's text.
Example code
def changeText():
global label #This is just an example and is not used in the main programm
label.configure(text="Text Updated")
for i in range(0,10000000): #This should represent the API-Call
print("Doing something different here")
if __name__ == '__main__':
root = tk.Tk()
label = tk.Label(root, text="Text")
button = tk.Button(root,
text="Click to change text below",
command=changeText)
button.pack()
label.pack()
root.mainloop()
I've tried to fix the error by myself but I couldn't. I think it has something to do with the focus of the root window. After I start the API-Call/For-Loop I think the window loses its focus and gains it after the call/loop is finished.
Does somebody know how to change the text of a label, when doing something different (like Api/For) afterwards and could maybe tell me if my guess is right or wrong?

Display user input in Tkinter.Text area

I'm trying to get the user input from an entry box and once a button is pressed, display that in a tk.Text(). The reason I am not doing it in a label is because I'd like the gui looking something like this:
User: Hey
Response: What's up
User: Nothing..
I had a look at this documentation :http://effbot.org/tkinterbook/text.htm
And example uses here but can't get mine to work.
result = None
window = Tk()
def Response():
global result
result = myText.get()
#The below print displays result in console, I'd like that in GUI instead.
#print "User: ", result
#Creating the GUI
myText = tk.StringVar()
window.resizable(False, False)
window.title("Chatbot")
window.geometry('400x400')
User_Input = tk.Entry(window, textvariable=myText, width=50).place(x=20, y=350)
subButton = tk.Button(window, text="Send", command=Response).place(x =350, y=350)
displayText = Text(window, height=20, width=40)
displayText.pack()
displayText.configure(state='disabled')
scroll = Scrollbar(window, command=displayText).pack(side=RIGHT)
window.mainloop()
I have tried variations of;
displayText.insert(window,result) and displayText.insert(End, result)
But still get nothing when I submit the text. The key thing is to obviously keep the last stored text of the User, rather than overwriting it, simply displaying each input underneath each other, I have been advised Text is the best method for this.
UPDATE
Thanks to the comments and answer by Kevin, the user text is now showing in the gui, but when I enter something and click send again, it goes to the side, like this:
HeyHey
rather than :
Hey
Hey
My chatbot is linked to Dialogflow and so in between each user input the chatbot will respond.
as jasonharper indicated in the comments, you need to un-disable your text box before you can add text to it. Additionally, displayText.insert(window,result) is not the correct way to call it. insert's first argument should be an index, not the window object.
Try:
def Response():
#no need to use global here
result = myText.get()
displayText.configure(state='normal')
displayText.insert(END, result)
displayText.configure(state='disabled')
(You may need to do tk.END or tkinter.END instead of just END, depending on how you originally imported tkinter. It's hard to tell since you didn't provide that part of your code)

Tkinter Entry returns float values regardless of input

I have some pretty simple code right now that I am having issues with.
root = Tk()
label1 = Label(root, text ="Enter String:")
userInputString = Entry(root)
label1.pack()
userInputString.pack()
submit = Button(root,text = "Submit", command = root.destroy)
submit.pack(side =BOTTOM)
root.mainloop()
print(userInputString)
When I run the code everything operates as I would expect except
print(userInputString)
for an input asdf in the Entry print will return something like 0.9355325
But it will never be the same value back to back always random.
I am using python 3.5 and Eclipse Neon on a Windows 7 Machine.
Ultimately the goal is to accept a string from the user in the box that pops up and then be able to use that value as string later on. For example, it might be a file path that needs to be modified or opened.
Is Entry not the correct widget I should be using for this? Is there something inherently wrong with the code here? I am new to python and don't have a lot of strong programming experience so I am not even certain that this is set up right to receive a string.
Thanks in advance if anyone has any ideas.
There are two things wrong with your print statement. First, you print the widget, not the text in the widget. print(widget) prints str(widget), which is the tk pathname of the widget. The '.' represents the root window. The integer that follows is a number that tkinter assigned as the name of the widget. In current 3.6, it would instead be 'entry', so you would see ".entry".
Second, you try to print the widget text after you destroy the widget. After root.destroy, the python tkinter wrapper still exists, but the tk widget that it wrapped is gone. The following works on 3.6, Win10.
import tkinter as tk
root = tk.Tk()
label = tk.Label(root, text="Enter String:")
entry = tk.Entry(root)
def print_entry(event=None):
print(entry.get())
entry.bind('<Key-Return>', print_entry)
entry.focus_set()
submit = tk.Button(root, text="Submit", command=print_entry)
label.pack()
entry.pack()
submit.pack()
root.mainloop()
Bonus 1: I set the focus to the entry box so one can start typing without tabbing to the box or clicking on it.
Bonus 2: I bound the key to the submit function so one can submit without using the mouse. Note that the command then requires an 'event' parameter, but it must default to None to use it with the button.
The NMT Reference, which I use constantly, is fairly complete and mostly correct.

How do I prepopulate a text field with suggested text in Tkinter?

I'm trying to prepopulate a text field based on the most recent entry. As this is not a Listbox, I don't see how to do it, and I'm not seeing any examples on the web. Thanks.
Update. I've managed to find a partial way of doing this. Still wondering, is it possible to supply suggested text in Tkinter which fades when the text box is clicked?
from Tkinter import *
app = Tk()
app.title("GUI Example")
app.geometry('560x460+200+200')
x = Text(app)
x.insert(END, "Before")
x.pack()
def replace():
x.delete(1.0, END)
x.insert(END, "After")
abutton = Button(app, text="Click me", command=replace)
abutton.pack()
app.mainloop()
Well, I personally don't know of any options to do this (any answers giving one will easily trump this one).
However, you can closely mimic this behavior with a little coding. Namely, you can bind the textbox to a function that will insert/remove the default text for you.
Below is a simple script to demonstrate:
import Tkinter as tk
tk.Tk()
textbox = tk.Text(height=10, width=10)
textbox.insert(tk.END, "Default")
textbox.pack()
# This is for demonstration purposes
tk.Text(height=10, width=10).pack()
def default(event):
current = textbox.get("1.0", tk.END)
if current == "Default\n":
textbox.delete("1.0", tk.END)
elif current == "\n":
textbox.insert("1.0", "Default")
textbox.bind("<FocusIn>", default)
textbox.bind("<FocusOut>", default)
tk.mainloop()
Notice how:
When you click in the top textbox, the default text disappears.
When you click in the bottom textbox, the top one loses focus and the default text reappears.
This behavior will only occur if there is nothing in the top textbox.

How do I execute a callback when the Enter key is pressed after entering text into a Text widget?

I've really tried to find this out but have only discovered disconnected snippets such as tag_bind. I cannot work out how to use this (if indeed this is the right way forward).
I've got a Text widget into which the user can enter some text (such as a command or question) and I'd like to execute a function that reads that text then responds to it. Obviously I could provide a nearby Button widget which when clicked, reads the text in the Text widget. But I don't want people to have to move their hand from the keyboard to the mouse. I'd just like the callback to be triggered if they hit the Enter key. How do I do it please?
import Tkinter as tk
def on_enter(event):
widget = event.widget
print(widget.get())
root = tk.Tk()
entry = tk.Entry()
entry.pack(padx=5, pady=5)
entry.focus()
entry.bind('<Return>', on_enter)
root.mainloop()

Categories

Resources