Just like Ctl, Alt + delete
I want to write a program, which uses global hotkeys with 3 or more arguments in python. The assigned function should only perform when I press all three keys on my keyboard. For example alt, windows and F3.
win32con.VK_F3, win32con.MOD_WIN, win32con.VK_F5
This is the current program I want to run, however its output is:
Traceback (most recent call last):
File "C:\Python32\Syntax\hot keys\hotkeys2.py", line 41, in <module>
for id, (vk, modifiers) in HOTKEYS.items ():
ValueError: too many values to unpack (expected 2)
The Program:
import os
import sys
import ctypes
from ctypes import wintypes
import win32con
byref = ctypes.byref
user32 = ctypes.windll.user32
HOTKEYS = {
1 : (win32con.VK_F3, win32con.MOD_WIN, win32con.VK_F5),
2 : (win32con.VK_F4, win32con.MOD_WIN),
3 : (win32con.VK_F2, win32con.MOD_WIN)
}
def handle_win_f3 ():
#os.startfile (os.environ['TEMP'])
print ("Hello WOrld! F3")
def handle_win_f4 ():
#user32.PostQuitMessage (0)
print ("Hello WOrld! F4")
def handle_win_f1_escape ():
print("exit")
sys.exit()
HOTKEY_ACTIONS = {
1 : handle_win_f3,
2 : handle_win_f4,
3 : handle_win_f1_escape
}
for id, (vk, modifiers) in HOTKEYS.items ():
print ("Registering id", id, "for key", vk)
if not user32.RegisterHotKey (None, id, modifiers, vk):
print ("Unable to register id", id)
try:
msg = wintypes.MSG ()
while user32.GetMessageA (byref (msg), None, 0, 0) != 0:
if msg.message == win32con.WM_HOTKEY:
action_to_take = HOTKEY_ACTIONS.get (msg.wParam)
#print(" msg.message == win32con.WM_HOTKEY:")
if action_to_take:
action_to_take ()
user32.TranslateMessage (byref (msg))
user32.DispatchMessageA (byref (msg))
finally:
for id in HOTKEYS.keys ():
user32.UnregisterHotKey (None, id)
print("user32.UnregisterHotKey (None, id)")
Registering 3 hotkeys? Possible? Explains how one can use assign one key that needs to be pressed and then if two of which either needs to be pressed. However I won’t that the function only performs when all there are pressed simultaneously. I took
For starters, if you wanted alt, windows and F3, wouldn't you need to use win32con.VK_F3, win32con.MOD_ALT, win32con.MOD_WIN
for the HOTKEYS
entry?
However, it doesn't really make sense to say press F3 with modifiers of the Win and F5 key.
The error on the line:
for id, (vk, modifiers) in HOTKEYS.items ():
is because the value of each dictionary entry is a variable length tuple
. Here's a way to handle that which also bitwise OR s all the modifier values together in preparation for passing them as a single argument to RegisterHotKey()
.
from functools import reduce
for id, values in HOTKEYS.items ():
vk, modifiers = values[0], reduce (lambda x, y: x | y, values[1:])
print ("Registering id", id, "for key", vk)
if not user32.RegisterHotKey (None, id, modifiers, vk):
print ("Unable to register id", id)
It would have been easier to work on your problem if your code was indented properly and followed the PEP 8 -- Style Guide for Python Code recommendations. Please consider doing so in the future.