2

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

finefoot
  • 9,914
  • 7
  • 59
  • 102
Mixstah
  • 411
  • 1
  • 7
  • 22
  • 1
    That's not a large real number, it just has a lot of digits after the decimal point, but I guess that makes it look messy. 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; I'll post some code shortly. – PM 2Ring Jul 03 '16 at 08:10

2 Answers2

4

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.

Community
  • 1
  • 1
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
  • 1
    @BillalBEGUERADJ: Ah, good point. I neglected to re-read the question's title. :) – PM 2Ring Jul 03 '16 at 08:28
  • Thank you. I thought I had tried adding a command to the scale but maybe not. Works perfectly; I did just want the integer :) – Mixstah Jul 03 '16 at 20:03
3

An other less complicated option and easy to use alternative is to use an instance of tkinter.Scale() class with which you can inject the resolution option to whatever value you want. The default one is the one you are looking for because its value is 1

Billal Begueradj
  • 20,717
  • 43
  • 112
  • 130
  • 1
    Good advice; I was almost going to suggest that myself, but I decided to see what I could do with ttk. I've only recently installed Python 3, and I've never used ttk before. – PM 2Ring Jul 03 '16 at 08:34
  • Yes thanks for this. I did manage it with tkinter but the GUI is more modern in ttk but less documented which is why I got stuck I think. – Mixstah Jul 03 '16 at 19:56