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
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.
I'm having trouble using the keyboard module. I'm working on a typing game in turtle graphics. The user types and a "guide" arrow above the sentence shows the user how far they've typed. The arrow is supposed to turn red when an incorrect letter is typed, and it turns green when a correct letter is typed.
Knowing if the user has typed the correct letter is no problem, I'm using keyboard.is_pressed() to move the arrow forward and change green. However, the incorrect part is the problem. I need to use a function that returns the value of a any key, not a specific key. If it returns the value of the key the user types, then I can see if it is incorrect or not.
I tried using the conditional: if keyboard.read_key() != letter: which does what I want, but since I am using keyboard.is_pressed() to see if the letter is correct or not, the arrow only changes green for an instant, and then goes red. This is the code I am using:
count1 = 0
while True:
if x[count1].isupper():
if keyboard.is_pressed(x[count1]) and keyboard.is_pressed('shift'):
carmove()
arrowmove()
count1 += 1
try:
if keyboard.read_key() != x[count1]:
incorrect()
except:
IndexError
else:
if keyboard.is_pressed(x[count1]):
carmove()
arrowmove()
count1 += 1
try:
if keyboard.read_key() != x[count1]:
incorrect()
except:
IndexError
if count1 == length1:
break
x[count1] is a specific letter in the sentence. This code causes the arrow to turn green for second, then it goes right back to red.
I also tried making a list of all of the printable characters, then remove the correct letter the user must type, and then iterate through the list but that didn't seem to work either.
I read through the API docs for the keyboard module, but I couldn't find anything else that might work. I'm wondering if it is possible to use the keyboard module, or if I have to use another module. Any help is appreciated.
is_pressed() function is not blocking the code to get a button click. and you also use the read_key function in the same code which is blocking the code until it gets a key.
since there is nothing here mention that the initial state for the arrow to be red. I'm assuming that the error is not in this code. this code has an error which is if you clicked the right key too fast. might not count. because is_pressed needs to be clicking the key while it executes. and another function will be blocking the code in other parts
So, I suggest this edit for your code
count1 = 0
while True:
key = keyboard.read_key()
if key == x[count1]:
carmove()
arrowmove()
count1 += 1
else:
incorrect()
if count1 == length1:
break
and the read_key result for a capital key the letter in capital. no need to check for shift
You might be able to toss the keyboard module and use turtle's own onkey() event handling. If you leave off the (second) key argument to the onkey() function, it will call your key handler code when any key is pressed. The problem is, there's no mechanism to let you know which key was pressed.
The following answer includes code to work around this design error, rewriting the underlying code to pass tkinter's event.char to turtle's event handler in the case where no key has been set (i.e. key is None):
How can I log key presses using turtle?
Been using the pyautogui module to do most of my things, but I have come across one problem:
I cannot hold down a key for a certain length of time.
Does anyone know any modules that can do this, or have a solution without downloading any modules?
For example (perfect for me):
I go into word, and run my code. Word should just be receiving (w pressed down), with the w's slowly increasing - (after a while holding adds like 5 a half sec).
You can use the following example:
>>> pyautogui.keyDown('shift') # hold down the shift key
>>> pyautogui.press('left') # press the left arrow key
>>> pyautogui.press('left') # press the left arrow key
>>> pyautogui.press('left') # press the left arrow key
>>> pyautogui.keyUp('shift') # release the shift key
In your case you'd use the keyDown function and a timer or equivelent to trigger keyUp.
You can find more information in regards to using timers here or better yet use Timer from the threading library - especially if you want to the processing to continue.
Example of using threading.Timer below.
def hello():
print("hello, world")
t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed
In the keyDown documentation one can note the following:
NOTE: For some reason, this does not seem to cause key repeats like
would happen if a keyboard key was held down on a text field.
An alternative to using the keyDown function is to repeat the press function; in cases where keyDown is not satisfying the behaviour required by the developer and/or user.
def hold_key(key, hold_time):
import time, pyautogui
start_time = time.time()
while time.time() - start_time < hold_time:
pyautogui.press(key)
or
import pyautogui
while True:
pyautogui.press('w')
The above code is not tested.
Despite hunting around I can't seem to find an answer to this seemingly simple question:
I'm new to pygame (but not to python), and am trying to get some code to work from continuous button presses - but get_pressed just does not seem to work for me. I made this just to check that I wasn't going insane (I've left out the importing to make it neat for you guys):
def buttonpress():
while True:
keys = pygame.key.get_pressed()
print keys[K_SPACE]
time.sleep(0.5)
buttonpress()
To the best of my knowledge, this should return a '1' when you press the space bar, but no matter what key you change it too - it simply returns an endless string of zeros.
What am I missing?
Thanks
There is no code that processes the input to get all the keys pressed. In order for this to work you need to call event.poll().
So your code will look like this.
import pygame
from pygame.locals import *
import time
pygame.init()
screen = pygame.display.set_mode((640,380))
def buttonpress():
while True:
keys = pygame.key.get_pressed()
print (keys[K_SPACE])
time.sleep(0.5)
pygame.event.poll()
buttonpress()
One more thing, do not use time.sleep(). This pauses the thread, and can cause the OS to think that your application does not respond (since it's not removing events from the event queue).