key.char gives AttributeError when using Key.f5 in Python Pynput
Im trying to make a very simple program that presses the F5 key when I press another key (example q). Whenever I use regular characters a-z I compare using
if key.char == 'q':
This works fine until I introduce Key.f5
(or any other Key.
)
if key.char == 'q':
keyboard.press(Key.f5)
keyboard.release(Key.f5)
I then get this error:
if f(*args) is False:
File "C:\Users\lkl\Desktop\combination-1.py", line 17, in on_release
if key.char == 'q':
AttributeError: 'Key' object has no attribute 'char'
I have tried renaming key
to key1
and other names. I have tried to create a controller called keyboard1
and other names. I have tried to isolate the following code in its own function:
keyboard.press(Key.f5)
keyboard.release(Key.f5)
I have tried to catch the error with Try Except statements. The Error still comes. And it ends the execution.
I have tried avoid to key.char
by simply comparing key with the Unicode and html code for the character. This triggers no action when pressing q
if key == 'U+0071':
The thing is, the program executes the F5
command even when I use key.char
but the AttributeError stops the program.
I am able to make this run:
if key == Key.shift_l:
keyboard.press(Key.f5)
keyboard.release(Key.f5)
but I need the key to be a simple a-z key, because the machine is receiving the key through a keylogger on a seperate machine. And it can only send/receive non-special keys. eg. numbers and letters.
This is completely wrinkling my brain. I can't find a single way to send F5
while listening for 'q'
.
Here is the full code:
from pynput.mouse import Listener as ms
from pynput.keyboard import Listener as kb
from pynput.keyboard import Key, Controller
import os
import sys
import subprocess
keyboard = Controller()
def on_press(key):
print('{0} pressed'.format(
key))
def on_release(key):
print('{0} release'.format(
key))
if key.char == 'q':
keyboard.press(Key.f5)
keyboard.release(Key.f5)
if key == "a":
subprocess.call("C:/Users/lkl/Desktop/fastsafelargetest - Copy.vbs", shell=True)
if key == 'z':
subprocess.call("C:/Users/lkl/Desktop/autofill.vbs", shell=True)
if key == Key.esc:
return False
def on_click(x, y, button, pressed):
if pressed:
pass
else:
#subprocess.call("C:/Users/lkl/Desktop/fastsafelargetest - Copy.vbs", shell=True)
print('Released')
def on_scroll(x, y, dx, dy):
print('Scrolled {0}'.format(
(x, y)))
# Collect events until released
with ms(
on_click=on_click,
on_scroll=on_scroll) as listener:
with kb(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
Based on @jim-todd answer i found the python module "keyboard". Its not a very elegant solution but it technically provides a workaround for the problem. I use this line to check for key input:
keyboard.is_pressed('q'):
rename my pynput controller to keyboard1
keyboard1 = Controller()
And the entire code for this problem can look like this (not all imports here are necessary).
from pynput.mouse import Listener as ms
from pynput.keyboard import Listener as kb
from pynput.keyboard import Key, Controller
import keyboard
import os
import sys
import subprocess
import time
keyboard1 = Controller()
def on_press(key):
while keyboard.is_pressed('q'):
keyboard1.press(Key.f5)
keyboard1.release(Key.f5)
print('{0} pressed'.format(
key))
time.sleep(0.05)
break
if key == Key.esc:
return False
with ms() as listener:
with kb(
on_press=on_press) as listener:
listener.join()