Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TkInter, slider: how to trigger the event only when the iteraction is complete?

Tags:

python

tkinter

I'm using the slider to update my visualization, but the command updateValue is sent everytime I move the slider thumb, even for intermediate values.

Instead I want to trigger it only when I release the mouse button and the interaction is complete.

self.slider = tk.Scale(self.leftFrame, from_=0, to=256, orient=tk.HORIZONTAL, command=updateValue)

How can I trigger the function only once, when the interaction is ended ?

like image 987
aneuryzm Avatar asked Oct 19 '10 07:10

aneuryzm


2 Answers

This is quite an ancient question now, but in case anyone stumbles upon this particular problem just use the bind() function and the "ButtonRelease-1" event like so:

import Tkinter as tk

class App:
    def __init__(self):
        self.root = tk.Tk()

        self.slider = tk.Scale(self.root, from_=0, to=256, 
                               orient="horizontal")
        self.slider.bind("<ButtonRelease-1>", self.updateValue)
        self.slider.pack()
        self.root.mainloop()

    def updateValue(self, event):
        print self.slider.get()

app=App()

Hope this helps anyone!

like image 89
dsoosh Avatar answered Nov 02 '22 10:11

dsoosh


You can't.

What you can do instead is have your command delay any real work for a short period of time using 'after'. Each time your command is called, cancel any pending work and reschedule the work. Depending on what your actual requirements are, a half second delay might be sufficient.

Another choice is to not use the built-in command feature and instead use custom bindings. This can be a lot of work to get exactly right, but if you really need fine grained control you can do it. Don't forget that one can interact with the widget using the keyboard in addition to the mouse.

Here's a short example showing how to schedule the work to be done in half a second:

import Tkinter as tk

#create window & frames
class App:
    def __init__(self):
        self.root = tk.Tk()
        self._job = None
        self.slider = tk.Scale(self.root, from_=0, to=256, 
                               orient="horizontal", 
                               command=self.updateValue)
        self.slider.pack()
        self.root.mainloop()

    def updateValue(self, event):
        if self._job:
            self.root.after_cancel(self._job)
        self._job = self.root.after(500, self._do_something)

    def _do_something(self):
        self._job = None
        print "new value:", self.slider.get()

app=App()
like image 8
Bryan Oakley Avatar answered Nov 02 '22 09:11

Bryan Oakley