How to stop infinite loops using pynput and pyautogui? - python

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!

Related

Why is there such latency when clicking using pyautogui?

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

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()

Making A Bot In Python

I was making a bot that would basically keep the left mouse button clicked or unclicked based on a toggle. I get it to work but then it started lagging my entire computer so I didn't take it one step further, being scared to burn my PC, how It happened to my phone one year ago. So we are finally here asking you guys for some optimization to my project.
Code:
import keyboard
import win32api, win32con
from pynput.mouse import Button, Controller
mouse = Controller()
play=False
def toggle():
global play
if play==False:
play=True
else:
play=False
keyboard.add_hotkey('home',toggle)
played=False
while True:
if play==True and played==False:
played=True
mouse.press(Button.left)
elif play==False:
mouse.release(Button.left)
played=False
else:
pass
You should put a time.sleep() or something to wait between each loop because your while statement is running again and again without any pauses.
You can slow the while loop by inserting a sleep function in it. To do this, import the module time and call the function time.sleep(ms) in your while loop. It will be less reactive but you can set a sleep time of only a few ms and it will be better because the program will not be running at full speed all the time.

How to simulate a mouse click while holding the SHIFT key in Windows?

Hello I'm trying to simulate a mouse click while holding the SHIFT key. I have been trying to do this with the pynput module.
This is my code so far:
from pynput.keyboard import Key
from pynput.keyboard import Controller as Cont
from pynput.mouse import Button, Controller
import time
mouse = Controller()
keyboard = Cont()
with keyboard.pressed(Key.shift):
mouse.position = (1892, 838)
mouse.click(Button.left)
I know the code for holding the shift key is working (If I try to press the
"a" button in the code I see an "A"). Also I know the mouse click is working. However, together it does not work.
Also I tried another code from a StackOverflow post: Pyautogui - Need to hold shift and click
I tried the following code from it:
import pyautogui
pyautogui.keyDown('shift')
pyautogui.click()
pyautogui.keyUp('shift')
This worked for a minute then it stopped working! Very strange. It fails like 9 out of 10 times.
You should add a timer to it most likely will work.
import pyautogui
import time
#cordinates
cordinates = 100,100
pyautogui.keyDown('shift')
time.sleep(0.15)
pyautogui.click(cordinates)
time.sleep(0.15)
pyautogui.keyUp('shift')
The script works as intended, but it seems the target on which you are trying to apply Shift + Left-Click is not accepting such inputs while its window on Windows GUI is not in focus. That is why it works when you include a Left-Click before the Shift + Left-Click, because that first click puts the target window (whatever program/app it is) in focus, then the already working but ignored Shift + Left-Click is also accepted by the target
Well a workaround i suggest is creating an event listener like this :
from pynput.keyboard import Key, Listener
def on_press(key):
print('{0} pressed'.format(
key))
def on_release(key):
print('{0} release'.format(
key))
if key == Key.esc:
# Stop listener
return False
enter code hereCollect events until released
with Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()

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