Why is there such latency when clicking using pyautogui? - python

I've got a small and simple piece of code which is supposed to make it so you are unable to click and hold. It works fine, however it has a large amount of latency and when I click it takes about half a second or more for it to interact with anything on my screen.
I've also noticed that sometimes it will do something to my cursor which makes my cursor move at about 5 fps with extremely high resistance and momentum (by momentum I mean it keeps moving even when I stop moving the mouse).
I'm wondering if I'm doing something wrong or maybe there's some other module which is better for the job?
This is my code:
import pyautogui
from pynput import mouse, keyboard
def on_click(x, y, button, pressed):
if button == mouse.Button.left:
if pressed:
pyautogui.mouseUp()
return True
while True:
listener = mouse.Listener(on_click=on_click)
listener.start()
listener.join()

I don't have the same issues you have on your machine. But it could be that inside your loop you are continually starting the listener? Try putting the listener outside the loop and just have a pass inside the loop:
import pyautogui
from pynput import mouse, keyboard
def on_click(x, y, button, pressed):
if button == mouse.Button.left:
if pressed:
print('doogie')
pyautogui.mouseUp()
return True
listener = mouse.Listener(on_click=on_click)
listener.start()
listener.join()
while True:
pass

Related

How to stop infinite loops using pynput and pyautogui?

I was trying to emulate "double-clicking" often used in gaming mouses as a python programme but after making a short programme and reading the docs, I realized I caused an infinite loop of clicking!
Now, I would like to continue but I don't know what the best way out of the infinite loop.
My Code:
import pyautogui
import random
from pynput import mouse
def on_click(x, y, button, pressed):
pyautogui.click()
x = random.randint(1, 2)
if x == 2:
pyautogui.click()
# Collect events until released
with mouse.Listener(
on_click=on_click) as listener:
listener.join()
Thanks!

Python pyautogui/pynput click function

I tried making a simple autoclicker but it is not working for me.My cursor is moving slowly as f***.
You guys have an idea how to fix this?
Problem: line 11, pyautogui.click(button='left') is not clicking.
from pynput.mouse import Listener, Button, Controller
import pyautogui
# This function will be called when any key of mouse is pressed
def on_click(*args):
# see what argument is passed.
print(args)
if args[-1]:
# Do something when the mouse key is pressed.
print('The "{}" mouse key has held down'.format(args[-2].name))
pyautogui.click(button='left') # <--- lagging mouse
elif not args[-1]:
# Do something when the mouse key is released.
print('The "{}" mouse key is released'.format(args[-2].name))
# Open Listener for mouse key presses
with Listener(on_click=on_click) as listener:
# Listen to the mouse key presses
listener.join()
Supposing this is on a while or for loop, you can make it faster by changing the pyautogui.pause variable. Write this on top of your code:
pyautogui.PAUSE = .001
It specifies the delay between each pyautogui function call.
On my Windows 10 Computer running the topic poster code from question led to Python window that doesn't close for an hour and I can't close it with Task Manager.
So be careful with executing this code.

Python 3.x Collecting Mouse Events

I'm just trying to learn the "Listener" function. But I couldn't manage to break any loop with mouse clicking. Here is an example:
from pynput.mouse import Listener
import time
def on_click(x, y, button, pressed):
counter = 0
while True:
print(counter)
counter += 1
time.sleep(1)
if pressed:
break
with Listener(on_click = on_click) as listener:
listener.join()
When I'm running this code, my PC is getting very slow. I'm a beginner. I need to use listener with normal codes.
Thanks
Keep in mind that on_click function is called twice. Once when you press the mouse button down, and again when the button is released. Since the function will be called twice, we cannot break the loop that the first function call creates by calling it again with a different value for the state of the mouse button.
I am assuming your intention was to print counter every second the mouse button is held down. I have a snippet below for you that uses threading to accomplish this, and each call to the on_click function can read the state of the mouse as well as the state of the thread used for printing.
While using time.sleep() within a function it causes the thread it was called in to sleep. When you only have one thread running it causes the entire program to sleep every second. I believe that your computer was not lagging, however the mouse would appear to lag because your input is being interrupted by the call to sleep every second.
from pynput import mouse
import time
from threading import Thread
def on_click(x, y, button, pressed):
thread = Thread(target = threaded_function)
if pressed and thread.is_alive() == False:
thread.start()
if not pressed:
if thread.is_alive():
thread.join()
return False
def threaded_function():
count = 0
while True:
count+=1
print(count)
time.sleep(1)
with mouse.Listener(on_click = on_click) as listener:
listener.join()

