Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I control keyboard repeat delay in a Tkinter root window?

This simple application almost does what I want:

import Tkinter as Tk

def hello(x):
    print "Hello"

root = Tk.Tk()
root.bind("<Up>", hello)
root.mainloop()

I mash down the up arrow, it prints "Hello" over and over. However, there is a delay before this repetition begins, and the repetition rate is slower than I want. How can I set this repeat delay to zero? How can I control the repeat interval?

I know that other Tkinter widgets have configuration options for 'repeatdelay' and 'repeatinterval', but I can't seem to find one for a Tkinter root window.

(I'm looking in your direction, Bryan Oakley)

like image 240
Andrew Avatar asked Oct 20 '25 17:10

Andrew


2 Answers

This is not something configurable in Tk -- Tk has no control over how fast the keyboard driver sends repeated key events.

What you can do instead is have a binding on the button press and button release to set and then unset a flag. Then, you can write a function that does whatever you want it to do, then check the flag and call itself again after whatever delay you want.

The function would look something like this:

def hello(x):
    global SHOULD_REPEAT
    print "hello"
    if SHOULD_REPEAT:
        root.after(10, hello) # wait 10ms then repeat

To do it right requires a little bit more logic, but that's the general idea.

like image 114
Bryan Oakley Avatar answered Oct 23 '25 05:10

Bryan Oakley


Below is a complete example based on Bryan's answer in this post:

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # either in python 2 or in python 3
except ImportError:
    import Tkinter as tk


def step(*event):
    label['text'] += 1


    if label._repeat_on:
        root.after(label._repeat_freq, step)


def stop(*event):
    if label._repeat_on:
        label._repeat_on = False
        root.after(label._repeat_freq + 1, stop)
    else:
        label._repeat_on = True


if __name__ == '__main__':
    root = tk.Tk()
    label = tk.Label(root, text=0)
    label._repeat_freq = 10
    label._repeat_on = True

    root.bind('<KeyPress-s>', step)
    root.bind('<KeyRelease-s>', stop)

    label.pack()
    root.mainloop()
like image 26
Nae Avatar answered Oct 23 '25 06:10

Nae



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!