how do i keep a key pressed using pyautogui? - python

i am very new to coding and am making a macro for a game that after seing the specified color it will move the cursor to said color.
the code goes:
from time import sleep
import pyautogui
x=1
color = (166, 166, 61)
sleep(5)
while x==1:
s = pyautogui.screenshot()
pyautogui.keyDown("space")
for x in range(1171, 1172):
for y in range(544, 990):
if s.getpixel((x, y)) == color:
pyautogui.moveTo((x,y))
pyautogui.keyUp("space")
sleep(38)
the thing is that the space bar is not held like it would be if a player held it down as the menu connected to it doesn't open. Is there any way for me to simulate pressing the space bar so that it acts like it was pressed irl?

Related

How to make a python application that detects a color and when detected presses a button on the keyboard?

I am trying to write an application that constantly checks for a color and when detected, presses the e button once.
import pyautogui
import time
color = (1, 72, 132)
def clicker():
while True:
x, y = pyautogui.position()
pixelColor = pyautogui.screenshot().getpixel((x, y))
if pixelColor == color:
pyautogui.press('e')
def main():
while True:
clicker()
main()
I only got this but it does not work at all.
To get a tuple of RGB colors at the current mouse position I use this
pixel = pyautogui.pixel(*pyautogui.position())

python - How to recognize images and click on them

