Reset Tkinter Widget to its default value - python

In need to make a generic function that on event it would return the focused-out widget to its default value. Is there a way to accomplish this?
Example:
entry1 = Tkinter.Entry()
entry1.grid(..)
entry1.insert(0,"hello")
entry1.bind("<FocusIn>", EntryFocusedIn)
entry1.bind("<FocusOut>", EntryFocusedOut)
entry2 = Tkinter.Entry()
entry2.grid(..)
entry2.insert(0,"again")
entry2.bind("<FocusIn>", EntryFocusedIn)
entry2.bind("<FocusOut>", EntryFocusedOut)
def EntryFocusedIn(params):
params.widget.delete(0, Tkinter.END)
def EntryFocusedOut(params):
# return widget to its default value
# which in case of entry1 its "hello"
# and in case of entry2 its "again"

You could subclass the Entry widget to add an attribute to store a default value, and reference that attribute in the event handler. However, there's nothing stopping you from simply adding your own attribute to each Entry widget directly, e.g. entry1.default_value = 'hello', entry1.default_value = 'again':
import Tkinter
def EntryFocusedIn(params):
params.widget.delete(0, Tkinter.END)
def EntryFocusedOut(params):
# restore default value
params.widget.delete(0, Tkinter.END)
params.widget.insert(0, params.widget.default_value)
root = Tkinter.Tk()
entry1 = Tkinter.Entry()
entry1.default_value = 'hello'
entry1.pack()
entry1.insert(0, entry1.default_value)
entry1.bind("<FocusIn>", EntryFocusedIn)
entry1.bind("<FocusOut>", EntryFocusedOut)
entry2 = Tkinter.Entry()
entry2.default_value = 'again'
entry2.pack()
entry2.insert(0, entry2.default_value)
entry2.bind("<FocusIn>", EntryFocusedIn)
entry2.bind("<FocusOut>", EntryFocusedOut)
root.mainloop()

Related

how to destroy previews label when the function call again in tkinter python

def entering(a):
value=entry1.get() #entry1.get()is used to get values which entered in entry box
label1=Label(root, text =value, height=10)
label1.pack()
entry1.delete(0, END) # used to clear entry box
root.bind('<Return>',entering)
how do I remove the widget that I created in the function call entering?
I know about the destroy function. I don't want to destroy it after a particular time.
I want to destroy it or overwrite it into the widget when I call the function again
I think this is what you expect:
import tkinter as tk
root = tk.Tk()
myentry = tk.Entry(root)
myentry.pack()
var = tk.StringVar(root)
mylabel = tk.Label(root, textvariable= var)
mylabel.pack()
def entering(event):
text = myentry.get()
var.set(text)
myentry.bind('<Return>', entering)
root.mainloop()

How can I set the text of a ttk.Entry?

It appears that I cannot set the text of a ttk.Entry with a root of ttk.Label during an event:
import tkinter
from tkinter import ttk
def modify_label_text(event):
entry = event.widget
newvalue = entry.get()
label = entry.master
label.configure(text=newvalue)
entry.unbind("<Return>")
entry.pack_forget()
label.focus()
def create_entry(event):
label = event.widget
oldvalue = label.cget("text")
newvalue = tkinter.StringVar()
entry = ttk.Entry(label, textvariable=newvalue)
'''
entry = tkinter.Entry(label, textvariable=newvalue)
'''
entry.pack()
entry.delete(0, "end")
entry.insert(0, oldvalue)
entry.bind("<Return>", modify_label_text)
entry.focus()
root = tkinter.Tk()
clickme = ttk.Label(root, width=16)
clickme.pack()
clickme.bind("<Button-1>", create_entry)
clickme.focus()
root.mainloop()
When I click the empty label and enter a new value, the value is reflected in the label. However, if I click the label again to "edit" the value, the entry field is empty again.
Furthermore, if I use tkinter.Entry rather than ttk.Entry, it appears to work.
Why is the text of the entry only set when using tkinter.Entry? How can I fix this to work with ttk.Entry?
This may not an answer, but a bit too large for a comment. Also could someone elaborate this behavior in a different enviorment. I ran that code with:
Mashine:
Windows 10 Home; x64-base,Intel(R) Core(TM) i3-2120 # 3.30GHz, 3300 MHz, 2Cores
with
Python 3.7.2 and tkinter 8.6
After some research I couldnt find a reason for this behavior. Neither in the docs, nor in the sometimes tricky style_map or in the default bindings.
Can I assume that you create the labels with the entries in a function/loop? You may want to reuse the entry, because for some reason the exact same code works if you adress the entry by winfo_children(). And even if I call .update_idletasks() or just for experience the evil .update() it dosent work for no reason.
import tkinter
from tkinter import ttk
def modify_label_text(event):
entry = event.widget
newvalue = entry.get()
label = entry.master
label.configure(text=newvalue)
entry.unbind("<Return>")
entry.pack_forget()
label.focus()
def create_entry(event):
label = event.widget
oldvalue = label.cget("text")
newvalue = tkinter.StringVar()
if len(label.winfo_children()) == 0:
print('new')
entry = ttk.Entry(label, textvariable=newvalue)
'''
entry = tkinter.Entry(label, textvariable=newvalue)
'''
e = label.winfo_children()[0]
e.pack()
e.delete(0, "end")
e.insert(0, oldvalue+' works')
e.bind("<Return>", modify_label_text)
e.focus()
root = tkinter.Tk()
clickme = ttk.Label(root, width=16)
clickme.pack()
clickme.bind("<Button-1>", create_entry)
clickme.focus()
root.mainloop()
Another solution could be:
def create_entry(event):
label = event.widget
oldvalue = label.cget("text")
newvalue = tkinter.StringVar()
entry = ttk.Entry(label, textvariable=newvalue)
'''
entry = tkinter.Entry(label, textvariable=newvalue)
'''
root.after(100,after_time,entry,oldvalue)
def after_time(entry,oldvalue):
entry.pack()
entry.delete(0, "end")
entry.insert(0, oldvalue)
entry.bind("<Return>", modify_label_text)
entry.focus()
I suggest you create an instance of Entry outside the function and simply pack() and pack_forget() in the function. pack_forget() will not delete your widget it will only hide it from the layout. To delete the widget you might have to use widget.destroy().
import tkinter
from tkinter import ttk
def modify_label_text(event):
newvalue = entry.get()
clickme.configure(text=newvalue)
entry.pack_forget()
clickme.focus()
def create_entry(event):
label = event.widget
entry.pack()
entry.focus()
root = tkinter.Tk()
newvalue = tkinter.StringVar()
clickme = ttk.Label(root, width=16)
clickme.pack()
clickme.bind("<Button-1>", create_entry)
clickme.focus()
entry = ttk.Entry(clickme, textvariable=newvalue)
entry.bind("<Return>", modify_label_text)
root.mainloop()
Edit(writing my comment as answer)
I suspect that it has to do something with the textvariable being set. Simply removing it or changing the newvalue to global scope seems to work. Also, since you don't seem to be using .set or .get methods you can simply remove it if you want.

