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()
Related
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()
Here is my prank code for my friend but I can not stop this program from keyboard when I make executable.
How can I stop this listener from keyboard shortcut. I know it is thread issue.
import sys
import pyautogui
import keyboard
from pynput.mouse import Listener
from threading import Thread
global x,y
def on_move(x, y):
print ("Mouse moved to ({0}, {1})".format(x, y))
def on_click(x, y, button, pressed):
try: #FOR AUTO FAIL-SAFE
if pressed:
print ('Mouse clicked at ({0}, {1}) with {2}'.format(x, y, button))
pyautogui.move(x+100,y+100)
except:
pass
def on_scroll(x, y, dx, dy):
print ('Mouse scrolled at ({0}, {1})({2}, {3})'.format(x, y, dx, dy))
with Listener(on_move=on_move, on_click=on_click, on_scroll=on_scroll) as listener:
listener.join()
while True:
if keyboard.is_pressed("q"):
sys.exit(0)
break
So here is my fix. I works because I had the same problem:
Insert:
from pynput.keyboard import Key
then:
In on_move(), on_click(), and on_scroll() add:
if key == Key.f10:
sys.exit()
This will check that when you press f10 (or you can change), the program will exit
You also need to pass key as an argument!
The full updated code is:
import sys
import pyautogui
import keyboard
from pynput.keyboard import Key
from pynput.mouse import Listener
from threading import Thread
global x,y
def on_move(key, x, y):
print ("Mouse moved to ({0}, {1})".format(x, y))
if key == Key.f10:
sys.exit()
def on_click(key, x, y, button, pressed):
try: #FOR AUTO FAIL-SAFE
if pressed:
print ('Mouse clicked at ({0}, {1}) with {2}'.format(x, y, button))
pyautogui.move(x+100,y+100)
except:
pass
if key == Key.f10:
sys.exit()
def on_scroll(key, x, y, dx, dy):
print ('Mouse scrolled at ({0}, {1})({2}, {3})'.format(x, y, dx, dy))
if key == Key.f10:
sys.exit()
with Listener(on_move=on_move, on_click=on_click, on_scroll=on_scroll) as listener:
listener.join()
while True:
if keyboard.is_pressed("q"):
sys.exit(0)
break
I solved this problem. When mouse position(x,y) on left-top and mid scrolled. Program finishes itself.
def on_scroll(x, y, dx, dy):
print('Scrolled {0} at {1}'.format(
'down' if dy < 0 else 'up',
(x, y,dx,dy)))
if x<100 and y<100:
return False
I'm trying to detect what mouse button was clicked
so here is my code:
from pynput.mouse import Listener
def on_click(button, pressed):
if button.Left and pressed:
print("You pressed the left mouse button")
if button.Right and pressed:
print("You pressed the right mouse button")
so there was no errors but It's not working any Ideas?
From the Documentation Here
CODE
from pynput import mouse
def on_move(x, y):
print('Pointer moved to {0}'.format(
(x, y)))
def on_click(x, y, button, pressed):
print(button) # Print button to see which button of mouse was pressed
print('{0} at {1}'.format(
'Pressed' if pressed else 'Released',
(x, y)))
# Collect events until released
with mouse.Listener(
on_click=on_click
) as listener:
listener.join()
# ...or, in a non-blocking fashion:
listener = mouse.Listener(on_click=on_click)
listener.start()
As you can see, the button parameter in the function on_click tells you which button was pressed.
EDIT:
Here is how you may handle action based on which button of the mouse was pressed
def on_click(x, y, button, pressed):
btn = button.name
if btn == 'left':
print('Left if Pressed')
# ====== < Handle Pressed or released Event ====== > #
if pressed:
print('Do somethin when Pressed with LEft')
else:
print('LEFT is Released')
elif btn == 'right':
print('Right BTN was pressed ')
# ====== < Handle Pressed or released Event ====== > #
if not pressed:
print('right Button is released')
else:
pass
I post a second answer because of a different nature of the issue found on code here
The issue is how you call the imports.
CORRET CODE
from pynput import mouse
mouse_ = mouse.Controller()
button = mouse.Button
def on_click(x, y, button, pressed):
btn = button.name
if btn == 'left':
if pressed:
mouse_.click(button_.left)
print('works')
with mouse.Listener(
on_click=on_click
) as listener:
listener.join()
Copy and Paste the code without changes.
WARNING
when I use button.left my pc becomes extremely lagy so i suggest you to don't use is unless you know what you are doing
As I said, I'm pretty new to coding and python, and I need to make an auto clicker that toggles when I hold left click and stops when i release the button. The current code makes a key bind that toggles it off and on. I was searching the web for the last few days and couldn't find anything. Thanks in advance!
import time
import threading
import random
from pynput.mouse import Button, Controller
from pynput.keyboard import Listener, KeyCode
x = (0.7, 0.8, 0.9, 0.11)
delay = random.choice(x)
button = Button.left
start_stop_key = KeyCode(char='s')
exit_key = KeyCode(char='e')
class ClickMouse(threading.Thread):
def __init__(self, delay, button):
super(ClickMouse, self).__init__()
self.delay = delay
self.button = button
self.running = False
self.program_running = True
def start_clicking(self):
self.running = True
def stop_clicking(self):
self.running = False
def exit(self):
self.stop_clicking()
self.program_running = False
def run(self):
while self.program_running:
while self.running:
mouse.click(self.button)
time.sleep(self.delay)
time.sleep(0.1)
mouse = Controller()
click_thread = ClickMouse(delay, button)
click_thread.start()
def on_press(key):
if key == start_stop_key:
if click_thread.running:
click_thread.stop_clicking()
else:
click_thread.start_clicking()
elif key == exit_key:
click_thread.exit()
listener.stop()
with Listener(on_press=on_press) as listener:
listener.join()
mouse = Controller()
click_thread = ClickMouse(delay, button)
click_thread.start()
def on_press(key):
if key == start_stop_key:
if click_thread.running:
click_thread.stop_clicking()
else:
click_thread.start_clicking()
elif key == exit_key:
click_thread.exit()
listener.stop()
with Listener(on_press=on_press) as listener:
listener.join()
For what it is worth, I would look to this approach:
PyAutoGUI Chapter
With full documentation here:
PyAutoGUI Docs:
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()