Trying to do a program that double clicks for you when you click the left mouse button once with pynput. I have the following code, but if I run the code, my mouse glitches out and stops working.
from pynput.mouse import Listener, Button, Controller
mouse = Controller()
def on_click(x, y, button, pressed):
if pressed == True:
mouse.click(Button.left, 2)
else:
pass
with Listener(on_click=on_click) as listener:
listener.join()
Also in addition of this, how would the implementation of pressing "F10" enables that 1 click acts like double click and pressing "F10" again would disable it, so 1 click would act like 1 click be possible?
Oh,I maybe find your problem,
Two probable causes:
In your script,when your press the mouse button.It will call function on_click.Then it will mouse.click(Button.left, 2).But this code will also call on_click.So it will be a endless loop.Finally,you will find your mouse will be not responding.So I think you should use another way to do that.
In pynput official document,It seems it can be used in macOS(maybe windows couldn't use it.And I also found if I only use mouse.click(Button.left, 2) in my PC,my python will be not responding.(It couldn't be stopped).Maybe you should just use .press and .release directly):
Also in addition of this, how would the implementation of pressing "F10" enables that 1 click acts like double click and pressing "F10" again would disable it.
So this seems a switch,you can use a global variable to do that.There is a minimal example of use pynput to do a switch.(This will don't print Mode is on if you don't press F10,and it won't print it after you press F10 again).
# import win32api,win32con
from pynput.mouse import Controller
from pynput import keyboard
from pynput.keyboard import Key
mouse = Controller()
Mode = False
def on_press(key):
global Mode
if key == Key.f10:
if Mode:
Mode = False
else:
Mode = True
listener = keyboard.Listener(on_press=on_press)
listener.start()
while True:
if Mode:
print("Mode is on")
Related
I'm using the python pynput module to send emulated keypresses to my computer. I've tried it also with pyautogui, but either case has a problem: I'm trying to detect my own keypresses simulatneously, and my program is detecting the pynput emulated keypresses as well, with no way of filtering them.
from pynput.keyboard import Key, Listener, Controller
keyboard = Controller()
def write(word):
global keyboard,typing
keyboard.type(word)
def on_press(key):
global curword
key = str(key).replace("'","")
if key.isalpha():
write("hello") #when it detects a letter being pressed, it writes hello
def on_release(key):
pass
with Listener(on_press=on_press,on_release=on_release) as listener:
listener.join() #detects keypresses
Essentially, I'm trying to make a code that just autocompletes words when I type them, but when the program 'writes' the word out, the pynput listener detects the controller typing and creates an infinite loop.
I'm writing a background scrypt that requires a left mouse button to be pressed. Currently my code looks something like this:
from pynput.mouse import Button
from pynput.mouse import Controller
mouse = Controller()
def main():
mouse.press(Button.left)
while True:
#do sth every n seconds
main()
However, background activity sometimes causes the mouse button to be released.
Is there a way to check if the key is pressed within the while loop (Something like mouse.is_pressed(Button.left)) other than adding another mouse.press(pynput.mouse.Button.left) every iteration of loop?
I have tried to search google and other websites such as GitHub but I cant find a way to detect if the right key has been pressed. I am using the two modules Keyboard and Pyautogui to make a auto clicker but all the ideas that I have come up with have failed. Here is my code:
import keyboard
import pyautogui
pyautogui.PAUSE = 0.1
while True:
if keyboard.is_pressed('h'):
pyautogui.rightClick()
if keyboard.is_pressed('g'):
pyautogui.click()
I want a way to replace the h and g with right click and left click any ideas?
If you are trying to check for just mouse clicks, the pynput library could work.
from pynput import mouse
# mouse.Events looks at all events, you could use
# events = mouse.Events().get(1) to look at just the events in the last second
with mouse.Events() as events:
for event in events:
if isinstance(event, mouse.Events.Click):
if event.button == mouse.Button.right and event.pressed:
#Do stuff for right click
else:
print('Received event {}'.format(event))
I am using Click so that movements are not tracked. Similarly, press down/up are counted as separate events, so to filter those out using event.pressed
Take a look at https://pynput.readthedocs.io/en/latest/mouse.html for other mouse listener ideas
Having trouble turning 1 mouse click into multiple mouse clicks. Basically what I want to do is to control multiple windows at once. I want to click on one master window and have the clicks propagate to the subsequent windows. In this snippet there are 4 windows and I track them via determining the offset between it and the master window.
I'm using python3 with pynput for the mouse listener and pyautogui for mouse control.
What I'm having a problem with is setting up the mouse listener such that it listens to my actual clicks but ignores the programmatic clicks. Right now, I think it's getting stuck in an infinite loop where my initial click triggers the on_click event, propagates the clicks, each triggering an additional on_click event, propagates the clicks, etc. When I run the below code it starts fine, and then when I first click it just heavily lags my mouse for a minute before return back to normal with no mouse listener active anymore. My guess is that a failsafe kicks in to return it to normal.
Things I have tried:
using pynput for listener and control - this does not change the outcome
stopping the listener and creating a new one after propagated clicks have finished - bad hacky solution that still did not change the outcome
semaphore locking with _value peeking to ignore events if semaphore has already been acquired - also hacky and did not work
calling propagateActions via threading and waiting for completion before returning from on_click event - did not work
commenting out pyautogui.click() - this allows for expected behavior to move the mouse to the subsequent locations and return it back to its initial position after. Without the click, it works perfect. With the click, it lags and the listener dies.
searching stackoverflow - this question bears a resemblance in terms of outcome, but is unanswered and is trying to achieve something different.
My snippet is below:
from pynput import mouse, keyboard
import pyautogui
pyautogui.PAUSE = 0.01
mouseListener = None
killSwitch = False
# this is just a keyboard listener for a kill switch
def on_release(key):
if key == keyboard.Key.f1:
global killSwitch
print('### Kill switch activated ###')
killSwitch = True
# on mouse release I want to propogate a click to 4 other areas
def on_click(x, y, button, pressed):
print('{0} at {1}'.format('Pressed' if pressed else 'Released', (x, y)))
if not pressed:
propogateActions(x, y, button)
# propogates clicks
def propogateActions(x, y, button):
print('propogating actions to {0} windows'.format(len(offsets)+1))
for offset in offsets:
pyautogui.moveTo(x+offset.x, y+offset.y)
print('mouse moved')
if button == mouse.Button.left:
print('left clicking at ({0}, {1})'.format(x+offset.x, y+offset.y))
pyautogui.click()
pyautogui.moveTo(x, y)
# point class for ease of use
class Point():
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return 'Point(x={0}, y={1})'.format(self.x, self.y)
# main method
def doTheThing():
print('started')
while not killSwitch:
pass
# initializations and starting listeners
# offsets tracks how far the subsequent clicks are from the initial click point
offsets = [Point(50, 0), Point(50, 50), Point(0, 50)]
keyboardListener = keyboard.Listener(on_release=on_release)
mouseListener = mouse.Listener(on_click=on_click)
keyboardListener.start()
mouseListener.start()
doTheThing()
My Question:
Is there some way to listen only for "real" clicks and not programmatic clicks?
If not, can I pause the mouse listener and then restart it some way after the propagated clicks have occurred?
This is the small section of code that's relevant to the issue at hand. offsets has an initialization that sets it more appropriately and there's other bells and whistles, but this is the section relevant to the problem. I appreciate your help.
Found the answer! Had to go a layer deeper.
Pynput has a method of suppressing events that exposes the win32 data behind the click event. Ran a test of one of my clicks vs a pyautogui.click() and lo-and-behold there is a difference. The data.flags was set to value 0 on a user click event and set to value 1 on a programmatic click.
That's good enough for me to filter on. This is the pertinent filter:
def win32_event_filter(msg, data):
if data.flags:
print('suppressing event')
return False
added that to my above code and changed the
mouseListener = mouse.Listener(on_click=on_click)
to
mouseListener = mouse.Listener(on_click=on_click, win32_event_filter=win32_event_filter)
and it works!
My real clicks prevail, programmatic clicks are propagated, and I am not stuck in an infinite loop. Hope this helps if others run into this issue.
I am searching for a way to create a cross-platform keyboard shortcut in Python. Such that when I press something like Ctrl+C or Ctrl+Alt+F, the program will run a certain function.
Does there exist such method or library?
I don't know is it possible to send combinations of Ctrl and/or alt. I tried couple of times but I think it doesn't work. (If someone has any other information please correct me). What you can do is something like this:
from msvcrt import getch
while True:
key = ord(getch())
if key == 27: #ESC
PrintSomething()
def PrintSomething():
print('Printing something')
this will run a scrpit every time you press ESC although it will only work when you run it in command prompt.
You can create a listener for keypress event by pynput library.
this is a simple code that run a function when press CTRL+ALT+H keys:
from pynput import keyboard
def on_activate():
print('Global hotkey activated!')
def for_canonical(f):
return lambda k: f(l.canonical(k))
hotkey = keyboard.HotKey(
keyboard.HotKey.parse('<ctrl>+<alt>+h'),
on_activate)
with keyboard.Listener(
on_press=for_canonical(hotkey.press),
on_release=for_canonical(hotkey.release)) as l:
l.join()
Try keyboard. It can be installed with pip install keyboard, and the Ctrl + C example can be accomplished with the syntax:
import keyboard
keyboard.add_hotkey("ctrl + c", print, args=("Hello", "world!"))