How to get output from class after input all values

from tkinter import *
app = Tk()
app.title("First Software")
app.minsize(500, 500)
#For Input Declaration
UserName = StringVar()
pass1 = IntVar()
class Functions:
def username(self, UserName):
self.UserName = Username
print(UserName.get())
def password(self, pass1):
self.pass1 = pass1
print(pass1.get())
#---Label---
label = Label(text='Enter any Number between 1 and 100...').pack()
#---Entry---
entry = Entry(app, textvariable=UserName).pack()
entry1 = Entry(app, textvariable=pass1).pack()
#---Buttton---
button = Button(text='Submit', command=Functions).pack()
app.mainloop()
After running this code, How can I get separate input of Username and password by using this method. I'm lil bit confused right now!
command=Functions tells Tkinter to create an instance of your Functions class when the Submit button is pressed. But it doesn't tell it to call the functions defined inside Functions. However, that class definition is a bit odd, and you don't really need a class to contain those functions. Instead, we can write a simple function that gets the values of UserName and pass1 and prints them.
I've made a few other minor changes to your code.
import tkinter as tk
app = tk.Tk()
app.title("First Software")
#app.minsize(500, 500)
#For Input Declaration
UserName = tk.StringVar()
pass1 = tk.IntVar()
def print_entries():
print('User name:', UserName.get())
print('Password:', pass1.get())
tk.Label(app, text='User name.').pack()
entry = tk.Entry(app, textvariable=UserName)
entry.pack()
tk.Label(app, text='Password\nEnter any Number between 1 and 100').pack()
entry1 = tk.Entry(app, textvariable=pass1)
entry1.pack()
tk.Button(app, text='Submit', command=print_entries).pack()
app.mainloop()
This code doesn't actually need the names entry and entry1, but I kept them in case you want to add code that does need to refer to those widgets by name.
Note that you should not do
entry = Entry(app, textvariable=UserName).pack()
The .pack method returns None, so the above statement assigns the value of None to entry. Instead, we do
entry = tk.Entry(app, textvariable=UserName)
entry.pack()
That assigns the new Entry widget to the name entry and then calls its .pack method to pack it into the window.
If you like, you can wrap that code up in a class, but I wouldn't bother with a simple GUI like this. But this is one way to do it:
import tkinter as tk
class App:
def __init__(self):
root = tk.Tk()
root.title("First Software")
#root.minsize(500, 500)
#For Input Declaration
self.UserName = tk.StringVar()
self.pass1 = tk.IntVar()
tk.Label(root, text='User name.').pack()
entry = tk.Entry(root, textvariable=self.UserName)
entry.pack()
tk.Label(root, text='Password\nEnter any Number between 1 and 100').pack()
entry1 = tk.Entry(root, textvariable=self.pass1)
entry1.pack()
tk.Button(root, text='Submit', command=self.print_entries).pack()
root.mainloop()
def print_entries(self):
print('User name:', self.UserName.get())
print('Password:', self.pass1.get())
App()

How to retain the value of an entry field acquired in a popup toplevel window in tkinter?

