Accepting inputs from Tkinter - python

I want to write a GUI in Tkinter that accepts a text inputs from the user and stores it in a variable Text; I also want to be able to use this variable later on... Here is something i tried that failed:
from Tkinter import *
def recieve():
text = E1.get()
return text
top = Tk()
L1 = Label(top, text="User Name")
L1.pack(side=LEFT)
E1 = Entry(top, bd=5)
E1.pack(side=RIGHT)
b = Button(top, text="get", width=10, command=recieve)
b.pack()
print text
top.mainloop()
So how do I do this?

The problem lies here:
print text
top.mainloop()
Before top.mainloop() is called, text has not been defined. Only after the call to top.mainloop is the user presented with the GUI interface, and the mainloop probably loops many many times before the user gets around to typing in the Entry box and pressing the Button. Only after the button is pressed is recieve (sic) called, and although it returns a value, that value is not stored anywhere after recieve ends. If you want to print text, you have to do it in the recieve function:
from Tkinter import *
def receive():
text = E1.get()
print(text)
top = Tk()
L1 = Label(top, text="User Name")
L1.pack( side = LEFT)
E1 = Entry(top, bd =5)
E1.pack(side = RIGHT)
b = Button(top, text="get", width=10, command=receive)
b.pack()
top.mainloop()

Related

Returning a value when clicking a button in tkinter

I have created a simple text box and want to take the text from it when i click on a button, but for some reason it doesn't work. I tried using a global variable but it still doesn't work.
Here is what i have written sofar:
t = Text(r, height=20, width=40)
t.pack()
def myClick():
myLabel= Label(r,text= "Sent!")
global input
input = t.get("1.0", 'end-1c')
myLabel.pack()
myButton = Button(r, text="Send ", command=myClick)
myButton.pack()
print(input)
r.mainloop()
I think you are using too many arguments in the .get() and the widget type has to be Entry and you really should define your variable before everything else. Here is my suggestion for your code:
from tkinter import *
r = Tk()
t = Entry(r, width=40)
t.pack()
def myClick():
global input
input = t.get()
myLabel= Label(r,text= input)
myLabel.pack()
myButton = Button(r, text="Send ", command=myClick)
myButton.pack()
print(input)
r.mainloop()

How to use textfield key press event using python

if i write some thing on the textfield and press enter key on the keyboard.what i entered on the textfield display messagebox. this point get error if(format(k=event.char(13)))) : if i set the enter key code. i added full code below.
from tkinter import *
root = Tk()
root.geometry("800x800")
global e1
def callback(event):
if(format(k=event.char(13)))):
msg = e1.get()
print(msg)
Label(root, text="Student Name").place(x=140, y=40)
e1 = Entry(root)
e1.place(x=140, y=10)
e1.bind('<Key>',callback)
root.mainloop()
Try this out
from tkinter import *
root = Tk()
root.geometry("800x800")
def callback(event):
msg = e1.get()
print(msg)
Label(root, text="Student Name").place(x=140, y=40)
e1 = Entry(root)
e1.place(x=140, y=10)
e1.bind('<Return>',callback) #<Return> is equivalent to your Enter key
root.mainloop()
When you click on Enter key, on the entry widget, then the function gets called and the output will be printed out. I also removed the global as it makes no sense to use it in outside functions.
Hope it helped you out.
Cheers

Updating label keeps previous text

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.

.get() not giving a value [duplicate]

