How to simulate key presses on a specific application - python

I'm trying to set up a bot that does things for me, at the moment I have to be in the same window so that it works. Is it possible to be able to change my window (e.g using google chrome) while the bot is running on that specific application?
Also if you're asking about what application its, its Runescape just an old game and I'm just using it to learn more about python.
I couldn't find any information online about any module that does this sadly.
from pynput.mouse import Button, Controller
from time import sleep
from random import randint, uniform
def move_mouse(next_pos):
sleep(uniform(0.1,0.2))
mouse.position = (randint(int(round(next_pos[0])), int(round(next_pos[2]))), randint(int(round(next_pos[1])), int(round(next_pos[3]))))
sleep(uniform(1,1.2))
mouse.click(Button.left, 1)
mouse = Controller()
print(mouse.position)
shaft = [ 1299.25, 590.48828125, 1315.6171875, 610.69921875]
box = [705.01171875, 600.671875, 957.640625, 616.37109375]
sleep(2)
while True:
move_mouse(shaft)
move_mouse(box)
sleep(71)
So far everything works perfectly I get no errors what so ever. All I need is for it to click on a specific application.

Related

Python 3.10.6 /w pyautogui Display Message Boxes, crashes

Python: 3.10.6,
os: MacOS 12.6,
Software: VS code
I want to confirm before activating the mouse_click()with pyautogui's message box (.alert or .confirm).
Running the script the message box opens, and if I do nothing its okey. But once I click in the message box, a button or anywhere in the message box window, the 'spinning wheel' appears. The application window crashes and needs to 'Force quit'.
Its the same with every message box.
import pyautogui
import time
def mouse_click():
while True:
time.sleep(1)
pyautogui.click()
def main():
pyautogui.confirm('Shall I proceed?')
mouse_click()
main()
quit()
What might be the issue?
I believe your issue may stem from being in a while loop:
taking it out of the loop seems to fix things. The confirm box also returns the value of the button clicked so I implemented that.
import pyautogui
import time
x = pyautogui.confirm('Shall I proceed?', title='Are you sure?', buttons=['Ok', 'Cancel'])
if x == 'Ok':
time.sleep(1)
pyautogui.click()
else:
quit()
Though for some reason the box doesn't close until after the click event.
In any event you can work around this by making pyautogui move your mouse and click elsewhere.
the solution would be the use of 'threading'. As having an active GUI and a task running in a loop causes the GUI to freeze, looks to have crashed, until the loop has ended.
some info about threading can be found here Python threading and PySimpleGUI
I've moved over to PySimpleGUI and used threading. Explanation and demo code:
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Multithreaded_Multiple_Threads.py

Capture device ID on key press in python on windows

So I've been working on a small project which will essentially be a macros program. The idea is to use a small external numpad with custom labels to click certain areas of the screen which correspond to buttons. I've got this all working beautifully with one minor (or major?) caveat which is the fact that I cannot differentiate between keyboards. Ideally I'd like to be able to still use my main keyboard and numpad normally. My code below for a sample key:
import keyboard
import pynput
from pynput.mouse import Button, Controller
import time
mouse = Controller()
tab = (1639, 16)
def handler():
print(keyboard.KeyboardEvent.device)
prev = mouse.position
mouse.position = tab
mouse.click(Button.left, 1)
mouse.position = prev
keyboard.add_hotkey("a", handler, suppress=True)
while True:
time.sleep(0.1)
So you can see here I am using the keyboard and pynput libraries. In the docs for the keyboard library, it notes an issue where on windows specifically, keyboard.KeyboardEvent.device returns "None" always.
I looked around a bit at various solutions for using raw input, but I wasn't able to really find anything applicable to my situation, and anything that looked remotely close was admittedly beyond my skill level. Anybody have any thoughts? Thanks.

MacOS - Python 3.7 - GUI mouse control for DirectX 8 (2003) app - unable to simulate mouse clicks but I can simulate keyboard entry

