0

I'm trying to have my mouse click randomly along a bar within a program to set data. I'm not sure how to do it. I have tried setting a box inside the leftClick at the bottom but that unsurprisingly didn't work. I'm very new to python and I'm doing this for an aerospace engineering class I'm taking.

from PIL import ImageGrab
import os
import time
import win32api, win32con
import random

# Globals
# ----------------

x_pad = 14
y_pad = 70

def screenGrab():
    box = (x_pad+1,y_pad+1,x_pad+1508,y_pad+258)
    im = ImageGrab.grab(box)
    im.save(os.getcwd() + '\\full_snap__' + str(int(time.time())) + '.png', 'PNG')

def main():
    screenGrab()

if __name__ == '__main__':
    main()

"""
Omitted code not necessary for this part
"""

def get_cords():
    x,y = win32api.GetCursorPos()
    x = x - x_pad
    y = y - y_pad

def startGame():
    #location of first bar
    mousePos((33,125))
    leftClick(
Emma
  • 27,428
  • 11
  • 44
  • 69

2 Answers2

0

Similar to @PeptideWitch, but more "Python" in mouse event.

from pynput.mouse import Button, Controller
import random

def click_box(x_min, x_max, y_min, y_max):
    new_x = random.uniform(x_min, x_max)
    new_y = random.uniform(y_min, y_max)
    print(new_x,new_y)
    mouse = Controller()
    mouse.position = (new_x, new_y)
    mouse.click(Button.left, 1)
Drake Wu
  • 6,927
  • 1
  • 7
  • 30
-1

Have a look at python's inbuilt random.randrange, which returns a value between your specified coordinates, say (33 and 124). You will want to feed in the outer limits of the box you make and then get python to return a random value between those two spaces.

Then, try something like this answer:

def click_box(x_min, x_max, y_min, y_max):
    new_x = random.randrange(x_min, x_max+1)
    new_y = random.randrange(y_min, y_max+1)
    win32api.SetCursorPos((new_x,new_y))
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,new_x,new_y,0,0)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,new_x,new_y,0,0)
PeptideWitch
  • 2,239
  • 14
  • 30
  • 1
    This is missing the [`MOUSEEVENTF_ABSOLUTE`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-mouse_event) flag. Once you add it, you're going to have to calculate normalized coordinates, too. This is also missing an opportunity to prevent a bug by calling [SendInput](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput), as the documentation explains. – IInspectable Jul 15 '19 at 05:45
  • So if I understand you correctly, we use `win32api.mouse_event(win32con.MOUSEEVENTF_MOVE | win32con.MOUSEEVENTF_ABSOLUTE, int(x/SCREEN_WIDTH*65535.0), int(y/SCREEN_HEIGHT*65535.0))` instead of setting the cursor position. I'm not sure how to wrap this inside of the `SendInput` function, though. – PeptideWitch Jul 15 '19 at 06:03
  • 1
    IInspectable means [`mouse_event`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-mouse_event) function has been superseded by `SendInput` according to the document. – Drake Wu Jul 15 '19 at 06:40
  • 1
    The important point here is, that you want to make sure to inject compound information into the input stream atomically, without opening a window of opportunity to have it interspersed with input from other sources. As for the other point: Yes, that's a partial implementation calculating normalized coordinates. It's missing the part that's retrieving the overall geometry, and I don't know which size to use in case of a multi-monitor setup. – IInspectable Jul 15 '19 at 07:14