Search code examples
pythontkinterttktkinter-scale

How to retrieve the integer value of tkinter ttk Scale widget in Python?


Could anyone advise how to retrieve and update a Label widget with the value from a Scale widget in Python? Currently it shows a very large real number. I have tried to type cast the value but this only works when I print to idle. I tried slider.get() but the label is blank. Also tried int(slider.get()) which works when I print to idle.

from tkinter import *
from tkinter import ttk

root = Tk()
root.title("Playing with Scales")

mainframe = ttk.Frame(root, padding="24 24 24 24")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))

slider = IntVar()

ttk.Scale(mainframe, from_=0, to_=100, length=300,  variable=slider).grid(column=1, row=4, columnspan=5)
ttk.Label(mainframe, textvariable=slider).grid(column=1, row=0, columnspan=5)

for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)


root.mainloop()

Here you can see the very large real value:

screenshot


Solution

  • I don't see a way to control the resolution of the Scale widget, but it's fairly easy to modify the string it produces. According to these ttk docs the Scale widget returns a float, but in my experiments it returns a string, which is slightly annoying.

    Rather than setting the Label text directly from the slider variable attached to the Scale widget we can bind a command to the Scale widget that converts the string holding the Scale's current value back to a float, and then format that float with the desired number of digits; the code below displays 2 digits after the decimal point.

    import tkinter as tk
    from tkinter import ttk
    
    root = tk.Tk()
    root.title("Playing with Scales")
    
    mainframe = ttk.Frame(root, padding="24 24 24 24")
    mainframe.grid(column=0, row=0, sticky=('N', 'W', 'E', 'S'))
    
    slider = tk.StringVar()
    slider.set('0.00')
    
    ttk.Scale(mainframe, from_=0, to_=100, length=300, 
        command=lambda s:slider.set('%0.2f' % float(s))).grid(column=1, row=4, columnspan=5)
    
    ttk.Label(mainframe, textvariable=slider).grid(column=1, row=0, columnspan=5)
    
    for child in mainframe.winfo_children(): 
        child.grid_configure(padx=5, pady=5)
    
    root.mainloop()
    

    If you just want the Label to display the integer value then change the initialization of slider to

    slider.set('0')
    

    and change the callback function to

    lambda s:slider.set('%d' % float(s))
    

    I've made a few other minor changes to your code. Primarily, I replaced the "star" import with import tkinter as tk; the star import brings in over 130 names into your namespace, which creates a lot of unnecessary clutter, as I mentioned in this recent answer.