I'm trying to use an Entry field to get manual input, and then work with that data.
All sources I've found claim I should use the get() function, but I haven't found a simple working mini example yet, and I can't get it to work.
I hope someone can tel me what I'm doing wrong. Here's a mini file:
from tkinter import *
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
content = entry.get()
print(content) # does not work
mainloop()
This gives me an Entry field I can type in, but I can't do anything with the data once it's typed in.
I suspect my code doesn't work because initially, entry is empty. But then how do I access input data once it has been typed in?
It looks like you may be confused as to when commands are run. In your example, you are calling the get method before the GUI has a chance to be displayed on the screen (which happens after you call mainloop.
Try adding a button that calls the get method. This is much easier if you write your application as a class. For example:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.entry = tk.Entry(self)
self.button = tk.Button(self, text="Get", command=self.on_button)
self.button.pack()
self.entry.pack()
def on_button(self):
print(self.entry.get())
app = SampleApp()
app.mainloop()
Run the program, type into the entry widget, then click on the button.
You could also use a StringVar variable, even if it's not strictly necessary:
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set("a default value")
s = v.get()
For more information, see this page on effbot.org.
A simple example without classes:
from tkinter import *
master = Tk()
# Create this method before you create the entry
def return_entry(en):
"""Gets and prints the content of the entry"""
content = entry.get()
print(content)
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
# Connect the entry with the return button
entry.bind('<Return>', return_entry)
mainloop()
*
master = Tk()
entryb1 = StringVar
Label(master, text="Input: ").grid(row=0, sticky=W)
Entry(master, textvariable=entryb1).grid(row=1, column=1)
b1 = Button(master, text="continue", command=print_content)
b1.grid(row=2, column=1)
def print_content():
global entryb1
content = entryb1.get()
print(content)
master.mainloop()
What you did wrong was not put it inside a Define function then you hadn't used the .get function with the textvariable you had set.
you need to put a textvariable in it, so you can use set() and get() method :
var=StringVar()
x= Entry (root,textvariable=var)
Most of the answers I found only showed how to do it with tkinter as tk. This was a problem for me as my program was 300 lines long with tons of other labels and buttons, and I would have had to change a lot of it.
Here's a way to do it without importing tkinter as tk or using StringVars. I modified the original mini program by:
making it a class
adding a button and an extra method.
This program opens up a tkinter window with an entry box and an "Enter" button. Clicking the Enter button prints whatever is in the entry box.
from tkinter import *
class mini():
def __init__(self):
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
Button(master, text='Enter', command=self.get_content).grid(row=1)
self.entry = Entry(master)
self.entry.grid(row=0, column=1)
master.mainloop()
def get_content(self):
content = self.entry.get()
print(content)
m = mini()

Constantly Update Label Widgets From Entry Widgets TKinter

I am trying to make a form using TKinter that takes information from a/multiple entry widget(s) and uses them as the value for text widgets. For example, this could work:
import Tkinter
from Tkinter import *
top = Tk()
e1 = Entry(top)
e2 = Entry(top)
t = Label(top, text = e1.get() + e2.get())
e1.pack()
e2.pack()
t.pack()
top.mainloop()
The issue is that this does not automatically update itself. I know it could be done using a button, but I would like to have the information calculated/updated in the Label widget as the user types into the Entry widgets. What would be the best was to do this? The following implementation of a while loop does not work as the program enters the top.mainloop() and does not exit:
import Tkinter
from Tkinter import *
top = Tk()
e1 = Entry(top)
e2 = Entry(top)
t = Label(top, text = e1.get() + e2.get())
e1.pack()
e2.pack()
while True:
t = Label(top, text = e1.get() + e2.get())
t.pack()
top.mainloop()
Thank you in advance.
Six
while True will not work because mainloop() is some kind of while True loop and it works all the time till you stop program.
You have to use after(time_in_millisecond, function_name) which add function_name to special queue and mainloop() will run it (only once) after time_in_millisecond. Executed function can use after() to run itself again after time_in_millisecond.
Second solution: You can use StringVar with Entry and you can assign function to StringVar (using trace()) and this function will be executed every time when StringVar will be changed.
Third solution: you can bind event (<Key>) to Entry which will call some function when you press key in Entry.
Last solution: You can use validatecommand= with validate= in Entry to call some function when text in entry will be changed.
See Tkinterbook:
The Tkinter Entry Widget,
Events and Bindings,
The Variable Classes (BooleanVar, DoubleVar, IntVar, StringVar)
EDIT:
Example with validatecommand= with validate= .
Not all widgets have validatecommand=
from Tkinter import *
#------------------------------------
def my_validater():
new_text = e1.get() + e2.get()
# different method to set label text (without StringVar)
#t['text'] = new_text
t.config(text=new_text)
# validater have to return True or False
return True
#------------------------------------
top = Tk()
#---
t = Label(top)
t.pack()
#---
e1 = Entry(top, validate='key', validatecommand=my_validater) # validate every key
e1.pack()
#---
e2 = Entry(top, validate='key', validatecommand=my_validater) # validate every key
e2.pack()
#---
top.mainloop()
#------------------------------------
Example with StringVar and trace
Probably the best solution for most widgets.
from Tkinter import *
#------------------------------------
def my_tracer(a, b, c): # trace send 3 arguments to my_tracer
#print a, b, c
# using StringVar to get and set text
new_text = e1_var.get() + e2_var.get()
t_var.set(new_text)
#------------------------------------
top = Tk()
#---
t_var = StringVar() # or StringVar(top)
t = Label(top, textvariable=t_var)
t.pack()
#---
e1_var = StringVar() # or StringVar(top)
e1_var.trace('w', my_tracer) # run my_tracer if value was changed (w = write)
e1 = Entry(top, textvariable=e1_var)
e1.pack()
#---
e2_var = StringVar() # or StringVar(top)
e2_var.trace('w', my_tracer) # run my_tracer if value was changed (w = write)
e2 = Entry(top, textvariable=e2_var)
e2.pack()
#---
top.mainloop()
#------------------------------------
Example with bind(<Key>, ...)
Binded function is called before char is placed in Entry so you get text without last char in Entry. This method is not good for this situation but I keep it.
Eventually you can get event.char and add missing char to text.
from Tkinter import *
#------------------------------------
def my_bind(event): # bind send 1 argument to my_bind
# different type of event can have different atributes
#print event, event.widget, event.char, event.keysym, event.keycode
new_text = e1.get() + e2.get()
t.config(text=new_text)
#------------------------------------
top = Tk()
#---
t = Label(top)
t.pack()
#---
e1 = Entry(top)
e1.pack()
e1.bind('<Key>', my_bind)
#---
e2 = Entry(top)
e2.pack()
e2.bind('<Key>', my_bind)
#---
top.mainloop()
#------------------------------------
Example with after().
Used for different repeated jobs.
from Tkinter import *
#------------------------------------
def my_after():
new_text = e1.get() + e2.get()
t.config(text=new_text)
# call again after 100 ms
top.after(100, my_after)
#------------------------------------
top = Tk()
#---
t = Label(top)
t.pack()
#---
e1 = Entry(top)
e1.pack()
#---
e2 = Entry(top)
e2.pack()
#---
# call first time
my_after()
# call first time after 100 ms
#top.after(100, my_after)
#---
top.mainloop()
#------------------------------------

Categories