I would like to make a script that clicks on images depending on what is asked, it needs to go trough a list of images. so for example if the user is asked by the program to click on the green circle:
question_list = greencircle, redcircle, bluesquare, redtriangle
if(greencircle == greencircle.png){
pyautogui.click(greencircle.png)
}
could someone help with this?
PyAutoGUI has a built in function called locateOnScreen() which returns the x, y coordinates of the center of the image if it can find it on the current screen (it takes a screenshot and then analyzes it).
The image has to match exactly for this to work; i.e. if you want to click on a button.png that button picture has to be the same exact size / resolution as the button in your windows for the program to recognize it. One way to achieve this is to take a screenshot, open it in paint and cut out only the button you want pressed (or you could have PyAutoGUI do it for you as I'll show in a later example).
import pyautogui
question_list = ['greencircle', 'redcircle', 'bluesquare', 'redtriangle']
user_input = input('Where should I click? ')
while user_input not in question_list:
print('Incorrect input, available options: greencircle, redcircle, bluesquare, redtriangle')
user_input = input('Where should I click?')
location = pyautogui.locateOnScreen(user_input + '.png')
pyautogui.click(location)
The above example requires you to already have greencircle.png and all the other .png in your directory
PyAutoGUI can also take screenshots and you can specify which region of the screen to take the shot pyautogui.screenshot(region=(0, 0, 0, 0)) The first two values are the x,y coordinates for the top left of the region you want to select, the third is how far to the right(x) and the fourth is how far down (y).
This following example takes a screenshot of the Windows 10 Logo, saves it to a file, and then clicks on the logo by using the specified .png file
import pyautogui
pyautogui.screenshot('win10_logo.png', region=(0, 1041, 50, 39))
location = pyautogui.locateOnScreen('win10_logo.png')
pyautogui.click(location)
You also don't have to save the screenshot to a file, you can just save it as a variable
import pyautogui
win10 = pyautogui.screenshot(region=(0, 1041, 50, 39))
location = pyautogui.locateOnScreen(win10)
pyautogui.click(location)
Making a program detect if a user has clicked in a certain area (let's say, the windows 10 logo) would require another library like pynput.
from pynput.mouse import Listener
def on_click(x, y, button, pressed):
if 0 < x < 50 and 1080 > y > 1041 and str(button) == 'Button.left' and pressed:
print('You clicked on Windows 10 Logo')
return False # get rid of return statement if you want a continuous loop
with Listener(on_click=on_click) as listener:
listener.join()
PUTTING IT ALL TOGETHER
import pyautogui
from pynput.mouse import Listener
win10 = pyautogui.screenshot(region=(0, 1041, 50, 39))
location = pyautogui.locateOnScreen(win10)
# location[0] is the top left x coord
# location[1] is the top left y coord
# location[2] is the distance from left x coord to right x coord
# location[3] is the distance from top y coord to bottom y coord
x_boundary_left = location[0]
y_boundary_top = location[1]
x_boundary_right = location[0] + location[2]
y_boundary_bottom = location[1] + location[3]
def on_click(x, y, button, pressed):
if x_boundary_left < x < x_boundary_right and y_boundary_bottom > y > y_boundary_top and str(button) == 'Button.left' and pressed:
print('You clicked on Windows 10 Logo')
return False # get rid of return statement if you want a continuous loop
with Listener(on_click=on_click) as listener:
listener.join()

Check for mouse press while mouse moves

I'm making a simple program that randomly moves my mouse to farm hours on sites like VHL. I want to add a section of code that stops the code from running when the mouse button is pressed.
So far I have this:
# imports
import random
import time
import pyautogui
# screen resolution - 2256, 1504
while True: # constantly runs, constantly updates variables
# vars that need to update part
posX = random.randint(0, 2256) # get a random x coordinate
posY = random.randint(0, 1504) # get a random y coordinate
randDuration = random.randint(2, 10) # get a random duration for mouse movement
randSleep = random.randint(5, 100) # get a random sleep time
# code part
pyautogui.moveTo(posX, posY, randDuration) # moves cursor to random coordinates from defined variables
print(f"Cursor moved to x:{posX} y:{posY} in {randDuration} seconds!")
time.sleep(randSleep)
from pynput.mouse import Listener
def is_clicked(x, y, button, pressed): # function that stops code after mouse1 is pressed
if pressed:
exit()
with Listener(on_click=is_clicked) as listener:
listener.join()
Everything works fine, but I want to be able to stop the program while the mouse is moving. In other words, while the line below runs:
pyautogui.moveTo(posX, posY, randDuration)
I want to simultaneously check if the mouse 1 button is being pressed.
Please let me know if you need any clarification. Thanks for the help.

Command to trigger "long click" on left mouse button

I searched in win32gui and PyAutoGUI some commands that make "long - click" on the left mouse button, and I didn't find anything.
I'm actually building a code that helps me to remote another pc's mouse
so i need a command that makes a long click on a mouse.
I put *** on my code so you can see the parts where I need help:
import win32api
import time
state_left = win32api.GetKeyState(0x01) # Left button down = 0 or 1. Button up = -127 or -128
while True:
a = win32api.GetKeyState(0x01)
if a != state_left: # Button state changed
state_left = a
print(a)
if a < 0:
# *** long click on left mouse button ***
print('Left Button Pressed')
else:
# *** stop click on left mouse button ***
print('Left Button Released')
time.sleep(0.001)
In theory, PyAutoGUI covers this with mouseDown & mouseUp functions.
>>> pyautogui.mouseDown(); pyautogui.mouseUp() # does the same thing as a left-button mouse click
>>> pyautogui.mouseDown() # press the left button down
>>> pyautogui.mouseUp(x=100, y=200) # move the mouse to 100, 200, then release the button up.
A solution might be:
pyautogui.dragTo(100, 200, button='left') # drag mouse to X of 100, Y of 200 while holding down left mouse button
pyautogui.dragTo(300, 400, 2, button='left') # drag mouse to X of 300, Y of 400 over 2 seconds while holding down left mouse button
pyautogui.drag(30, 0, 2, button='right') # drag the mouse left 30 pixels over 2 seconds while holding down the right mouse button

Conceptual bug in a turtle program using resetscreen()

Criteria I'm trying to meet:
The screen resets when the user presses the SPACEBAR, meaning the drawn lines go away and the unnamed turtle returns to the center but it doesn’t return to the default turtle color and shape!
""" A simple drawing program
Click and drag the center turtle to draw
Click the colorful buttons to change the
turtle's color,
and then draw different shapes.
Press the SPACEBAR key to reset the
drawing.
"""
from turtle import *
turtle_1 = Turtle()
turtle_2 = Turtle()
turtle_3 = Turtle()
def callback_1(x,y):
color("red")
shape("circle")
circle(100)
def callback_2(x,y):
color("blue")
shape("square")
circle(100,steps=4)
def callback_3(x,y):
color("green")
shape("triangle")
circle(100,steps=3)
def place_turtles():
turtle_1.color("red")
turtle_1.shape("circle")
turtle_1.penup()
turtle_1.goto(-200,-200)
turtle_2.color("blue")
turtle_2.shape("square")
turtle_2.penup()
turtle_2.goto(0,-200)
turtle_3.color("green")
turtle_3.shape("triangle")
turtle_3.penup()
turtle_3.goto(200,-200)
def start_over():
resetscreen()
place_turtles()
listen()
onkey(start_over, "space")
ondrag(goto)
place_turtles()
This code allows the user to drag the turtle, press buttons, and reset the screen when they press SPACEBAR. For some reason, though, resetting the screen also resets the color of the turtle. How can I prevent this from happening?
Basically what I want to happen is if, say, the user clicks on the blue square button, then resets the screen to hide the shape drawn by the button, all of the turtles return to their original positions, but the unnamed turtle does not change its previous color and shape. Let me know if I need to elaborate further.
With a "better late than never" attitude, I believe I've reworked your code to get the behavior you desired. I also reworked your drag logic to give you better drawing capability:
from turtle import Turtle, Screen, getturtle
def callback_1(x, y):
anonymous.color(*turtle_1.color())
anonymous.shape(turtle_1.shape())
anonymous.circle(100)
def callback_2(x, y):
anonymous.color(*turtle_2.color())
anonymous.shape(turtle_2.shape())
anonymous.circle(100, steps=4)
def callback_3(x, y):
anonymous.color(*turtle_3.color())
anonymous.shape(turtle_3.shape())
anonymous.circle(100, steps=3)
def setup_turtles():
turtle_1.onclick(callback_1)
turtle_1.color("red")
turtle_1.penup()
turtle_1.goto(-200, -200)
turtle_2.onclick(callback_2)
turtle_2.color("blue")
turtle_2.penup()
turtle_2.goto(0, -200)
turtle_3.onclick(callback_3)
turtle_3.color("green")
turtle_3.penup()
turtle_3.goto(200, -200)
def start_over():
colors = anonymous.color()
anonymous.reset()
anonymous.color(*colors)
def drag_handler(x, y):
anonymous.ondrag(None) # disable event inside event handler
anonymous.goto(x, y)
anonymous.ondrag(drag_handler) # reenable event on event handler exit
anonymous = getturtle()
anonymous.ondrag(drag_handler)
turtle_1 = Turtle(shape="circle")
turtle_2 = Turtle(shape="square")
turtle_3 = Turtle(shape="triangle")
setup_turtles()
screen = Screen()
screen.onkey(start_over, "space")
screen.listen()
screen.mainloop()
Many of the changes are just for personal style reasons. The two key changes are: just reset the anonymous turtle itself, not the screen; rather than use goto as an event handler, wrap it in a function that turns off drag events during the goto call.

Categories