I cannot get my code to pass the pop up text entry to a global variable i am also attempting to set this global variable as the default text in the entry field in all future instances.
Pop up -> Enter Filepath -> accept&close -> Re-open shows last filepath present as default -> if changed new filepath entry becomes default in future.
import tkinter as tk
from tkinter import ttk
from tkinter import *
master = tk.Tk()
Var1 = StringVar()
Filepath_Var = None
def A_Connect():
root = Tk()
root.title("Entry Field")
def entry_field():
global Filepath_Var
Filepath_Var = Var1.get()
tk.Label(root, text="filepath: ").grid(row=0)
e1 = tk.Entry(root, textvariable=Var1)
tk.Label(root, text="Item Number: ").grid(row=1)
e2 = tk.Entry(root)
#e1.insert(0, r"C:\Users\zxy\ghj\iugf\Bea\something.xlsx")
e1.insert(0, Var1.get())
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
Button(root, text = 'Accept', command = entry_field).grid(row=3, column=1,
sticky=W, pady=4)
root.mainloop()
note = ttk.Notebook(master)
tab1 = tk.Frame(note)
canvas7 = Canvas(tab1, width=520, height=350)
canvas7.pack()
A_Button = tk.Button(tab1, text="A",
width=12, height=3,command=A_Connect, anchor = 'w')
A_Button_Window = canvas7.create_window(20, 120, anchor = 'sw',
window = A_Button)
note.add(tab1, text = " Main ")
note.pack()
master.mainloop()
As a follow up to your earlier question, I encapsulated an example of the (bare bones) desired behavior in two classes:
The main App consists of a button that launches an entry popup; upon filling the fields and accepting, the value in the entry is provided to the App, and the popup closed.
The value entered is stored by the App, and used to populate the entry field of the entry fields in successive popups.
You will probably want to add confirmations and verifications before changing the defaults, and closing the popup, but here, you have the basic skeleton to attach this to.
import tkinter as tk
class PopUpEntry(tk.Toplevel):
def __init__(self, master, default_value=None):
self.master = master
super().__init__(self.master)
if default_value is None:
self.default_entry = 'C:*****\somthing.xlsx'
else:
self.default_entry = default_value
self.title("Entry Field")
tk.Label(self, text="Filepath: ").pack()
self.e1 = tk.Entry(self)
self.e1.insert(0, self.default_entry)
self.e1.pack()
tk.Button(self, text = 'Accept', command=self.entry_field).pack()
def entry_field(self):
self.default_entry = self.e1.get()
self.master.provide_entry_value(self.default_entry)
self.destroy()
class App(tk.Tk):
def __init__(self):
super().__init__()
self.pop_entry = tk.Button(self, text='launch entry', command=self.launch_entry)
self.pop_entry.pack()
self.default_entry_value = None
self.mainloop()
def launch_entry(self):
PopUpEntry(self, self.default_entry_value)
def provide_entry_value(self, value):
self.default_entry_value = value
print(self.default_entry_value)
App()

AttributeError: Event instance has no attribute 'delete'

I am trying to make a program that will return the user's input and also clear the Entry when Return/Enter is pressed. When ran, the second method (def e_delete(e):) always gives the error, AttributeError: Event instance has no attribute 'delete' and if the e is changed to self no string is returned and no error happens.
from Tkinter import *
import os.path
import PIL.Image, PIL.ImageTk
import Tkinter as tk
def on_change(e):
inp = e.widget.get()
print inp
root = tk.Tk()
#Makes a canvas for objects
canvas = Canvas(root, height=100, width=400)
#Displays the canvas
canvas.grid(row=3, column=2)
root.grid_columnconfigure(0, weight=1)
root.grid_columnconfigure(1, weight=1)
label = Label(root, text="Enter an element or the atomic number from 1 to 118.").grid(row=0, column=2)
e = tk.Entry(root)
e.pack()
e.bind("<Return>", on_change)
e.grid(row=2, column=2)
e.focus()
def e_delete(e):
e.delete(0, 'end')
e.bind("<Return>", e_delete)
#img = create_image(0, 300, 'ptable.png')
root.mainloop()
You're doing this:
def entry_delete(e):
e.delete(0, 'end')
The value that gets passed to a callback for an event binding is an Event object. And they don't have a delete method.
The fact that you also have a global variable with the same name doesn't make any difference (except to confuse you and other readers); the parameter e hides the global e.
So, if you want to call a method on your Entry object, don't hide it:
def e_delete(evt):
e.delete(0, 'end')
Or, if you want to call a method on whatever widget triggered the event (which, in this case, will always be the same thing, so it's just a matter of which one makes more sense to you), you can do that instead:
def e_delete(evt):
evt.widget.delete(0, 'end')
However, it's usually even better to give everything clear and distinct names to avoid this kind of confusion:
entry = tk.Entry(root)
ent.pack()
entry.bind("<Return>", on_change)
entry.grid(row=2, column=2)
entry.focus()0
def entry_delete(evt):
entry.delete(0, 'end')
entry.bind("<Return>", entry_delete)

Categories

Resources