I am trying to write a Python program that reads input from the command line like the input builtin function. I would also like to be able to detect key presses of certain keys (such as the home, end, page up, page down, function keys, etc.) When one of those keys is pressed I would like to fire off an event (i.e. call a mapped function). Other keys should go into a buffer to be returned when enter is pressed (i.e. act like the input built in). Finally I would like this to be cross platform and run on the command line.
Effectively I would like to be able to scroll a table down a page when the page down key is entered and still return the text from the input line when enter is hit.
I have found any number of solutions that don't fit all of these criteria:
input builtin - doesn't detect special keys and doesn't return until enter entered
curses - not shipped with Windows
msvcrt.getch - Windows only
tkinter - doesn't run on command line
readline - can't remap the standard navigation keys (such as home and end). When I bind these keys it still performs the vi or emacs navigation function
Any help would be appreciated.
You can download the keyboard module in python
pip3 install keyboard
You can then code as
import keyboard #Using module keyboard
while True: #making a loop
try: #used try so that if user pressed other than the given key error will not be shown
if keyboard.is_pressed('a'): #if key 'a' is pressed
print('You Pressed A Key!')
break #finishing the loop
else:
pass
except:
break #if user pressed other than the given key the loop will
break
Related
import keyboard
import pygame
import mouse
import time
def press_X():
time.sleep(0.2)
keyboard.press('x')
time.sleep(0.6)
keyboard.release('x')
print('Command Executed - press_X')
#SA_R_X V_1.0
#------------------------------------------
while True:
try:
keyboard.add_hotkey('r', press_X)
time.sleep(0.5)
break
except:
keyboard.add_hotkey('r', press_X)
time.sleep(0.5)
break
the problem is the code cannot detect if 'r' is pressed when i am holding 'w' and/or 'space'... (well any key really)
I tried to use a try and except to handle a combination of any key + 'r'. But it did not work. All I need is for the code to be able to detect an 'r' input even if I am pressing/ holding another key at the same time. Then after this the code waits 0.2 seconds before holding down the 'x' key for 0.6 seconds and releasing. Any help is appreciated and it would be very helpful if you included a short explanation on where I went wrong and how you fixed it.
The documentation for this module can be found here. This is where all relevant information can be found.
The best way to do this, from my understanding, is to use an alternative function. If you want the program to continue to run, even though the key has not been pressed, then I suggest using the keyboard.on_press_key() function. This would mean that the rest of your program could still run, and your press_X() function could be run as a callback. Here is an example of how this code could be implemented.
import keyboard
import pygame
import mouse
import time
class App:
running = True
def press_X():
time.sleep(0.2)
keyboard.press('x')
time.sleep(0.6)
keyboard.release('x')
print('Command Executed - press_X')
App.running = False
#SA_R_X V_1.0
#------------------------------------------
keyboard.on_press_key('r', lambda x: press_X()) ## Adds an event listener for the r key
## This will stop execution if there is no code after this point
If you want it to stop the program and wait for the r key to be pressed, then you could use keyboard.wait(). This will basically pause your program until the key is pressed, after which your function would be run. For example, to replace the keyboard.on_press_key('r', lambda x: press_X()):
keyboard.wait('r')
press_X()
From my understanding, keyboard.add_hotkey() does not work in your situation because it is looking for an exact combination of keys being pressed, such as Ctrl+C, and will only go if only the keys in the hotkey are pressed.
I hope this helps, good luck!
I'm using Windows, Python, and PyAutoGUI to try to automate some activities in Minecraft as a fun project.
I have been successful with using PyAutoGUI to switch to Minecraft once I start the script in Visual Studio Code, click on the "Back to Game" button, and then move the avatar forward by holding the "w" key.
I am using a 3rd party program called "NeatMouse" to use my numpad keys in place of using a mouse. The numpad 8 button is equivalent to moving the mouse up, which in Minecraft causes your avatar to look up. When I press this button myself in Minecraft, it works as expected, so it must be the case that NeatMouse is not the problem.
When I try to have PyAutoGUI replicate this same key press, it seems like nothing is happening.
I have tried different combinations of
pag.press()
pag.hold()
pag.keyDown() & pag.keyUp()
These functions do work for the WASD keys, so I know that Minecraft is able to receive keyboard input from PyAutoGUI, so that generally must not be the problem.
Here is a sample code block of what I have tried.
import pyautogui as pag
def align_vertical_facing_axis(target):
facing = get_facing_axes()[1]
# Looking down
if facing > target:
print('torture')
pag.keyDown('num8')
sleep(1)
pag.keyUp('num8')
get_facing_axes() is a function I wrote to retrieve the axes the avatar is facing as a tuple from the Minecraft debug screen. A positive value in the [1] index means the character is looking at a downward angle. When I run this script, it does print "torture" to my console so I know for sure it is entering that "if" block.
That was the long version of the explanation, the short version is: PyAutoGUI won't press the numpad keys, what do??
After some research, pyautogui.platformModule contains the mappings for numpad.
Here are the windows key mappings: https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
import pyautogui as pag
#This is where you update key mappings, num8 is now referring to the virtual key code VK_NUMPAD8 or 0x68
pag.platformModule.keyboardMapping.update({'num8':0x68})
#To call it, you use the mapping name you gave to the virtual key code
pag.press('num8')
Use the list I gave you for other key mapping values such as 0x68 for num8 and so on.
Im trying to do a simple bot with using python keyboard lib.
i can send key presses with keyobard.send however if player presses and holds w for movement keyboard.send is not working.
What should i do?
But here you go you need to call the press and release function like this:
# press a
keyboard.press("a")
# wait 1 second
time.sleep(1)
# release a
keyboard.release("a")
so I'm using pyautogui to type, and I'm trying to hold a key down for more than a second but I've ran into this problem where the key only types a single letter
import pyautogui
import time
pyautogui.keyDown("w")
time.sleep(2)
pyautogui.keyUp("w")
my output is "w"
but my output should be "wwwwwwwwwwwwwww" since I'm holding down the key?
the same thing occurs when im using the press function for pyautogui,
pyautogui.press("w") #but instead of pressing a single key, it totally just doesnt get outputted but only works for main keyboard functions like windowsKey and enter
if this is wrong, is their a way i can make it so I'm holding down the key?
From the Documentation it seems that it's not possible to do the way you have tried, however this function can help for 'holding down' a letter for a set number of seconds:
def hold_character(hold_time, character, interval=0.1):
pyautogui.write(character * int(hold_time / interval), interval=interval)
hold_character(2, 'w')
...gives the 'wwwwwwwwwwwwwww' effect for me
as the question suggest I am looking for a way to hide or mask user input within python without using the standard getpass library due to using spyder; I am wondering if this would potentially be possible using key pressed and recording each key pressed without it displaying until say enter is pressed? If this is possible would someone be able to help me with a snippet for this purpose
Thanks,
Sam Hedgecock
You should take a look at a kind of key-logging mechanism. You could detect which key the user pressed, store those keys in a buffer to finally output them after ENTER is pressed.
Working cross-platform example:
from getkey import getkey, keys
#Buffer holding all the pressed keys
pressed_keys = []
while True:
#Getting the pressed key
key = getkey()
#Appending it to array
pressed_keys.append(key)
#If ENTER is pressed, exit loop
if key == keys.ENTER:
break
#Outputting all pressed keys after ENTER is pressed
for key in pressed_keys:
print(key, end='')
You need to install getkey though. Use pip3 install getkey.