Clever Hotkey Debouncing in Sikuli

Asked by Jonathan on 2017-12-15

In your docs, I suggest you update the pattern for hotkey debouncing. The old pattern ends up creating a variable and an "IF" check for every single new hotkey added, and is somewhat tedious. I suggest using a clever python trick of function passing and lambdas. Here is a better pattern. With this pattern, to add a new hotkey, you simply add a function and addHotKey() and DONE:

doing = None
def do(command):
    global doing
    doing = command

running = True
def quitSikuli(e):
    global running
    running = False

def helloWorld():
    popup("Hello World")

Env.addHotkey("x", KeyModifier.ALT+KeyModifier.CTRL, quitSikuli)
Env.addHotkey("c", KeyModifier.ALT+KeyModifier.CTRL, lambda e: do(helloWorld))

while running:
    if doing:
        doing = None

Question information

English Edit question
Sikuli Edit question
No assignee Edit question
Last query:
Last reply:
RaiMan (raimund-hocke) said : #1

thanks for the inspiration.

... but I do not agree with your opinion about the current example in the docs: it is one of many possible setups, that wants to keep all processing in the main part of the script with the option to decide, at what place in the main workflow one wants to process the intention of the hotkey or even ignore it at this time.

your example:
of course an example of using lambdas and functions (... but this is normal Python - by no way a trick).
... but to get what you want, not needed.

the minimum solution (using a lambda to exit the script from the handler - brute force lite):

Env.addHotkey("x", KeyModifier.ALT+KeyModifier.CTRL, lambda e: exit())

def helloWorld(e):
    popup("Hello World")
Env.addHotkey("c", KeyModifier.ALT+KeyModifier.CTRL, helloWorld)

# this loop is not necessary, it only stands for some
# time consuming main workflow to keep this example running
while true:

... true for this also: you simply add a function and addHotKey()

lambdas instead of a function name in addHotKey() only make sense if:
- you want to decide about the visited handler function at runTime
- and/or you want to handover parameters to your handler (instead of using globals)

I will add an additional example to the docs show these more sophisticated cases.

Nevertheless thanks again for your efforts and the feedback.

Can you help with this problem?

Provide an answer of your own, or ask Jonathan for more information if necessary.

To post a message you must log in.