使用全局热键切换到Tkinter程序焦点
我想注册一个全局热键,这样在我的Tkinter程序中按下这个热键就能触发一些操作。我参考了这个链接。当我运行那个链接里的代码时,一切都正常。但我现在遇到的问题是,怎么把那个循环和Tkinter的事件循环结合起来。
Tkinter的循环需要定期检查热键是否被按下。这应该很简单,可以用root.after()
来实现。不过,程序似乎根本没有检测到热键被按下,即使在窗口聚焦的时候也没有。
这里有一个简短的代码示例——我尽量把它缩短到最简洁的形式。这段代码是我尝试修改链接中的代码,以便能和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()
我注意到一个奇怪的现象,如果我把root.after()
的第一个参数设为零,GUI就不会正确显示,有时Python还会崩溃。
1 个回答
1
eryksun 指出了问题所在 - 我使用了错误的字母大小写来设置快捷键。ord("v")
应该改成 ord("V")
。