Вопрос

I'm trying to register a system-wide hotkey that will trigger some action in my Tkinter program. I'm using this as reference. When I run the code from that link, it works fine. What I'm struggling with is integrating the loop there with the event loop in Tkinter.

The Tkinter loop needs to periodically check for the hotkey being pressed. This should be trivial, using root.after(). However, the program doesn't seem to pick up on the hotkey being pressed at all, not even when it's in focus.

Here is a succinct code example - it's as short as I could get it. It represents my attempts to modify the code from the link to play nicely with Tkinter.

from tkinter import *
import ctypes
from ctypes import wintypes
import win32con

user32 = ctypes.windll.user32
byref = ctypes.byref

def hotkey_handler(root):
    msg = wintypes.MSG()
    if user32.GetMessageA(byref(msg), None, 0, 0) != 0:
        if msg.message == win32con.WM_HOTKEY:
            if msg.wParam == 1:
                print("hotkey pressed")
    user32.TranslateMessage(byref(msg))
    user32.DispatchMessageA(byref(msg))
    root.after(1, hotkey_handler, root)

root = Tk()

if user32.RegisterHotKey(None, 1, win32con.MOD_SHIFT, ord("v")) != 0:
    print("--Hotkey registered!")

root.after(1, hotkey_handler, root)

root.mainloop()

One quirk I've noticed is that if I set the first argument of root.after() to zero, the GUI doesn't draw correctly and Python sometimes ends up crashing.

Это было полезно?

Решение

eryksun pointed out the problem - I was using the wrong case for the hotkey. ord("v") should have been ord("V").

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top