I am using PyAutoGUI library. How can I know if the left mouse button is pressed?
This is what I want to do:
if(leftmousebuttonpressed):
print("left")
else:
print("nothing")
(I'm the author of PyAutoGUI.) I can confirm that currently PyAutoGUI can't read/record clicks or keystrokes. These features are on the roadmap, but there aren't any resources or timelines dedicated to them currently.
How to know if left mouse click is pressed?
A simple version of the code inspired from the original documentation:
from pynput import mouse
def on_click(x, y, button, pressed):
if button == mouse.Button.left:
print('{} at {}'.format('Pressed Left Click' if pressed else 'Released Left Click', (x, y)))
return False # Returning False if you need to stop the program when Left clicked.
else:
print('{} at {}'.format('Pressed Right Click' if pressed else 'Released Right Click', (x, y)))
listener = mouse.Listener(on_click=on_click)
listener.start()
listener.join()
Like Sir Al Sweigart mentioned in the comment above, I looked for pynput module which works perfect. See documentation and PyPi instructions at:
https://pynput.readthedocs.io/
https://pypi.org/project/pynput/
Install the library using pip: pip install pynput
Monitoring other events (e.g. Mouse move, click, scroll)
See the code under Monitoring the mouse heading from original documentation.
https://pynput.readthedocs.io/en/latest/mouse.html#monitoring-the-mouse
I don't think you can use PyAutoGui to listen for mouseclick.
Instead try Pyhook (from their source page):
import pythoncom, pyHook
def OnMouseEvent(event):
# called when mouse events are received
print 'MessageName:',event.MessageName
print 'Message:',event.Message
print 'Time:',event.Time
print 'Window:',event.Window
print 'WindowName:',event.WindowName
print 'Position:',event.Position
print 'Wheel:',event.Wheel
print 'Injected:',event.Injected
print '---'
# return True to pass the event to other handlers
return True
# create a hook manager
hm = pyHook.HookManager()
# watch for all mouse events
hm.MouseAll = OnMouseEvent
# set the hook
hm.HookMouse()
# wait forever
pythoncom.PumpMessages()
I believe you can you do this:
import pyHook, pythoncom
def left_down():
print("left down")
def right_down():
print("right down")
hm = pyHook.HookManager()
hm.SubscribeMouseLeftDown(left_down)
hm.SubscribeMouseRightDown(right_down)
hm.HookMouse()
pythoncom.PumpMessages()
hm.UnhookMouse()
They also do keyboards events, just go look their api up.
Edit:
Here's their mini tutorial: https://sourceforge.net/p/pyhook/wiki/PyHook_Tutorial/
Also PyHook is only for windows (thanks to John Doe for pointing it out)
you can use win32api which is a built-in library as in the following example:
import win32api
if win32api.GetKeyState(0x01)<0: #if mouse left button is pressed
#do something
else: #if mouse left button is not pressed
#do something
as for why that code functions like that here's the explanation:
you do "<0" because the GetKeyState function returns either a negative number or 1 or 0, 1 or 0 are for when the button is released and it changes each time u let go and the negative number is for when the button is pressed, as an example if the mouse button is now returning a 0 using the GetKeyState function and you press it it will return a negative number until u let go and then it will return 1, and if it was a 1 and u press the button it will return a negative number while your holding it down and then once u let go it will go back to being 0 (you can print(GetKeyState(0x01) and see for yourself for a better understanding), as for "0x01" thats the virtual key code for the left mouse button and you can find all the virtual keycodes of each and every button on the mouse and the keyboard using this site provided by microsoft themselves https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
Related
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.
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()
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()
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
At the moment I'm trying to use Python to detect when the left mouse button is being held and then start to rapidly send this event instead of only once. What I basically want to do is that when the left mouse button is held it clicks and clicks again until you let it go. But I'm a bit puzzled with the whole Xlib, I think it's very confusing actually. Any help on how to do this would be really awesome. That's what I've got so far:
#!/usr/bin/env python
import Xlib
import Xlib.display
def main():
display = Xlib.display.Display()
root = display.screen().root
while True:
event = root.display.next_event()
print event
if __name__ == "__main__":
main()
But there is unfortunately no output in the console. After a quick search on the internet I found the following:
root.change_attributes(event_mask=Xlib.X.KeyPressMask)
root.grab_key(keycode, Xlib.X.AnyModifier, 1, Xlib.X.GrabModeAsync,
Xlib.X.GrabModeAsync)
This is seemingly import to catch a special event with the given keycode. But firstly what keycode does the left-mouse click have, if any at all? And secondly how can I detect when it is being held down and then start sending the mouseclick event rapidly. I would be really grateful for help. (Maybe a way to stop this script with a hotkey would be cool aswell...)
Actually you want Xlib.X.ButtonPressMask | Xlib.X.ButtonReleaseMask, to get events for button presses and releases (different from key presses and releases). The events are ButtonPress and ButtonRelease, and the detail instance variable gives you the button number. From when you get the press event, to when you get the release event, you know the button is being held down. Of course you can also receive key events and do something else (e.g. exit your script) when a certain key is pressed.
Edit: this version works fine for me, for example...:
import Xlib
import Xlib.display
def main():
display = Xlib.display.Display(':0')
root = display.screen().root
root.change_attributes(event_mask=
Xlib.X.ButtonPressMask | Xlib.X.ButtonReleaseMask)
while True:
event = root.display.next_event()
print event
if __name__ == "__main__":
main()