I have writing the following code to get key pressed by the user:
class Key:
def __init__(self) -> None:
pass
# Define the function that will be called when a key is pressed.
def on_press(self, key: KeyType) -> None:
pass
# Define the function that will be called when a key is released.
def on_release(self, key: KeyType, queue: Queue, listener: Listener) -> None:
try:
# Put the character key in the queue.
queue.put(key.char)
# Stop the listener
listener.stop()
except AttributeError:
# Put non-character keys in the queue.
queue.put(key.name)
# Stop the listener
listener.stop()
def get_key(self, prompt_string: str) -> str:
'''
Prompts the user for a key.
Args:
prompt_string (str): A string representing the prompt to display to the user
Returns:
key (str): A key which the user pressed
Examples:
To prompt the user for a key and print the key that was pressed, use:
>>> key = get_key("Press a key: ")
>>> print("You pressed:", key)
'''
# Create a new queue object to hold the key value.
key_queue = Queue()
# Start a keyboard listener with the on_press and on_release functions.
# Use a lambda function to pass the queue object to the on_release function.
with Listener(on_press=self.on_press, on_release=lambda key: self.on_release(key, queue=key_queue, listener=listener)) as listener:
# Print the prompt string to the console.
# Use flush=True to ensure that the message is printed immediately.
# Use end='' to make sure that the next print statement is on the same line.
print(prompt_string, end='', flush=True)
# Initialize the key value to None.
key = None
# Keep looping until a key value has been retrieved from the queue.
while key is None:
key = key_queue.get()
# Return the key value to the calling function.
return key
I call the above code in a separate file after which I ask the user for a input using the input()
function.
# Get key to be autoclicked from user by calling get_key function with a prompt message.
button = key.get_key(f"{INPUT_COLOR}Key to be autoclicked (press any key): {RESET}")
# Print the button that the user has pressed.
print(USER_INPUT_COLOR + button + RESET)
# Get delay between key presses in seconds from user by calling get_input function with a prompt message.
delay = float(input(f"{INPUT_COLOR}Delay between key presses (in seconds): {USER_INPUT_COLOR}"))
print(f"{RESET}", end="")
But when the above code is executed I can press a button to enter a key for the button input but for the delay input when try to enter a float value like '0.1', it doesn't show anything that I am typing. Furthermore when I press enter after typing '0.1' it gives this error: ValueError: could not convert string to float: 'mqe0.1'
or other times the error changes to this: ValueError: could not convert string to float: 'kqer0.1'
.
After this the program naturally exists but I find that the terminal seems to be broken because whatever I type seems to not be displayed but it is there because when I enter the terminal responds to whatever I typed but doesn't show it.
Some extra info:
- I have checked and made sure all my imports and correct.
- the
f'{INPUT_COLOR}'
andf'{RESET}
are just constant values for ansi escape codes that I have defined in another file and they are not causing the issue. - the distro for linux that I am using is Zorin OS 16 which is built on Ubuntu 20.04.
- I am running the above code in bash terminal, which is provided by default when I installed Zorin (this is a relatively new install).
What I have tried:
I tried adding a listener.stop()
to the listener
for getting key presses but that doesn't change anything
Is this a problem with Pynput on linux or a problem with the code I have written? Any help would be appreciated!