I'm trying to use Tkinter's Entry widget. I can't get it to do something very basic: return the entered value. Does anyone have any idea why such a simple script would not return anything? I've tried tons of combinations and looked at different ideas.
This script runs but does not print the entry:
from Tkinter import *
root = Tk()
E1 = Entry(root)
E1.pack()
entry = E1.get()
root.mainloop()
print "Entered text:", entry
Seems so simple.
Edit
In case anyone else comes across this problem and doesn't understand, here is what ended up working for me. I added a button to the entry window. The button's command closes the window and does the get() function:
from Tkinter import *
def close_window():
global entry
entry = E.get()
root.destroy()
root = Tk()
E = tk.Entry(root)
E.pack(anchor = CENTER)
B = Button(root, text = "OK", command = close_window)
B.pack(anchor = S)
root.mainloop()
And that returned the desired value.
Your first problem is that the call to get in entry = E1.get() happens even before your program starts, so clearly entry will point to some empty string.
Your eventual second problem is that the text would anyhow be printed only after the mainloop finishes, i.e. you close the tkinter application.
If you want to print the contents of your Entry widget while your program is running, you need to schedule a callback. For example, you can listen to the pressing of the <Return> key as follows
import Tkinter as tk
def on_change(e):
print e.widget.get()
root = tk.Tk()
e = tk.Entry(root)
e.pack()
# Calling on_change when you press the return key
e.bind("<Return>", on_change)
root.mainloop()
from tkinter import *
import tkinter as tk
root =tk.Tk()
mystring =tk.StringVar(root)
def getvalue():
print(mystring.get())
e1 = Entry(root,textvariable = mystring,width=100,fg="blue",bd=3,selectbackground='violet').pack()
button1 = tk.Button(root,
text='Submit',
fg='White',
bg= 'dark green',height = 1, width = 10,command=getvalue).pack()
root.mainloop()
Related
I am writing a python program which executes the following sequence:
1. Dialog box to open/select a directory
2. perform certain operations
3. rename the file using a tkinter dialog box
4. Perform rest of the operations
I have written the following code:
def open_directory():
directory_name = filedialog.askdirectory(title='Ordner Auswählen',parent=root)
print(directory_name)
root.destroy()
def input_name():
def callback():
print(e.get())
root.quit()
e = ttk.Entry(root)
NORM_FONT = ("Helvetica", 10)
label = ttk.Label(root,text='Enter the name of the ROI', font=NORM_FONT)
label.pack(side="top", fill="x", pady=10)
e.pack(side = 'top',padx = 10, pady = 10)
e.focus_set()
b = ttk.Button(root, text = "OK", width = 10, command = callback)
b.pack()
def close_window():
root.destory()
root = tk.Tk()
root.withdraw()
open_directory() #dialogue box to select directory
<perform certain operations>
input_name() #dialgue box for user input file name
root.mainloop()
close_window() #exit the mainloop of tkinter
<perform rest of the functions>
but I get the following error
Tclerror: NULL main window
I think it is realted to declaring root as the main window, but I dont seem to find where I have made the mistake.
Is there some other method, which is better, for what I am trying to do here?
As #CommonSense has mentioned, when you use withdraw to hide the main window, then you need to use the method deiconify to use the root again. Hence, change the function change_directory as follows:
def open_directory():
directory_name = filedialog.askdirectory(title='Ordner Auswählen',parent=root)
print(directory_name)
root.deiconify()
If you do not deiconify the window, you could not call the function input_name, which makes use of the root window.
I have tested this code and it works.
PS: You also have a typo in the function close_window (when destroying the window).
Your use of .destroy() and .quit() as #CommonSense truly said do not really seem well planned.
Not only that, you need to use triggers or events to control your function calls, else they just run straight the one preventing the other from running as is the case in your code.
You should also control when close_window() is called with an event:
from tkinter import filedialog
import tkinter as tk
def open_directory():
directory_name = filedialog.askdirectory(title='Ordner Auswählen',parent=root)
print(directory_name)
#root.destroy()
input_name()
def input_name():
def callback():
print(e.get())
#root.quit()
es_variable=tk.StringVar()
e = tk.Entry(root, textvariable=es_variable)
NORM_FONT = ("Helvetica", 10)
label = tk.Label(root,text='Enter the name of the ROI', font=NORM_FONT)
label.pack(side="top", fill="x", pady=10)
e.pack(side = 'top',padx = 10, pady = 10)
e.focus_set()
b = tk.Button(root, text = "OK", width = 10, command = callback)
b.pack()
def close_window():
root.destory()
root = tk.Tk()
#root.withdraw()
open_dir_button = tk.Button(root, text = "Open Dialog", width = 10, command =open_directory)
open_dir_button.pack()
#dialogue box to select directory
#<perform certain operations>
#dialgue box for user input file name
root.mainloop()
#close_window() #exit the mainloop of tkinter
#<perform rest of the functions>
My function is not returning any value which i entered into entry-box on button click:
from tkinter import *
import os
def onclick2():
val = box.get()
return(val)
root = Tk()
box = Entry(root)
box.pack()
buttonfortxtbox = Button(root, text="Check Result", font=('Cooper Black', 9), bd=10, width=20,command=onclick2)
buttonfortxtbox.pack(anchor = S)
print(onclick2())
root.mainloop()
Nothing is wrong with your code. But your understanding is not exact:
When you run this line: print(onclick2()) you are trying to print the content of the entry widget which is empty when the program first starts. So that is perfectly normal you are not getting anything visible on the Terminal.
To see the content of the entry widget, modify slightly your callback as follows:
def onclick2():
val = box.get()
print(val)
# You can remove "return val" as it is completely useless for your context
With this simple change, you will see None printed on the Terminal, which thing corresponds to what I described above. Now type something within the entry widget and click on the button: what you type appears finally on the output (Terminal).
You are trying to print the content of your entry widget but you are using the variable for your entry to receive the content which is wrong. Also call print the content in your entry widget to the your terminal .
from tkinter import *
def onclick2():
val = boss.get()
print(val)
root = Tk()
boss = StringVar() # to receive the content in the entry
box = Entry(root , textvariable=boss)
box.pack()
buttonfortxtbox = Button(root, text="Check Result", font=('Cooper Black',
9), bd=10, width=20,command=onclick2)
buttonfortxtbox.pack(anchor = S)
#print(onclick2()) # don't need to call this
root.mainloop()
So my first GUI window is meant for taking input from user :
from tkinter import *
from main import *
root = Tk()
root.configure(background="orange")
root.wm_title("Python Project")
label_1 = Label(root, text="Project Name",bg="orange",fg="black")
label_2 = Label(root, text="Site URL Link",bg="orange",fg="black")
entry_1 = Entry(root)
entry_2 = Entry(root)
label_1.grid(row=0,sticky=W)
label_2.grid(row=3333,sticky=W)
entry_1.grid(row=0,column=1,padx=50,ipadx=100)
entry_2.grid(row=3333,column=1,ipadx=100)
def callback():
a1 = entry_1.get()
a2 = entry_2.get()
mmm(a1,a2,root) # main program
button1 = Button(root,text="Run",command=callback)
button2=Button(root,text="Quit",command=root.quit)
button1.grid(row=3334,ipadx=15,padx=50,column=1)
button2.grid(row=3335,column=1,ipadx=15,padx=50)
root.mainloop()
And then i use another GUI window someone in this forum made to show my results :
from tkinter import *
root = Tk()
textbox = Text(root)
textbox.pack()
def redirector(inputStr):
textbox.insert(INSERT, inputStr)
sys.stdout.write = redirector # whenever sys.stdout.write is called, redirector is called.
sys.stderr.write = redirector
root.mainloop()
Now every time i run the first GUI , both GUIs open although there is no way the code reached the second GUI code yet... What is the problem here?
Also the second GUI is supposed to print from a class , but i have a bunch of error when I try to just put it there . What changes I need to make so I can make this 2nd GUI work with a class?
In the program I made, the user presses enter and the text typed is then shown as a label in the program. So the label keeps getting updated and then written on the next line. The problem is that in the textbox the previous line the user typed stays there, which means u have to keep manually deleting the string in the textbox to write a new line. How can I make it so that you start out with a cleared textbox? Also, the enter button works but it seems that when i click on the "Return" button it gives me an error:
TypeError: evaluate() missing 1 required positional argument: 'event'
Here's the code:
from tkinter import *
window = Tk()
window.geometry("200x300")
def evaluate(event):
thetext = StringVar()
labeloutput = Label(app, textvariable = thetext)
n = e.get()
thetext.set(n)
labeloutput.grid()
app = Frame(window)
app.pack()
e = Entry(window)
e.pack()
b= Button(window, text="Return", command=evaluate)
b.pack()
window.bind("<Return>", evaluate)
mainloop()
Since you bind evaluate as a callback and you use it as a button command, when you use it in the button you have to use a lambda and pass None to the event. event argument is needed because of the binding, but there is no event when you call it from button click, so just pass None to get rid of the error. You can delete by doing entry.delete(0, 'end').
from tkinter import *
window = Tk()
window.geometry("200x300")
def evaluate(event):
thetext = StringVar()
labeloutput = Label(app, textvariable = thetext)
n = e.get()
thetext.set(n)
labeloutput.grid()
e.delete(0, 'end') # Here we remove text inside the entry
app = Frame(window)
app.pack()
e = Entry(window)
e.pack()
b = Button(window, text="Return", command=lambda: evaluate(None)) # Here we have a lambda to pass None to the event
b.pack()
window.bind("<Return>", evaluate)
mainloop()
Of course, if you want to prevent the lambda from being used, you would have to create a function to handle the key binding, and a separate one for the button click.
From the first answer here:
StackOverflow #6548837
I can call callback when the user is typing:
from Tkinter import *
def callback(sv):
print sv.get()
root = Tk()
sv = StringVar()
sv.trace("w", lambda name, index, mode, sv=sv: callback(sv))
e = Entry(root, textvariable=sv)
e.pack()
root.mainloop()
However, the event occurs on every typed character. How to call the event when the user is done with typing and presses enter, or the Entry widget loses focus (i.e. the user clicks somewhere else)?
I think this does what you're looking for. I found relevant information here. The bind method is the key.
from Tkinter import *
def callback(sv):
print sv.get()
root = Tk()
sv = StringVar()
e = Entry(root, textvariable=sv)
e.bind('<Return>', (lambda _: callback(e)))
e.pack()
root.mainloop()
To catch Return key press event, the standard Tkinter functionnality does it. There is no need to use a StringVar.
def callback(event):
pass #do the work
e = Entry(root)
e.bind ("<Return">,callback)