TkInter,slider:如何在迭代完成时触发事件?

ane*_*yzm 6 python tkinter

我正在使用滑块更新我的可视化,但每次移动滑块时都会发送命令updateValue,即使是中间值也是如此.

相反,我只想在释放鼠标按钮并完成交互时触发它.

self.slider = tk.Scale(self.leftFrame, from_=0, to=256, orient=tk.HORIZONTAL, command=updateValue)
Run Code Online (Sandbox Code Playgroud)

当交互结束时,如何仅触发一次该功能?

小智 28

这是一个相当古老的问题,但是如果有人偶然发现这个特定问题,只需使用bind()函数和"ButtonRelease-1"事件,如下所示:

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()
Run Code Online (Sandbox Code Playgroud)

希望这有助于任何人!

  • 谨防!如果Scale.takefocus为True,那么人们将只能使用键盘箭头键移动滑块.**但是没有任何事情会发生**因为你只是抓住鼠标点击.要解决问题,也要抓住按键.(您可以为单个回调绑定多个事件) (5认同)

Bry*_*ley 6

你不能

您可以做的是使命令使用“ after”在短时间内延迟任何实际工作。每次调用您的命令时,取消所有待处理的工作并重新安排工作。根据您的实际要求,半秒的延迟可能就足够了。

另一个选择是不使用内置命令功能,而使用自定义绑定。要完全正确,这可能需要大量工作,但是如果您确实需要细粒度的控制,则可以做到。不要忘记,除了鼠标之外,还可以使用键盘与小部件进行交互。

这是一个简短的示例,显示了如何安排工作在半秒内完成:

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()
Run Code Online (Sandbox Code Playgroud)