Python: saving mouse position in one list - python

In the following python code:
from pynput.mouse import Listener
coord = []
def click(x, y, button, pressed):
if pressed:
x = int(x)
y = int(y)
coord.append(x)
coord.append(y)
if len(coord) == 4:
print(coord)
return
with Listener(on_click = click) as Listener:
Listener.join()
what I want to do is ;
the code will stop when coord has 4 elements.
so like, this If will stop when I do click twice.

Since you append the x and y value individually every time. Each mouse click is stored as 2 values(the x and y). That is why instead of the code stopping at 4 clicks it stops at 2 clicks. To fix this, append a tuple or list(I've used a tuple)
from pynput.mouse import Listener
coord = []
def click(x,y, button, pressed):
if pressed:
x = int(x)
y = int(y)
coord.append((x,y)) # You can use a list also here.
if len(coord) == 4:
print(coord)
return
with Listener(on_click = click) as Listener:
Listener.join()

Related

How to block only one mouse button?

The middle button on my mouse sometimes clicks several times when I click it once. My mouse is expensive and I like it, so I decided to fix it with a program.
When I release the middle button, I'd like to freeze it for 0.1 seconds without freezing the other buttons.
I tried to block with the supress=True flag in pynput library, and then sending button for windows, but this doesn't work.
from pynput.mouse import Button, Controller, Listener
import time
mouse = Controller()
class BlockMiddle:
def __init__(self):
self.start = time.time()
with Listener(on_click=self.on_click, on_move=self.on_move,
suppress=True
) as listener:
listener.join()
def on_click(self, x, y, button, pressed):
if button == Button.left:
if pressed:
mouse.press(Button.left)
else:
mouse.release(Button.left)
if button == Button.right:
if pressed:
mouse.press(Button.right)
else:
mouse.release(Button.right)
if button == Button.middle:
if pressed:
if time.time() - self.start > 0.1:
mouse.press(Button.middle)
else:
mouse.release(Button.middle)
self.start = time.time()
if button == Button.x1:
if pressed:
mouse.press(Button.x1)
else:
mouse.release(Button.x1)
if button == Button.x2:
if pressed:
mouse.press(Button.x2)
else:
mouse.release(Button.x2)
def on_move(self, x, y):
mouse.position = (x, y)
block = BlockMiddle()
Finally I solved my problem.
from pynput.mouse import Button, Controller, Listener
import time
mouse = Controller()
class BlockMiddle:
def __init__(self):
self.start = time.time()
self.listener = Listener(
on_click=self.on_click,
on_move=self.on_move,
on_scroll=self.on_scroll,
suppress=False
)
with self.listener as l:
l.join()
def on_click(self, x, y, button, pressed):
self.listener._suppress = False
if not button == Button.middle:
return
if time.time() - self.start < 0.1:
self.listener._suppress = True
if not pressed:
self.start = time.time()
self.listener._suppress = False
def on_move(self, x, y):
self.listener._suppress = False
def on_scroll(self, x, y, dx, dy):
self.listener._suppress = False
block = BlockMiddle()

Retrieving x and y mouse positions for click and release in Pynput

I am using Python 3.9.7 with pynput, I wanted to retrieve the x and y position of mouse both clicking and releasing separately and saved it into variables outside of the function on_click (e.g: px = x position when pressed, rx = x position when released) for other function usage
The code are as follows , code are modified from Pynput documentations:
from pynput import mouse
import time
px = 0
py = 0
rx = 0
ry = 0
pressed_location = 0, 0
released_location = 0, 0
def on_click(x, y, button, pressed):
global pressed_location
global released_location
global px,py,rx,ry
if pressed:
pressed_location = x, y
px = x
py = y
else:
released_location = x, y
rx = x
ry = y
#debugging inside functions
#print('You pressed at {0}x{1} and released at {2}x{3}'.format(*pressed_location, *released_location))
print('Inside function pressed at {0}x{1}'.format(*pressed_location, *released_location))
print('Inside function released at {2}x{3}'.format(*pressed_location, *released_location))
return False
listener = mouse.Listener(on_click=on_click)
listener.start()
#debugging outside functions
print ("Outside function pressed: ", px , "x" ,py)
print ("Outside function released: ", rx , "x" , ry)
However I am stumped as with the output (outside the functions as it still shows 0 whereas as the variable inside the function is showing actual values.)Sample results is as followed:
I just wanted the values of variable inside the function can be "transferred" to the varible outside of the functions. Thanks in advance.
Outside function pressed: 0 x 0
Outside function released: 0 x 0
>>> Inside function pressed at 293x249
Inside function released at 768x815
rr
There's probably a better method, but this works:
from pynput import mouse
import time
pressed_location = 0, 0
released_location = 0, 0
def on_click(x, y, button, pressed):
global pressed_location
global released_location
if pressed:
pressed_location = x, y
else:
released_location = x, y
print('You pressed at {0}x{1} and released at {2}x{3}'.format(*pressed_location, *released_location))
listener = mouse.Listener(on_click=on_click)
listener.start()
while True:
time.sleep(1)
I've created a global variable pressed_location, which we give a default value to. If the user presses the mouse, the location gets stored in there. If the user releases the mouse, we show the pressed location and the released location.
Example output:
You pressed at 103x412 and released at 299x559
You pressed at 207x478 and released at 207x478
In the first event above I moved the mouse after pressing. In the second event I just clicked.
After tinkering codes for quite a while, it works.
Thank you to iѕєρєня and Robson for your help
from pynput import mouse
import time
global pressed_location
global released_location
#Initialize
px = py = rx = ry = 0
def on_click(x,y, button, pressed):
global px
global py
global rx
global ry
if pressed:
px, py = x, y
else:
rx , ry = x, y
if not pressed:
print("Inside function pressed x : " ,px , " ", py)
print("Inside function released y : " ,rx, " ", ry)
return False
return px
return py
return rx
return ry
listener = mouse.Listener(
on_click=on_click)
listener.start()
# some times needed for function to finish register the mouse location
time.sleep(3)
print("Outside function pressed x : " ,px , " ", py)
print("Outside function released y : " ,rx, " ", ry)
Output as followed:
Inside function pressed x : 505 206
Inside function released y : 1084 892
Outside function pressed x : 505 206
Outside function released y : 1084 892

Taking screenshot of a specific space using python

I am trying to take a screenshot of a specific region using python.
I wrote this code:
import pyscreenshot
from pynput.mouse import Listener
x=1
y=1
def on_click(x1, y1, button, pressed):
global x,y
x = x1
y = y1
def on_release(x2,y2, button, pressed):
global x,y
im = pyscreenshot.grab(x,y,x2,y2)
im.save("hello.png")
#Collect events until released
with Listener(
on_click=on_click,
on_release=on_release) as listener:
listener.join()
Here the problem is that it don't output anything.Please Help
I made a code for you. It works fine in my side. Please let me know your opinion after running my code.
import pyscreenshot
from pynput.mouse import Listener, Button
global x0, y0
def on_click(x1, y1, button, pressed):
global x0, y0
if button == Button.left and pressed:
x0, y0 = x1, y1
if button == Button.left and not pressed:
try:
im = pyscreenshot.grab(bbox=(x0, y0, x1, y1))
im.save("hello.png")
print('Screenshot was taken.')
return False
except:
pass
return True
# Collect events until released
with Listener(
on_click=on_click) as listener:
try:
listener.join()
except:
pass

pynput mouse position coordinate to variable and use of variable on a global scale

I'm trying to save the mouse's x and y coordinates when the mouse button is pressed and, separately, when it is released. I am able to print them but unable to save them to variables.
Here's what I got:
from pynput.mouse import Listener
def on_click(x, y, button, pressed):
print('{0} at {1}'.format(
'Pressed' if pressed else 'Released',
(x, y)))
if not pressed:
# Stop listener
return False
with Listener(on_click=on_click) as listener:
listener.join()
And then how would I call these variables on a global scale to use with another module (e.g. pyautogui?)
You've got pretty much everything in place, so I only had to add a few lines. Globals aren't the very best way to do things, but since this program isn't too complex, they will do the job.
The initial values of down_x, etc. don't really matter, as they will be overwritten, but they have to be there, or Python will throw an error.
#if you want to delay between mouse clicking, uncomment the line below
#import time
from pynput.mouse import Listener
import pyautogui
down_x = down_y = up_x = up_y = -1
def on_click(x, y, button, pressed):
global down_x
global down_y
global up_x
global up_y
if pressed:
(down_x, down_y) = (x, y)
else:
(up_x, up_y) = (x, y)
return False
with Listener(on_click=on_click) as listener:
listener.join()
print("Mouse drag from", down_x, ",", down_y, "to", up_x, ",", up_y)
# you may wish to import the time module to make a delay
#time.sleep(1)
pyautogui.mouseDown(down_x, down_y)
#time.sleep(1)
pyautogui.mouseUp(up_x, up_y)
Use global variables:
from pynput.mouse import Listener
xx, yy = 0, 0
def on_click(x, y, button, pressed):
global xx, yy
xx, yy = x, y
print('{0} at {1}'.format(
'Pressed' if pressed else 'Released',
(x, y)))
if not pressed:
# Stop listener
return False
with Listener(on_click=on_click) as listener:
listener.join()
# here you can read xx and yy
If your code gets more complicated you can consider wrapping it up in a class.

How to detect if mouse was clicked?

I'm trying to build a short script in Python, where if the mouse is clicked, the mouse will reset to some arbitrary position (right now the middle of the screen).
I'd like this to run in the background, so it could work with other applications (most likely Chrome, or some web browser). I'd also like it so that a user could hold down a certain button (say CTRL) and they could click away and not have the position reset. This way they could close the script without frustration.
I'm pretty sure I know how to do this, but I'm not sure which library to use. I'd prefer if it was cross-platform, or at least work on Windows and Mac.
Here's my code so far:
#! python3
# resetMouse.py - resets mouse on click - usuful for students with
# cognitive disabilities.
import pymouse
width, height = m.screen_size()
midWidth = (width + 1) / 2
midHeight = (height + 1) / 2
m = PyMouse()
k = PyKeyboard()
def onClick():
m.move(midWidth, midHeight)
try:
while True:
# if button is held down:
# continue
# onClick()
except KeyboardInterrupt:
print('\nDone.')
Try this
from pynput.mouse import Listener
def on_move(x, y):
print(x, y)
def on_click(x, y, button, pressed):
print(x, y, button, pressed)
def on_scroll(x, y, dx, dy):
print(x, y, dx, dy)
with Listener(on_move=on_move, on_click=on_click, on_scroll=on_scroll) as listener:
listener.join()
The following code worked perfectly for me. Thanks to Hasan's answer.
from pynput.mouse import Listener
def is_clicked(x, y, button, pressed):
if pressed:
print('Clicked ! ') #in your case, you can move it to some other pos
return False # to stop the thread after click
with Listener(on_click=is_clicked) as listener:
listener.join()
I was able to make it work just with win32api. It works when clicking on any window.
import win32api
import time
width = win32api.GetSystemMetrics(0)
height = win32api.GetSystemMetrics(1)
midWidth = int((width + 1) / 2)
midHeight = int((height + 1) / 2)
state_left = win32api.GetKeyState(0x01) # Left button up = 0 or 1. Button down = -127 or -128
while True:
a = win32api.GetKeyState(0x01)
if a != state_left: # Button state changed
state_left = a
print(a)
if a < 0:
print('Left Button Pressed')
else:
print('Left Button Released')
win32api.SetCursorPos((midWidth, midHeight))
time.sleep(0.001)
I was able to make it work for Windows using pyHook and win32api:
import win32api, pyHook, pythoncom
width = win32api.GetSystemMetrics(0)
height = win32api.GetSystemMetrics(1)
midWidth = (width + 1) / 2
midHeight = (height + 1) / 2
def moveCursor(x, y):
print('Moving mouse')
win32api.SetCursorPos((x, y))
def onclick(event):
print(event.Position)
moveCursor(int(midWidth), int(midHeight))
return True
try:
hm = pyHook.HookManager()
hm.SubscribeMouseAllButtonsUp(onclick)
hm.HookMouse()
pythoncom.PumpMessages()
except KeyboardInterrupt:
hm.UnhookMouse()
print('\nDone.')
exit()

Categories

Resources