按住tkinter按钮时尝试保持功能恒定运行

时间:2018-07-09 20:13:21

标签: python python-3.x tkinter

我目前在tkinter中有一个按钮,可以在释放按钮时运行功能。我需要按钮在按住按钮的整个过程中不断以一定的速率不断增加一个数字。

global var
var=1
def start_add(event,var):
    global running
    running = True
    var=var+1
    print(var)
    return var

def stop_add(event):
    global running
    print("Released")
    running = False
button = Button(window, text ="Hold")
button.grid(row=5,column=0)
button.bind('<ButtonPress-1>',start_add)
button.bind('<ButtonRelease-1>',stop_add)

我不必一定要在释放按钮时运行任何功能,只要有帮助就可以按住按钮。非常感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

没有内置的函数可以做到这一点,但是创建自己的Button可以很容易。您也走在正确的轨道上,唯一缺少的是需要使用after进行循环,并使用after_cancel停止循环:

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk

class PaulButton(tk.Button):
    """
    a new kind of Button that calls the command repeatedly while the Button is held
    :command: the function to run
    :timeout: the number of milliseconds between :command: calls
      if timeout is not supplied, this Button runs the function once on the DOWN click,
      unlike a normal Button, which runs on release
    """
    def __init__(self, master=None, **kwargs):
        self.command = kwargs.pop('command', None)
        self.timeout = kwargs.pop('timeout', None)
        tk.Button.__init__(self, master, **kwargs)
        self.bind('<ButtonPress-1>', self.start)
        self.bind('<ButtonRelease-1>', self.stop)
        self.timer = ''

    def start(self, event=None):
        if self.command is not None:
            self.command()
            if self.timeout is not None:
                self.timer = self.after(self.timeout, self.start)

    def stop(self, event=None):
        self.after_cancel(self.timer)

#demo code:
var=0
def func():
    global var
    var=var+1
    print(var)

root = tk.Tk()
btn = PaulButton(root, command=func, timeout=100, text="Click and hold to repeat!")
btn.pack(fill=tk.X)
btn = PaulButton(root, command=func, text="Click to run once!")
btn.pack(fill=tk.X)
btn = tk.Button(root, command=func, text="Normal Button.")
btn.pack(fill=tk.X)

root.mainloop()

如@ rioV8所述,after()调用不是非常准确。如果将超时设置为100毫秒,则通常可以在两次调用之间的100到103毫秒之间找到期望值。按住按钮的时间越长,这些错误就会越多。如果要精确计时按钮的按下时间,则需要使用其他方法。

答案 1 :(得分:0)

@Novel的答案在我看来应该行得通,但是这与您尝试的方式更加相似,不需要全新的课程:

from tkinter import *
INTERVAL=5 #miliseconds between runs
var=1
def run():
    global running, var
    if running:
        var+=1
        print(var)
        window.after(INTERVAL, run)

def start_add(event):
    global running
    running = True
    run()

def stop_add(event):
    global running, var
    print("Released")
    running = False

window=Tk()
button = Button(window, text ="Hold")
button.grid(row=5,column=0)
button.bind('<ButtonPress-1>',start_add)
button.bind('<ButtonRelease-1>',stop_add)
mainloop()