Tkinter entry widget execution [duplicate] - python

This question already exists:
Entry widget in tkinter
Closed 1 year ago.
So I made a simple program however it doesn't seem to work
my code is:
e = Entry(root, font = 20,borderwidth=5)
e.grid(row=1)
def capture(event):
print(e.get())
e.bind("<Key>", capture)
However the first time I enter something in the box, all I get is an empty string.

As #Art stated:
You can use "<KeyRelease>", e.bind("<Key>", lambda event: e.after(1, capture, event))" or simply Use StringVar()
from tkinter import *
root=Tk()
e = Entry(root, font = 20,borderwidth=5)
e.grid(row=1)
def capture(event):
print(e.get())
e.bind("<Key>", lambda event: e.after(1, capture, event))
root.mainloop()
Or you can use a StringVar()
from tkinter import *
root=Tk()
s=StringVar()
e = Entry(root,textvariable=s, font = 20,borderwidth=5)
e.grid(row=1)
def capture(*args):
print(s.get())
s.trace("w",capture)
root.mainloop()

Related

Creating button widgets in a loop tkinter [duplicate]

This question already has answers here:
tkinter creating buttons in for loop passing command arguments
(3 answers)
Closed 1 year ago.
I have some code below that creates 26 buttons in a tkinter window with each letter of the alphabet in it. I want the code to print the letter in the button when it is pressed. My code prints z no matter what button is pressed. How could I fix this?
import tkinter as tk
import string
def whenPressed(button):
print(button['text'])
root = tk.Tk()
alphabet = list(string.ascii_lowercase)
for i in alphabet:
btn = tk.Button(root, text = i, command = lambda: whenPressed(btn))
btn.grid(row = alphabet.index(i)//13, column = alphabet.index(i)%13, sticky = 'nsew')
Try this:
from functools import partial
import tkinter as tk
import string
def whenPressed(button, text):
print(text)
root = tk.Tk()
alphabet = list(string.ascii_lowercase)
for i in alphabet:
btn = tk.Button(root, text=i)
command = partial(whenPressed, btn, i)
btn.config(command=command)
row = alphabet.index(i) // 13
column = alphabet.index(i) % 13
btn.grid(row=row, column=column, sticky="news")
You have to update the button's command after you create it using <tkinter.Button>.config(command=...). I also used functools.partial. Its documentation is here. Also it's usually better to also pass in the text instead of having button["text"].
A little bit of updated version to avoid calculations to use with rows and columns:
from functools import partial
import tkinter as tk
import string
def whenPressed(button, text):
print(text)
root = tk.Tk()
alphabet = list(string.ascii_lowercase)
for i in range(2):
for j in range(13):
text = alphabet[13*i+j]
btn = tk.Button(root, text=text)
command = partial(whenPressed, btn, text) # Also can use lambda btn=btn,text=text: whenPressed(btn, text)
btn.config(command=command)
btn.grid(row=i, column=j, sticky="news")
root.mainloop()

Getting variable out of Tkinter

I would like to ask if anyone knows how to get out a variable from an Entry in Tkinter to be used in future calculation.
Let us assume that I want to create a prompt where the user needs to place two numbers in the two different Entry widgets.
These numbers are to be used in another script for calculation. How can I retrieve the values from the prompt created in Tkinter?
In my opinion, I would need to create a function with the code bellow and make it return the value from the Tkinter prompt. However, I cannot return the numbers because I'm destroying the root window. How can I get pass this, preferably without global variables.
Best Regards
from tkinter import *
from tkinter import ttk
#Start of window
root=Tk()
#title of the window
root.title('Title of the window')
def get_values():
values=[(),(value2.get())]
return values
# Creates a main frame on the window with the master being the root window
mainframe=ttk.Frame(root, width=500, height=300,borderwidth=5, relief="sunken")
mainframe.grid(sticky=(N, S, E, W))
###############################################################################
#
#
# Label of the first value
label1=ttk.Label(master=mainframe, text='First Value')
label1.grid(column=0,row=0)
# Label of the second value
label2=ttk.Label(master=mainframe, text='Second Value')
label2.grid(column=0,row=1)
###############################################################################
#
#
# Entry of the first value
strvar1 = StringVar()
value1 = ttk.Entry(mainframe, textvariable=strvar1)
value1.grid(column=1,row=0)
# Entry of the second value
strvar2 = StringVar()
value2 = ttk.Entry(mainframe, textvariable=strvar2)
value2.grid(column=1,row=1)
# Creates a simplle button widget on the mainframe
button1 = ttk.Button(mainframe, text='Collect', command=get_values)
button1.grid(column=2,row=1)
# Creates a simplle button widget on the mainframe
button2 = ttk.Button(mainframe, text='Exit', command=root.destroy)
button2.grid(column=2,row=2)
root.mainloop()
You use a class because the class instance and it's variables remain after tkinter exits.https://www.tutorialspoint.com/python/python_classes_objects.htm And you may want to reexamine some of your documentation requirements, i.e. when the statement is
"root.title('Title of the window')", adding the explanation "#title of the window" is just a waste of your time..
""" A simplified example
"""
import sys
if 3 == sys.version_info[0]: ## 3.X is default if dual system
import tkinter as tk ## Python 3.x
else:
import Tkinter as tk ## Python 2.x
class GetEntry():
def __init__(self, master):
self.master=master
self.entry_contents=None
self.e = tk.Entry(master)
self.e.grid(row=0, column=0)
self.e.focus_set()
tk.Button(master, text="get", width=10, bg="yellow",
command=self.callback).grid(row=10, column=0)
def callback(self):
""" get the contents of the Entry and exit
"""
self.entry_contents=self.e.get()
self.master.quit()
master = tk.Tk()
GE=GetEntry(master)
master.mainloop()
print("\n***** after tkinter exits, entered =", GE.entry_contents)
So, I have taken Curly Joe's example and made a function with the his sketch
The final result, for anyone wanting to use this as a template for a input dialog box:
def input_dlg():
import tkinter as tk
from tkinter import ttk
class GetEntry():
def __init__(self, master):
self.master=master
self.master.title('Input Dialog Box')
self.entry_contents=None
## Set point entries
# First point
self.point1 = ttk.Entry(master)
self.point1.grid(row=0, column=1)
self.point1.focus_set()
# Second point
self.point2 = ttk.Entry(master)
self.point2.grid(row=1, column=1)
self.point2.focus_set()
# labels
ttk.Label(text='First Point').grid(row=0, column=0)
ttk.Label(text='Second Point').grid(row=1, column=0)
ttk.Button(master, text="Done", width=10,command=self.callback).grid(row=5, column=2)
def callback(self):
""" get the contents of the Entries and exit the prompt"""
self.entry_contents=[self.point1.get(),self.point2.get()]
self.master.destroy()
master = tk.Tk()
GetPoints=GetEntry(master)
master.mainloop()
Points=GetPoints.entry_contents
return list(Points)
In python, functions are objects, as in get_values is an object.
Objects can have attributes.
Using these two, and the knowledge that we can't really return from a button command, we can instead attach an attribute to an already global object and simply use that as the return value.
Example with button
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
def on_button_press(entry):
on_button_press.value = entry.get()
entry.quit()
def main():
root = tk.Tk()
entry = tk.Entry(root)
tk.Button(root, text="Get Value!", command=lambda e = entry : on_button_press(e)).pack()
entry.pack()
tk.mainloop()
return on_button_press.value
if __name__ == '__main__':
val = main()
print(val)
Minimalistic example
Similarly modules are also objects, if you want to avoid occupying global namespace extremely, you can attach a new attribute to the module you're using
See:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
if __name__ == '__main__':
tk.my_value = lambda: [setattr(tk, 'my_value', entry.get()), root.destroy()]
root = tk.Tk()
entry = tk.Entry(root)
root.protocol('WM_DELETE_WINDOW', tk.my_value)
entry.pack()
tk.mainloop()
print(tk.my_value)

Python tkinter limit entry input [duplicate]

This question already has an answer here:
(Python) How to limit an entry box to 2 characters max [duplicate]
(1 answer)
Closed 5 years ago.
How do I limit the input on a Entry to only 4 characters
from tkinter import *
window = Tk()
display = Entry(window)
display.grid()
You can do this by running a trace on the attribute textvariable of the entry widget. Whenever this variable is updated you will need to set the variable to it's own value up to the 4th character.
See below:
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.sv = StringVar()
self.entry = Entry(root, textvariable = self.sv)
self.entry.pack()
self.sv.trace("w", lambda name, index, mode, sv=self.sv: self.callback(self.sv))
def callback(self, sv):
self.sv.set(self.sv.get()[:4])
root = Tk()
App(root)
root.mainloop()

Event callback after a Tkinter Entry widget

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)

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