Home > Net >  Is there a good way to add snapping to a ttk tkinter scale?
Is there a good way to add snapping to a ttk tkinter scale?

Time:07-19

I am trying to make a ttk themed Tkinter slider, by using the ttk.Scale widget. Problem is, that the resolution attribute that was found in the standard widget was removed here.

I have tried to do this in a very meh way, that is by simply setting the value of the slider to the rounded output. Example:

scale = ttk.Scale(frame, orient="horizontal", length=200,
                         from_=1, to=10, variable=foo,
                         command=lambda x: scale.set(round(float(x))))

The command section is what does all the work here. It sets the value of the scale to the rounded output.
Problem is, that it constantly spews out errors every tick the slider is held down, because it can not place the slider in its appropriate place. Note that visually and functionally, this solution works flawlessly, the only "problem" is the fact that it spits out errors. Of course, I could just silence these errors, but I really do not like handling problems like this that way.
This is the error it repeatedly spits out:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\foobar\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
    return self.func(*args)
  File "C:\foo\bar\main.py", line X, in <lambda>
    command=lambda x: scale.set(round(float(x))))
  File "C:\Users\foobar\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 3497, in set
    self.tk.call(self._w, 'set', value)
_tkinter.TclError

My question is: Is there a way to repeat this functionality, but without all the errors, or downgrading back to the standard tk widget?

CodePudding user response:

According to the document, the callback for command option will be triggered whenever the scale's value is changed via a widget command. So calling scale.set(...) will trigger the callback and so causing recursion issue.

Use the associated variable foo to update the value will fix it:

command=lambda x: foo.set(round(float(x)))
  • Related