Search code examples
pythontkintergetslider

How to get scale value with button press tkinter?


I really did my best to find the solution on my own, but haven't. I want to have the value from a slider and then save it to a csv file (which is working fine), at the click of a button. Alas, I can't get the value of the tkinter.Scale during my button event. I wonder if it global variables might solve my problem, but I haven't gotten them to work. I'm particularly surprised because I can print a live stream of the scale's value as I change it, but can't save it in a useful way. If you could answer any of my befuddlement or let me know if my question is unclear or in anyway could be better, I'd greatly appreciate it. Here are some links to things that helped me get this far:

https://www.programiz.com/python-programming/global-local-nonlocal-variables

Tkinter - Get the name and value of scale/slider

Here is my attempt to print the final value 10 times:

from tkinter import *
root = Tk()

def scaleevent(v):    #Live update of value printed to shell
    print(v)
    variable = v

def savevalue():
    global variable              #This is what I want to work, but doesn't
    for i in range(10):
        print(variable)

scale = Scale(orient='vertical', command=scaleevent).grid(column=0,row=0)
button = Button(text="button", command=savevalue).grid(column=1, row=0)

root.mainloop()

And here is my attempt to solve my problem using .get():

from tkinter import *
root = Tk()

def savevalue():        #print value 10 times. In final version I will save it instead
    for i in range(10):
        print(scale.get())     #I really want this to work, but it doesn't,
    root.destroy               #is it because .get is in a function?

scale = Scale(orient='vertical', command=scaleevent).grid(column=0,row=0)
button = Button(text="button", command=savevalue).grid(column=1, row=0)

root.mainloop()

(Python 3.5, Windows 10)

Edit:

This is the error I get from the first attempt using a global variable:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Me\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 1550, in __call__
    return self.func(*args)
  File "C:\Users\Me\Documents\programing\tkinter scale question.py", line 15, in savevalue
    print(variable)
NameError: name 'variable' is not defined

That's what happened when I run the first example of code, and similarly my actual project. Thanks Bryan Oakley!


Solution

  • You have to use global in scaleevent because you try to assing value to variable. Without global it assigns v to local variable and then it doesn't exists in savevalue

    from tkinter import *
    
    root = Tk()
    
    def scaleevent(v):
        global variable
    
        print(v)
        variable = v
    
    def savevalue():
        print(variable)
    
    Scale(orient='vertical', command=scaleevent).grid(column=0,row=0)
    Button(text="button", command=savevalue).grid(column=1, row=0)
    
    root.mainloop()
    

    As for second version you made mistake with var = Widget(...).grid()

    It assigns None to var because grid()/pack()/place() returns None.
    You have to do it in two lines:

    var = Widget(...)
    var.grid(...)
    

    Code

    from tkinter import *
    
    root = Tk()
    
    def savevalue():
        print(scale.get())
        root.destroy() # you forgot ()
    
    scale = Scale(orient='vertical')
    scale.grid(column=0,row=0)
    
    button = Button(text="button", command=savevalue)
    button.grid(column=1, row=0)
    
    root.mainloop()