I am trying to control an old DirectX application from a Python script. The application concerned is from 2003 (ish). Launches full screen (in a Desktop space) in OSX and requires the mouse be 'freed' via a command. Once the mouse is freed you can use it normally.
I have tried scripting to simulate a mouse click. I have used AppleScript and Python to no avail.
Keyboard simulation does work. For example the first thing any scripting does is swap into the relevant desktop space with a shortcut then hit a keyboard shortcut in the app. This works.
Moving the mouse around the app with scripting works.
However the following will not work.
1) Simulated clicks from code.
2) Turning on mouse keys and simulating a keyboard click in code. Note if I turn on mouse keys and manually hit the mouse click key in the app this does work.
Doesn't work -
import pyautogui
pyyautogui.click()
from pynput import Button,Controller
mouse = Controller()
mouse.click(Button.left, 2)
So basically simulating the keyboard works in the app but I am struggling to simulate a mouse click (moving the mouse works fine). Any ideas?
are you saying you want to write with pyautogui? you can use this:
import pyautogui
pyautogui.write('An example')

Running Python clicker based on keylogger inputs on the background in Windows

I wanted to write a program in Python for Windows that would act as a clicker, in which according to a key the user presses a click is made at a known location on the screen. This is used for an automated option selection from a list in a webpage. I have the clicking part working, but I wanted to be able to make several clicks during execution, as if there is a quiz with multiple lists one after another.
One option is to make a while loop with getch() from msvcrt. The thing is after a click outside the cmd its window is no longer selected, but rather the window where the destination point is located. Therefore, the script stops being active and the user cannot choose another location. A workaround is to click the cmd window to return the focus to it and be able to do any more clicks. To solve this, it would be necessary to create a service or, according to #Sanju, a thread.
The other option is to use a keylogger such as PyHook, which seems like the way to go. However, the problem is that the window where I want to use it in, a webpage in flash or another animations engine, causes an error that some users have found using this keylogger for example in Skype and is being described here. In my case, it also happens with this webpage and either when the click is made on the window itself or when the key is pressed with the window selected.
My base code is presented below, where click(...) would normally contain the coordinates as argument but they are being omitted for simplicity. In this case, 0 ends the program and there are three options being chosen with the numbers 1-3.
import msvcrt, win32api, win32con
def click(x,y):
win32api.SetCursorPos((x,y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
key=0
while key!=b'0':
key=msvcrt.getch()
if key==b'1':
click(...)
elif key==b'2':
click(...)
elif key==b'3':
click(...)
The attempts below try to implement #Sanju's suggestion, first with the whole while inside the thread and then with the queue, both not working as expected...
import threading, msvcrt, win32api, win32con
def MyThread():
key=0
while key!=b'0':
key=msvcrt.getch()
if key==b'1':
...
def click(x,y):
...
threading.Thread(target=MyThread,args=[]).start()
.
import queue, threading, msvcrt, win32api, win32con
def MyThread(key):
while key.get()!=b'0':
key.put(msvcrt.getch())
if key.get()==b'1':
...
def click(x,y):
...
key=queue.Queue()
key.put(0)
threading.Thread(target=MyThread,args=[key]).start()
The other attempt uses PyHook, but it's still facing the aforementioned issue.
import pyHook, pythoncom, win32api, win32con
def OnKeyboardEvent(event):
if event.Key=='Numpad1':
...
def click(x,y):
...
hm=pyHook.HookManager()
hm.KeyDown=OnKeyboardEvent
hm.HookKeyboard()
pythoncom.PumpMessages()
All you need here is move your click part to a thread and share the user input using a shareble object such as queue. It sounds like a overkill , but that's the way to keep your tasks in background.
And BTW, you have many GUI application frameworks available in Python like tkinter ,wxpython which can ease your objective.

Python keybd_event problems

For a personal project, I want to generate keyboard presses for a N64 emulator. It seems like it recognizes only one keyboard event when I select the Python IDE then switch to the emulator. I want the emulator to constantly recognize the button presses the python script generates. The code is really simple, it constantly replicates the x button being pressed.
import serial,win32api, win32con,time
while 1:
win32api.keybd_event(0x58,0x2D,0,0)
time.sleep(1)

Categories

Resources