Event callback after a Tkinter Entry widget - python

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)

Related

I can't seem to solve this EOL error, Can anyone please show me

from tkinter import *
root = Tk()
def evaluate(event):
data = e.get()
ans.configure(text = "Answer: " + str(eval(data)))
e = Entry(root)
e.bind('<Enter>',evaluate)
e.pack()
ans = Label(root)
ans.pack()
root.mainloop()
You simply bind the wrong event to your Entry widget. Use this:
e.bind('<Return>', evaluate)
In tkinter, the <Return> event is launched when the user hits ENTER key. Whereas the <Enter> event is launched when the mouse enters the geometric area of a widget. I know, it's a bit disturbing...

How can I print the text immediately in combobox with bind event?

from Tkinter import *
import ttk
main=Tk()
def print1(event):
string = ""
string = combobox1.get()
print combobox1.get()
val = StringVar()
combobox1 = ttk.Combobox(main, textvariable=val, height=4)
combobox1.bind("<Key>", print1)
combobox1.focus_set()
combobox1.pack()
mainloop()
How can I fix the problem that is, when I press the first button, it didn't show immediately.
For example, when I pressed a, it didn't show anything, and then I pressed b. It will show a, but not ab.
How can I fix this bug?
thanks.
You have it very close. The bind statement is slightly different from what you need. The problem was that it was printing before the key was delivered to the combobox. Now it waits until the key is released to fire the event.
from Tkinter import *
import ttk
main=Tk()
def print1(event):
string = ""
string = combobox1.get()
print combobox1.get()
val = StringVar()
combobox1 = ttk.Combobox(main, textvariable=val, height=4)
combobox1.bind("<KeyRelease>", print1)
combobox1.focus_set()
combobox1.pack()
mainloop()
#Ron Norris seems to figured-out and solved your issue. Regardless, here's another way to do things that doesn't involve binding events, it uses the trace() method common to all Tkinter variable classes (BooleanVar, DoubleVar, IntVar, and StringVar) which is described here. The arguments it receives when called are explained in the answer to this question.
from Tkinter import *
import ttk
main=Tk()
def print1(*args):
string = combobox1.get()
print string
val = StringVar()
val.trace("w", print1) # set callback to be invoked whenever variable is written
combobox1 = ttk.Combobox(main, textvariable=val, height=4)
combobox1.focus_set()
combobox1.pack()
mainloop()

Get function tkinter

I use tkinter on python 2.7. My problem is that I don't succeed in getting the variable entered into the entry_number; the function is called, but it didn't print anything.
How can I know if the checkbox is checked or not?
from tkinter import *
from tkinter import Tk, StringVar, Label, Entry, Button
def call():
print (e)
root = Tk()
var1 = IntVar()
c=Checkbutton(root, text="Bou ", variable=var1).grid(row=4, column=1)
text = StringVar(root)
button = Button(root, text='call',
command=call)
entry_number = Entry(root)
button.grid(column=8, row=20)
entry_number.grid(column=6,row=4)
e = entry_number.get()
root.mainloop()
The problem is that you define e immediately when you are creating the UI. At this point, the entry is still empty, so all that is printed when you press the button is an empty string.
Instead, put the definition of e inside the function, so it is updated each time you click:
def call():
e = entry_number.get()
print (e)

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.

How do I get the Entry's value in tkinter?

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

Categories