Python check if Left Mouse Button is being held?

I'm pretty new to Python and I'd like to make a kind of an Autoclicker, which keeps clicking every 0.1 seconds when my left mouse button is held down.
My Problem is, that when I run my script, my mouse instantly starts clicking. What should I do?:
import win32api
import time
from pynput.mouse import Button, Controller
mouse = Controller()
while True:
if win32api.GetAsyncKeyState(0x01):
mouse.click(Button.left, 1)
time.sleep(0.1)
else:
pass
Thanks
My Problem is, that when I run my script, my mouse instantly starts clicking. What should I do?
If the function succeeds, the return value specifies whether the key
was pressed since the last call to GetAsyncKeyState, and whether the
key is currently up or down. If the most significant bit is set, the
key is down, and if the least significant bit is set, the key was
pressed after the previous call to GetAsyncKeyState.
You should use win32api.GetAsyncKeyState(0x01)&0x8000 instead.
Now, the only thing it does is click once, which makes my click a double click.
Because GetAsyncKeyState detects the key state of the left mouse button. When you press the left mouse button, the click function is called, click will realize the two actions of the left mouse button press and release. Then in the place of the while loop, GetAsyncKeyState will detect the release action, which is why it stops after double-clicking.
I suggest you set the left mouse button to start and the right mouse button to stop.
Code Sample:
import win32api
import time
from pynput.mouse import Button, Controller
mouse = Controller()
while True:
if (win32api.GetAsyncKeyState(0x01)&0x8000 > 0):
flag = True
while flag == True:
mouse.click(Button.left, 1)
time.sleep(0.1)
if (win32api.GetAsyncKeyState(0x02)&0x8000 > 0):
flag = False
else:
pass
Check if win32api.GetAsyncKeyState(0x01) < 0 in the if condition.
I made it work with mouse5!
import win32api
import win32con
import time
from pynput.mouse import Button, Controller
mouse = Controller()
def ac():
if keystate < 0:
mouse.click(Button.left, 1)
time.sleep(0.1)
else:
pass
while True:
keystate = win32api.GetAsyncKeyState(0x06)
ac()

Unable To Break Out Of While Loop When Using Pynput.mouse

I have this relatively simple program that listens for mouse clicks and when the mouse button is held down prints "1"s. Unfortunately when I let go of the mouse it just keeps printing "1"s, even though there is an if statement which checks if the mouse is clicked and should stop the loop if it is not. I am using the pynput.mouse module for the mouse interaction.
Here is my code:
import time
from pynput.mouse import Listener
def clicked(x, y, button, pressed):
if pressed == True:
while button == button.left:
print("1")
time.sleep(1)
if pressed == False:
break
with Listener(on_click=clicked) as listener:
listener.join()
My theory is that once the loops starts it stops listening for mouse clicks, so it can never stop the loop. Would it be necessary to create a new thread for the loop? If yes, how would I do that?
Thanks!
Your current logic makes it impossible to get out of the loop, since pressed doesn't change within the loop. There is not a statement that checks if the mouse is clicked: your only if statements check whether the mouse was clicked when you entered the function. pressed doesn't change within the function.
Look at the critical logiic:
if pressed == True:
while ...
...
if pressed == False:
break
There is nothing in here to change the value of pressed; the first if guarantees that it's True anywhere within the loop.
Yes, you need to set up another listener that operates within the loop. You already know the building blocks: create a new one within the function and bind it to another operation that breaks the loop. For instance, you might "cheat" and have it reset pressed as a global variable.
You could also research how to do this in other answers, if you want an overall handler solution. keypress and keyrelease have been done often enough.
import pyautogui, random, time
import pynput
keys = ['w', 's', 'a', 'd']
def on_press(key):
p = True
if key == pynput.keyboard.Key.esc:
return False
else:
while p == True:
press = keys[random.randint(0,3)]
pyautogui.keyDown(press)
pyautogui.keyUp(press)
p = False
with pynput.keyboard.Listener(on_press=on_press) as L:
L.join()
a code like this will work instead of what you did.
BTW, that is just an example; feel free to visit my GitHub page: github.com/ironnicko

Categories

Resources