Search code examples
pythontkinterlabeltkinter-entry

Updating a label from an entry field on button push with tkinter in Python 3.5.2


I am trying to create a window with a line label, an entry field, a current value label, and an "Update Value" button.

Here is an example:

enter image description here

This is what I have so far. I can get the entered value to print to console, but I can't seem to work out how to get an entered value and change the currentValue Label to reflect that value by pressing the button:

from tkinter import*
main=Tk()

#StringVar for currentValue in R0C2
currentValue = StringVar(main, "0")

#Called by the setValues button, looks for content in the entry box and updates the "current" label
def setValues():
        content = entry.get()
        print(content)


#This kills the program
def exitProgram():
        exit()

#Title and window size
main.title("Title")
main.geometry("350x200")

#Descriptions on the far left
Label(main, text="Duration (min): ").grid(row=0, column=0)

#Entry boxes for values amidship
entry=Entry(main, width=10)
entry.grid(row=0, column=1)

#Displays what the value is currently set to.
currentValue = Label(textvariable=currentValue)
currentValue.grid(row=0,column=2)

#Takes any inputted values and sets them in the "Current" column using def setValues
setValues=Button(text='Set Values',width=30,command=setValues)
setValues.grid(row=9, column=0, columnspan=2)

#Red button to end program
exitButton=Button(main, text='Exit Program',fg='white',bg='red',width=30, height=1,command=exitProgram)
exitButton.grid(row=20, column = 0, columnspan=2)
main.mainloop()

Solution

  • There are a couple of problems with your code.

    Firstly, you are overwriting the setValues function with the setValues Button widget, and similarly, you are overwriting the currentValue StringVar with the currentValue Label.

    To set a StringVar, you use its .set method.

    Don't use plain exit in a script, that's only meant to be used in an interactive interpreter session, the proper exit function is sys.exit. However, in a Tkinter program you can just call the .destroy method of the root window.

    Here's a repaired version of your code.

    import tkinter as tk
    main = tk.Tk()
    
    #StringVar for currentValue in R0C2
    currentValue = tk.StringVar(main, "0")
    
    #Called by the setValues button, looks for content in the entry box and updates the "current" label
    def setValues():
        content = entry.get()
        print(content)
        currentValue.set(content)
    
    #This kills the program
    def exitProgram():
        main.destroy()
    
    #Title and window size
    main.title("Title")
    main.geometry("350x200")
    
    #Descriptions on the far left
    tk.Label(main, text="Duration (min): ").grid(row=0, column=0)
    
    #Entry boxes for values amidship
    entry = tk.Entry(main, width=10)
    entry.grid(row=0, column=1)
    
    #Displays what the value is currently set to.
    currentValueLabel = tk.Label(textvariable=currentValue)
    currentValueLabel.grid(row=0,column=2)
    
    #Takes any inputted values and sets them in the "Current" column using def setValues
    setValuesButton = tk.Button(text='Set Values',width=30,command=setValues)
    setValuesButton.grid(row=9, column=0, columnspan=2)
    
    #Red button to end program
    exitButton = tk.Button(main, text='Exit Program',fg='white',bg='red',width=30, height=1,command=exitProgram)
    exitButton.grid(row=20, column = 0, columnspan=2)
    main.mainloop()
    

    BTW, it's a Good Idea to avoid "star" imports. Doing from tkinter import * dumps 130 names into your namespace, which is unnecessary and creates the possibility of name collisions, especially if you do star imports from several modules. It also makes the code less readable, since the reader has remember which names you defined and which ones came from the imported module(s).