-
-
Save m10x/a9a2eb296fab2106a5ae7c16b8874a4b to your computer and use it in GitHub Desktop.
Global hot keys in Python for Win32, fixed range and missing brackets, implemented that you can now reassign a key without error, works now perfectly with Python 3.X. Added method to unregister. Accomplished PEP 8 compliance.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from ctypes import windll | |
from ctypes import byref as ctypes_byref | |
from ctypes.wintypes import MSG as wintypes_MSG | |
import win32con | |
class GlobalHotKeys(object): | |
key_mapping = [] | |
user32 = windll.user32 | |
MOD_ALT = win32con.MOD_ALT | |
MOD_CTRL = win32con.MOD_CONTROL | |
MOD_CONTROL = win32con.MOD_CONTROL | |
MOD_SHIFT = win32con.MOD_SHIFT | |
MOD_WIN = win32con.MOD_WIN | |
@classmethod | |
def register(cls, vk, keyname, modifier=0, func=None): | |
indexof = [i for i, s in enumerate(cls.key_mapping) if vk in s] | |
if indexof != []: | |
del cls.key_mapping[indexof[0]] | |
# Called as a decorator? | |
if func is None: | |
def register_decorator(f): | |
cls.register(vk, keyname, modifier, f) | |
return f | |
return register_decorator | |
else: | |
cls.key_mapping.append((vk, keyname, modifier, func)) | |
@classmethod | |
def unregister(cls, vk): # use vk number to delete from key_mapping | |
indexof = [i for i, s in enumerate(cls.key_mapping) if vk in s] | |
if indexof != []: | |
del cls.key_mapping[indexof[0]] | |
@classmethod | |
def listen(cls): | |
""" | |
Start the message pump | |
""" | |
for index, (vk, keyname, modifiers, func) in enumerate(cls.key_mapping): | |
if not cls.user32.RegisterHotKey(None, index, modifiers, vk): | |
# raise Exception('Unable to register hot key: ' + str(vk)) | |
input("Can't assign {} as hotkey. Press Enter to continue...".format(keyname[3:])) | |
for index, (vk, keyname, modifiers, func) in enumerate(cls.key_mapping): | |
cls.user32.UnregisterHotKey(None, index) | |
return | |
try: | |
msg = wintypes_MSG() | |
while cls.user32.GetMessageA(ctypes_byref(msg), None, 0, 0) != 0: | |
if msg.message == win32con.WM_HOTKEY: | |
(vk, keyname, modifiers, func) = cls.key_mapping[msg.wParam] | |
if not func: | |
break | |
func() | |
cls.user32.TranslateMessage(ctypes_byref(msg)) | |
cls.user32.DispatchMessageA(ctypes_byref(msg)) | |
finally: | |
for index, (vk, keyname, modifiers, func) in enumerate(cls.key_mapping): | |
cls.user32.UnregisterHotKey(None, index) | |
@classmethod | |
def _include_defined_vks(cls): | |
for item in win32con.__dict__: | |
item = str(item) | |
if item[:3] == 'VK_': | |
setattr(cls, item, win32con.__dict__[item]) | |
@classmethod | |
def _include_alpha_vks(cls): | |
for key_code in (range(ord('A'), ord('Z') + 1)): | |
setattr(cls, 'VK_' + chr(key_code), key_code) | |
@classmethod | |
def _include_numeric_vks(cls): | |
for key_code in (range(ord('0'), ord('9') + 1)): | |
setattr(cls, 'VK_' + chr(key_code), key_code) | |
GlobalHotKeys._include_defined_vks() | |
GlobalHotKeys._include_alpha_vks() | |
GlobalHotKeys._include_numeric_vks() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from globalhotkeys import GlobalHotKeys | |
@GlobalHotKeys.register(GlobalHotKeys.VK_F1, "VK_F1", GlobalHotKeys.MOD_SHIFT) | |
def hello_world(): | |
print ("Hello World!") | |
@GlobalHotKeys.register(GlobalHotKeys.VK_F2, "VK_F2",) | |
def hello_world_2(): | |
print ("Hello World again?") | |
# Q and ctrl will stop message loop | |
GlobalHotKeys.register(GlobalHotKeys.VK_Q, "VK_Q", 0, False) | |
GlobalHotKeys.register(GlobalHotKeys.VK_C, "VK_C", GlobalHotKeys.MOD_CTRL, False) | |
GlobalHotKeys.unregister(GlobalHotKeys.__dict__.get("VK_F1")) | |
# start main loop | |
GlobalHotKeys.listen() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment