Reputation: 87
I want to add numbers (only 4 numbers) to entry via button in tkinter. I tried this code but it's not working. I need some suggestions.
import tkinter as tk
win = tk.Tk()
var = tk.StringVar()
var_entry = tk.Entry(win,text='var',textvariable=var)
def handle_button(event):
return var.insert(0,4)
def window():
global win
var_entry.grid(row =1 ,column =2)
button1 = tk.Button(win,text = '1' ,textvariable = 1)
button1.bind("<Button-1>", handle_button)
button1.grid(row = 2 , column = 0)
# similarly I defined all the buttons.
windows()
win.mainloop()
The error it shows is:
AttributeError: 'StringVar' object has no attribute 'insert'
Upvotes: 0
Views: 11101
Reputation: 1
""" Below code restricts the ttk.Entry widget to receive type 'str'. """
import tkinter as tk
from tkinter import ttk
def is_type_int(*args):
item = var.get()
try:
item_type = type(int(item))
if item_type == type(int(1)):
print(item)
print(item_type)
except:
ent.delete(0, tk.END)
root = tk.Tk()
root.geometry("300x300")
var = tk.StringVar()
ent = ttk.Entry(root, textvariable=var)
ent.pack(pady=20)
var.trace("w", is_type_int)
root.mainloop()
Upvotes: 0
Reputation: 87
I tried this one and it also worked.
import tkinter as tk
win = tk.Tk()
var = tk.StringVar()
var_entry = tk.Entry(win,text='var',textvariable=var)
var_entry.grid()
def handle_button(event):
button_arg = event.widget['text']
var_entry.insert(0,'end')
button1 = tk.Button(win,text = '1')
button1.bind("<Button-1>", handle_button)
button1.grid()
# similarly I defined all the buttons.
windows()
win.mainloop()
Upvotes: 1
Reputation: 15236
To get the behavior you are looking for all you need to do is:
Change this:
def handle_button(event):
return var.insert(0,4)
To this:
def handle_button(event):
var.set(4)
That said there are a few things wrong with your code that are not useful here.
Looking at return var.insert(0, 4)
. This return
is actually not doing anything useful here because what it is trying to do is return the results of calling var.insert(0, 4)
and assigning it to what ever called that function. 2 major problems with this. var.insert(0, 4)
is not going to return a useful value for the return command to help and 2nd you cannot return a result to the binding it has no use. Instead delete the return all together and just write the command used to update the StringVar. In this case var.set(4)
.
Looking at var_entry = tk.Entry(win,text='var',textvariable=var)
. The text = 'var'
is 100% useless here. In an entry field the argument text
is actually short for textvariable
so what is going on here is you are assigning the string var
to the text variable and then immediately reassigning the textvariable to the StringVar(). So lets rewrite that line to just var_entry = tk.Entry(win, textvariable=var)
.
Looking at button1 = tk.Button(win,text = '1' ,textvariable = 1)
you are doing something here that does nothing to help. textvariable = 1
has no purpose here. So lets just delete that. Rewrite that line as button1 = tk.Button(win, text='1')
Looking at button1.bind("<Button-1>", handle_button)
is overkill for something the button can handle with the command
argument. Delete this line entirely and rewrite the button1
to contain the command. Like this: button1 = tk.Button(win, text='1', command=handle_button)
Looking at def window():
we can remove this function and take its content and move it to the global name space. Right now there is no benefit to using a function to set up the GUI so instead lets remove the extra step.
With all that you should have something that looks like this:
import tkinter as tk
win = tk.Tk()
var = tk.StringVar()
var_entry = tk.Entry(win, textvariable=var)
var_entry.grid(row=1, column=2)
def handle_button():
var.set(4)
tk.Button(win, text='1', command=handle_button).grid(row=2, column=0)
win.mainloop()
I am not sure if you have heard of lambda
just yet but it can be used here to reduce our code just a little bit more. lambda
is used to create anonymous function and what that means is we can create one line functions that do not require us to define a function by name.
So if we delete the def handle_button():
function and then we change the button1
command to a lambda we can save our selves 2 more lines of code that is not really helping us or improving readability.
The new final code should look like this:
import tkinter as tk
win = tk.Tk()
var = tk.StringVar()
var_entry = tk.Entry(win, textvariable=var)
var_entry.grid(row=1, column=2)
tk.Button(win, text='1', command=lambda: var.set(4)).grid(row=2, column=0)
win.mainloop()
In making all these changes we cut your code in half to achieve the same results and it is a bit cleaner to read.
Upvotes: 0