0

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'

4
  • 2
    What does "it's not working" mean? Does it mean "the code throws a NameError: name 'windows' is not defined"? Or does it mean "the code throws a AttributeError: 'StringVar' object has no attribute 'insert'"? Or something else? Commented May 25, 2018 at 16:45
  • error shows AttributeError: 'StringVar' object has no attribute 'insert' Commented May 25, 2018 at 16:49
  • Why do you think that var has an insert method? What do you think it means to insert into a variable? Did you try var_entry.insert(0,4)? Commented May 25, 2018 at 17:07
  • 1
    StringVar() uses set() to change the value. Commented May 25, 2018 at 18:29

3 Answers 3

1

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()
Sign up to request clarification or add additional context in comments.

Comments

0

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.

  1. 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).

  2. 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).

  3. 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')

  4. 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)

  5. 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.

Comments

0

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

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.