i am using PyMouse(Event) for detecting if mouse button is pressed:
from pymouse import PyMouseEvent
class DetectMouseClick(PyMouseEvent):
def __init__(self):
PyMouseEvent.__init__(self)
def click(self, x, y, button, press):
if button == 1:
if press:
print("click")
else:
self.stop()
O = DetectMouseClick()
O.run()
This works so far, but now i want to loop print("click") until mouse isnt pressed anymore ... i tried:
def click(self, x, y, button, press):
if button == 1:
if press:
do = 1
while do == 1:
print("down")
if not press:
do = 0
And also smth. like:
while press:
print("click")
Someone can help me? Thanks!
I think as Oli points out in his comment there isn't a constant stream of clicks when the mouse button is held down so you'll have to have the print in a loop. Having the while loop running on the same thread prevents the click event firing when the mouse is released so the only way I can think of to achieve what you are after is to print("click") from a separate thread.
I'm not a Python programmer but I've had a stab which works on my machine (Python 2.7 on Windows 8.1):
from pymouse import PyMouseEvent
from threading import Thread
class DetectMouseClick(PyMouseEvent):
def __init__(self):
PyMouseEvent.__init__(self)
def print_message(self):
while self.do == 1:
print("click")
def click(self, x, y, button, press):
if button == 1:
if press:
print("click")
self.do = 1
self.thread = Thread(target = self.print_message)
self.thread.start()
else:
self.do = 0
print("end")
else:
self.do = 0
self.stop()
O = DetectMouseClick()
O.run()
Related
I can't figure out how to make auto clicks start when I press the left mouse button and stop when I release it. Maybe someone knows how to solve it?
Perhaps with the help of pynput it is not advisable to do this, but it is better to use pyautogui, or there are some other solutions.
# importing time and threading
import time
import threading
from pynput.mouse import Button, Controller
# pynput.keyboard is used to watch events of
# keyboard for start and stop of auto-clicker
from pynput.keyboard import Listener, KeyCode
# four variables are created to
# control the auto-clicker
delay = 0.277
button = Button.left
start_stop_key = KeyCode(char='+') #The left mouse button should be here
stop_key = KeyCode(char='-')
# threading.Thread is used
# to control clicks
class ClickMouse(threading.Thread):
# delay and button is passed in class
# to check execution of auto-clicker
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
# method to check and run loop until
# it is true another loop will check
# if it is set to true or not,
# for mouse click it set to button
# and delay.
def run(self):
while self.program_running:
while self.running:
mouse.click(self.button)
time.sleep(self.delay)
time.sleep(0.1)
# instance of mouse controller is created
mouse = Controller()
click_thread = ClickMouse(delay, button)
click_thread.start()
# on_press method takes
# key as argument
def on_press(key):
# start_stop_key will stop clicking
# if running flag is set to true
if key == start_stop_key:
if click_thread.running:
click_thread.stop_clicking()
print("click end")
else:
click_thread.start_clicking()
print("click start")
# here exit method is called and when
# key is pressed it terminates auto clicker
elif key == stop_key:
click_thread.exit()
listener.stop()
with Listener(on_press=on_press) as listener:
listener.join()
I searched for a solution but didn't understand anything.
I found a solution.
It turned out that using the left mouse button when it is pressed is not the best solution, but rather not working.
You need to use an unoccupied key, in my case it is the middle mouse key. I replaced the function on_press with the function on_click, which was presented in the pynput documentation, but thereby lost the functionality of completing the script on the key.
Here is the code:
# importing time and threading
import time
import threading
from pynput.mouse import Button, Controller
from pynput import mouse
delay = 0.277
button = Button.left
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:
muse.click(self.button)
time.sleep(self.delay)
time.sleep(0.1)
# instance of mouse controller is created
muse = Controller()
click_thread = ClickMouse(delay, button)
click_thread.start()
def on_click(x, y, button, pressed):
if button == button.middle:
if pressed:
click_thread.start_clicking()
print("click start")
elif not pressed:
click_thread.stop_clicking()
print("click end")
with mouse.Listener(on_click=on_click) as listener:
listener.join()
I'm using the code from this website, https://www.geeksforgeeks.org/how-to-make-a-python-auto-clicker/, and I feel like I have it setup correctly but I get some strange errors when I trigger the auto clicker. I'm modifying it to use a button on my mouse as the start and stop button instead of keys on my keyboard. I actually don't even need pynput.keyboard. My script runs but I get these errors when I press the button on my mouse:
Here's my code:
# importing time and threading
import time
import threading
# from pynput import mouse
from pynput.mouse import Listener, Button, Controller
# pynput.keyboard is used to watch events of
# keyboard for start and stop of auto-clicker
# from pynput.keyboard import KeyCode
# four variables are created to
# control the auto-clicker
delay = 0.001
button = Button.left
start_stop_key = Button.x2
stop_key = Button.x2
# threading.Thread is used
# to control clicks
class ClickMouse(threading.Thread):
# delay and button is passed in class
# to check execution of auto-clicker
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
# method to check and run loop until
# it is true another loop will check
# if it is set to true or not,
# for mouse click it set to button
# and delay.
def run(self):
while self.program_running:
while self.running:
mouse.click(self.button)
time.sleep(self.delay)
time.sleep(0.1)
# instance of mouse controller is created
mouse = Controller()
click_thread = ClickMouse(delay, button)
click_thread.start()
# on_click method takes
# key as argument
def on_click(key):
# start_stop_key will stop clicking
# if running flag is set to true
if key == start_stop_key:
if click_thread.running:
click_thread.stop_clicking()
else:
click_thread.start_clicking()
# here exit method is called and when
# key is pressed it terminates auto clicker
elif key == stop_key:
click_thread.exit()
listener.stop()
with Listener(on_click=on_click) as listener:
listener.join()
I'm just not sure what I am missing at this point. Any help would be greatly appreciated.
This autoclicker script I found automatically clicks the mouse when you press the "s" key. However, I want to change it so that the autoclicker will only run when the left mouse button is depressed. I have spent a surplus of 10 hours trying to figure this one out, but frankly, I'm terrible at coding. Any help would be great. (Also, there is no GetKeyState or GetASyncKeyState in any library I know of)
My code is:
import threading
from pynput.mouse import Button, Controller
from pynput.keyboard import Listener, KeyCode
delay = 0.01
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)
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()
you have to go to microsoft to get the Virtual-Key codes for input.
For left mouse buttons, the code is 0x01. for Right mouse buttons the code is 0x02.
You will also need to install pywin32 and import the win32 api
Then you can do something like this:
```while True:
a = win32api.GetKeyState(0x01)
print(a)
time.sleep(255.0) #this should be long enough
Basically, when this is run where there's no input pressed, the script will print 0 indefinitely. However when it is pressed, it will print a 1 for as long as it's pressed.
From there you can make that into an if/then statement and activate the clicking function.
I'm making a auto clicker which turns off and on with "e" but after
it turns on it doesn't turn off.
I've tried changing the code multiple times but still can't find out the
problem.
import pynput
from pynput.keyboard import KeyCode, Listener
from pynput.mouse import Button, Controller
import time
mouse = Controller()
def onoff(keycode, on=None):
rkey = str(keycode).strip("'")
if rkey == "e":
if not on:
print("on")
on = True
elif on:
print("off")
on = False
if not on:
print("not on")
elif on:
while on:
mouse.click(Button.left)
time.sleep(0.4)
with Listener(on_press=onoff) as l:
l.join()
I expected it to turn off after I press "e" but keeps clicking.
It's not very clear what you mean, because Listener in pynput is a new thread. If you need to stop this thread, the while True task in the thread will stop accordingly. All of them should be separated from each other. Use .join() method to turn off keyboard listen after second press "e" and keeps clicking, try the following code to see if you want the effect:
from pynput.keyboard import Listener
from pynput.mouse import Button, Controller
import time
import threading
mouse = Controller()
class Demo:
def __init__(self):
self.key_list = []
self.c = threading.Thread(target=self.click)
self.l = Listener(on_press=self.onoff)
self.l.start()
self.l.join()
def click(self):
while True:
mouse.click(Button.left)
time.sleep(0.4)
def onoff(self, key):
try:
key_str = key.char
except AttributeError:
key_str = key.name
if key_str == "e":
if len(self.key_list) == 0:
self.key_list.append(key_str)
self.c.start()
elif key_str in self.key_list:
self.l.stop()
print('Keyboard listen stopped')
print('Mouse click continue')
self.c.join()
Demo()
I want to have a simple GUI with 4 buttons. If you just click the button, function A should be executed, for short button press (e.g.1sec) function B should be executed and finally a long press (e.g. > 2s) function C should be executed.
Imagine a counter.
If you click the button, it will be reset to 0
If you short press the button, counter will be increased by 1 for e.g t=1sec
If you long press the button, counter will be increased by 10 until button is released.
Is somebody haveing an idea. I was trying this to accomplish it with a 2nd thread but I haven't found a possibility to stop the thread like you can start it
This is easy to do in PyQt if you use a widget which inherits QAbstractButton. No need for any timers or separate threads. Just use the built-in auto-repeat functionality, and keep a record of the current state.
Here's a simple demo:
from PyQt4 import QtGui, QtCore
class Button(QtGui.QPushButton):
def __init__(self, *args, **kwargs):
QtGui.QPushButton.__init__(self, *args, **kwargs)
self.setAutoRepeat(True)
self.setAutoRepeatDelay(1000)
self.setAutoRepeatInterval(1000)
self.clicked.connect(self.handleClicked)
self._state = 0
def handleClicked(self):
if self.isDown():
if self._state == 0:
self._state = 1
self.setAutoRepeatInterval(50)
print 'press'
else:
print 'repeat'
elif self._state == 1:
self._state = 0
self.setAutoRepeatInterval(1000)
print 'release'
else:
print 'click'
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
button = Button('Test Button')
button.show()
sys.exit(app.exec_())
in wxPython I would do it like this ... however you may need to adjust it for your GUI library ...
start_time = None
def onLeftDown(e):
global running
running = True
ct =0
while running:
ct += 1
do_something(ct)
def onLeftUp(e):
print "You Pressed For %s Seconds!"%(time.time()-start_time)
my_btn = wx.Button(parent,-1,"Click Me!")
my_btn.Bind(wx.EVT_LEFT_DOWN,onLeftDown)
my_btn.Bind(wx.EVT_LEFT_UP,onLeftUp)
Im not very familliar with QT but maybe you can modify this wx code to do what you want...
import wx
ct = 0
def counting():
global running
global ct
if running:
ct +=1
print ct
wx.CallLater(1,counting)
else:
print "OK DONE COUNTING AT:",ct
def onLeftDown(evt):
global running
running = True
counting()
def onLeftUp(evt):
print "STOP NOW!!"
global running
running = False
a = wx.App(redirect=False)
f = wx.Frame(None,-1,"asdasd")
b = wx.Button(f,-1,"Click Me")
b.Bind(wx.EVT_LEFT_DOWN,onLeftDown)
b.Bind(wx.EVT_LEFT_UP,onLeftUp)
f.Show()
a.MainLoop()