So I've been attempting to get a script to type out a string of text in a video game (Guild Wars 2). Mainly I'm using pyautogui and for the most part it works fine. My issue is it seems I can't get the game to recognize 'enter'. For example if I have the code:
import pyautogui, time
time.sleep(2) #to allow me to have time to switch windows
pyautogui.press('enter')
pyautogui.typewrite("This is a test")
pyautogui.press('enter')
The two "press enter" function will not open and submit the text. If however I manually hit enter, the 3rd line types things out just fine.
I've also tried replacing press('enter') with keyDown followed by keyUp, but with still no results.
I've managed to create a workaround by having python hit F10, and then a separate Autohotkey script hitting enter when F10 is hit, but that is far from ideal. Are there any suggestions?
Extra note from comments: The script by itself works fine in other programs such as notepad. It seems to fail exclusively for the game client.
For anyone finding their way to this post. The answer is essentially that this can't be done in this fashion due to how most games interpret keypresses. A working system is shown here: Simulate Python keypresses for controlling a game
None of \n nor return works to me, so I have to use pydirectinput: https://github.com/learncodebygaming/pydirectinput
Install it using pip install pydirectinput, then import it and use as the README. Note that the file also needs to run as admin.
Related
I am using the latest version of PyCharm and Python. I'm trying to get my program to wait for specific keypresses like the arrow keys. I've been messing with the mscvrt (not worried about only windows) and using the getch() but it freezes my program everytime. I was able to get it to work printing to the console by using "emulate terminal in output console". But once I tried implementing it to a GUI with my code in tkinter it still freezes. Was wondering if it just doesn't work in GUI's and that's the issue (saw this mentioned on the internet) and if anyone had suggestions for what I could do.
For example:
This runs in the console and works. The arrow keys print as (b'\xe0' b'K') (left) and (b'\xe0' b'M') (right)
while True:
if msvcrt.kbhit():
key = str(msvcrt.getch())
if key == "b'w'":
print(key)
elif key == 'w':
print("suck it")
This freezes my program before I get the chance to press any keys. It seems to be only when I introduce GUI into the program. I also tried binding this as a function to space and it will freeze the GUI when I press space and crash after a bit. I also tried not using a while function and also without the kbhit part as well.
while True:
if msvcrt.kbhit()
user_input = str(msvcrt.getch())
start = tk.Label(window, text=(user_input), font=("arial", '25'))
start.place(relx=.5, rely=.7, anchor="center")
Appreciate any help/advice. I'm somewhat new to python and coding so not sure what the issue could be.
I have a program in Python that starts another executable. Some automated operations need to be done in the ribbon of this open executable, so I use pyautogui to do so.
First the ribbon needs to be ‘active’, so I click on the left most part.
Then I need to use the arrows to change the ribbon menu selection (two times to the left).
Then I need to hit enter to open the correct menu. (going from 'File' to 'Scripting')
The code I’m using for this is:
import pyautogui
pyautogui.click(x=0, y=30)
pyautogui.press(['left', 'left']) #this part does not work here
pyautogui.hotkey('enter')
Somehow, the click and enter do work, but the arrow-keys don’t work. I can use the physical arrow-keys to change the menu selection, but this code doesn’t perform these actions somehow.
Does someone know what is wrong here and how to solve this?
Best regards,
Ganesh
EDIT:
I tried to open both the program and the script with admin right, but that still didn't work. Somehow, the 'enter' and everything else works, except for the arrows.
Ganesh, it might not work with pyautogui as the program/ interface you're using might simply not register the key. To use the arrow keys or other special keys like 'enter' I would suggest using pydirectinput
First, install the library if not already
pip install pydirectinput
Then you can rewrite your code as
import pyautogui
import pydirectinput
pyautogui.click(x=0, y=30)
pydirectinput.press(['left', 'left']) #this is the updated line of code
pyautogui.hotkey('enter')
I want to detect if Ctrl + X is clicked so that I can exit my Python application. I don't know how to do it? Please help.
Have you thought about using a function like the ones discussed here? Python read a single character from the user
Or maybe you could use curses.
Either way you would just need to find the key code for ctrl-X, it's 24.
The simple and the best option is to use the module keyboard. Install it using pip install keyboard.
Use the following code at the start of your code:
import keyboard as k
k.add_hotkey("ctrl+x",lambda: quit())
#Your code....
Well, it works easily, but, it will read keys from the whole windows. For example the program is running and you are using notepad currently and you pressed ctrl+x , then the python program will close too.
I'm learning python and playing with the subprocess module. After reading several different tutorials and descriptions of how to use the module, my understanding was still not incredibly solid so I started working up some simple code to test the various functions and see how everything worked.
I wanted to see how it might behave if I tried to start the same process multiple times, using this code:
import subprocess
def tpltest(x):
while x > 0:
try:
subprocess.Popen('wordgrinder')
except:
print 'something broke!'
x -= 1
x = raw_input('how many?')
tpltest(x)
When I ran this in my terminal, wordgrinder (terminal word processor) opened normally, but then the cursor advanced down the screen at a rate of about one line per second. It appeared to be movement only, rather than any characters being added to the blank file onscreen. I pressed ctrl+c to see if a wordgrinder remained after closing the first instance and was met with my regular command line prompt, but the cursor continued to scroll. I ran top and did not see extra wordgrinder instances open, but the cursor continued scrolling.
Then I discovered the oddest part. If I rolled my mouse scroll wheel up in the window, chunks of text appeared over the window's contents. Some of the chunks were commands I had entered in the console over the past week, some of them were commands I had entered in my python shell but not the regular terminal, and some of the text was my WiFi security information, including the plaintext WPA2 password for my network. Scrolling the mousewheel down had no effect but scrolling up would overwrite a few lines with new text, seemingly from other random places in my system. After closing the terminal window and opening a new one, things were back to normal.
I'm running Debian 8 64bit with XFCE and using the default terminal emulator.
What did my code do, and why?
The explanation that I can offer is that what subprocess does is to run a background process. Additionally, wordgrinder is a program that takes full control of the terminal session by capturing input from the keyboard (stdin) and controlling the command-line (stdout) in a very particular way.
When you ran wordgrinder in the background through your script, it caused some funky things to happen. That's pretty crazy that your WiFi password ended up getting displayed from your experiment.
I was wondering if it is possible to write the pygame code to a separate terminal so that you can still do things like print to the terminal. When pygame's display becomes initialized it seems to be impossible to put any input into the terminal. Any way to get around this?
I also want to know that if this is possible can one the other terminal edit the one running pygame to change certain things?
Github
Ok, once you initialize pygame and start your pygame loop in startDisplay() in Commands.py, you are essentially leaving your main() loop in game.py. So your repeated request for input won't happen again. If you want to call for input during the loop in startDisplay() you'll need to do it expressly there. As I stated above, this will pause your game until you enter a command, which obviously isn't very good. You could build a little logic around it and only request input during a break in the action or implement a Pause event (using a key event) which would subsequently call the prompt for a command.