Simulate Mouse Events In Python
This demonstrates how to control the mouse with Python. Using pynput we are able to simulate mouse events into any window. This will show you how to press buttons, scroll and move the mouse.
- PIP
- Installing Pynput
- Simulating Mouse Events
- Finding the Position of the Mouse
- Setting the Position of the Mouse
- Moving the Mouse Relative to Its Position
- Clicking Buttons on the Mouse
- Pressing and Releasing Buttons
- Scrolling
- How can I use the keyboard and mouse controllers at the same time?
- How can I simulate buttons other than right and left?
- ModuleNotFoundError/ImportError: No module named ‘pynput’
- I got a SyntaxError
If you haven’t used or setup pip before, go to my tutorial at how-to-setup-pythons-pip to setup pip.
We will be using the pynput module to listen to mouse events. To install this module execute pip install pynput in cmd. Watch the output to make sure no errors have occurred; it will tell you when the module has been successfully installed.
To double-check that it was installed successfully, open up IDLE and execute the command import pynput ; no errors should occur.
Create a new script and save it somewhere so you can easily run the script. Import Button and Controller from pynput.mouse .
from pynput.mouse import Button, Controller
Make a variable called mouse and set it to an instance of Controller . Now using the mouse variable we can control the mouse.
Finding the Position of the Mouse
To find the position of the mouse we can use mouse.position . This will return a tuple of two integers. The first integer is the x position and the second integer is the y position. This is relative to the top left of the screen; x getting bigger is going right and y getting bigger is going down.
print ("Current position: " + str(mouse.position))
Setting the Position of the Mouse
To set the position of the mouse we can use mouse.position again. By setting this to an x and y point, the mouse position will be updated immediately.
Moving the Mouse Relative to Its Position
Instead of getting the mouses position and calculating where it needs to be moved to, if you want to move it a distance relative to the current position, we can use mouse.move . Passing an x and y integers to this will move the mouse relative to its current position. For example, if I wanted to move it to the right by 20 pixels and up by 13 pixels, I would use:
Clicking Buttons on the Mouse
To click buttons on the mouse, we would use mouse.click . Passing a button from the Button class imported and an integer, we can perform single, double and triple clicks for any button.
# Click the left button mouse.click(Button.left, 1) # Click the right button mouse.click(Button.right, 1) # Click the middle button mouse.click(Button.middle, 1) # Double click the left button mouse.click(Button.left, 2) # Click the left button ten times mouse.click(Button.left, 10)
Pressing and Releasing Buttons
We can also click a button using press and release methods. This would also allow us to drag an object by pressing, moving and then releasing. To press we would use the mouse.press method and to release we would use the mouse.release method. Both these methods need a button passed which can include the left, middle and right as shown above. More buttons can also be included depending on what operating system is being used.
mouse.press(Button.left) mouse.release(Button.left)
To scroll we need to use the mouse.scroll passing two integers for horizontal and vertical scroll. The first integer is for horizontal which is left to right scroll; a positive integer will scroll right vice versa. The second integer is for vertical which is up to down scroll; a positive integer will scroll up vice versa.
# Scroll up two steps mouse.scroll(0, 2) # Scroll right five steps mouse.scroll(5, 0)
Depending on your mouse settings, you may need to use bigger step values to see movement in the scroll. I have witnessed this myself and sometimes may need to use around 100 steps to move my mouse.
Common Issues and Questions
How can I use the keyboard and mouse controllers at the same time?
When you import the classes, Controller will be set to the last one imported. To show what the issue was, ask yourself, what controller did you use to set the mouse and what one to set the keyboard? You would have used the same, but they need to be from the different classes. So then you should use:
from pynput.keyboard import Key, Controller as KeyboardController from pynput.mouse import Button, Controller as MouseController
Now when you want to use the controller for the mouse use MouseController and KeyboardController for the keyboard.
keyboard = KeyboardController() mouse = MouseController()
How can I simulate buttons other than right and left?
To simulate the other buttons on your mouse, you first need to identify them. An easy way to do this would be to write a quick script to identify the buttons when you press them:
from pynput.mouse import Listener def on_click(x, y, button, pressed): if pressed: print('Pressed '.format(button)) with Listener(on_click=on_click) as listener: listener.join()
This script creates a mouse listener and prints out the name of any button you press. To use this, run the script and press the target button on your mouse. You should see some output like this:
Pressed Button.left Pressed Button.x1 Pressed Button.x2
In this output above, you can see that I pressed the left button on my mouse and then two other buttons on my mouse (my forward and back buttons). Using the buttons you have now identified, you can use them, for example, mouse.click(Button.x1) .
ModuleNotFoundError/ImportError: No module named ‘pynput’
Did you install pynput? This error will not occur if you installed it properly. If you have multiple versions of Python, make sure you are installing pynput on the same version as what you are running the script with.
Syntax errors are caused by you and there is nothing I can offer to fix it apart from telling you to read the error. They always say where the error is in the output using a ^. Generally, people that get this issue have incorrect indentation, brackets in the wrong place or something spelt wrong. You can read about SyntaxError on Python’s docs here.
Owner of PyTutorials and creator of auto-py-to-exe. I enjoy making quick tutorials for people new to particular topics in Python and tools that help fix small things.
How To Get Mouse Clicks With Python
This demonstration shows you how to track mouse clicks, movements and even scrolls using the pynput module. These can then be logged to a file as no console is displayed. This is very similar to a mouse logger.
If you haven’t used or setup pip before, go to my tutorial at how-to-setup-pythons-pip to setup pip.
We will be using the pynput module to listen to mouse events. To install this module execute pip install pynput in cmd. Watch the output to make sure no errors have occurred; it will tell you when the module has been successfully installed.
To double-check that it was installed successfully, open up IDLE and execute the command import pynput ; no errors should occur.
Create a new python file and save it with a .py file extension. You will first want to import Listener from pynput.mouse.
from pynput.mouse import Listener
Setup the listener by creating an instance in a with statement and using it’s .join() method to join it to the main thread.
with Listener() as listener: listener.join()
Create three methods; on_move, on_click and on_scroll with the parameters as shown below.
def on_move(x, y): pass def on_click(x, y, button, pressed): pass def on_scroll(x, y, dx, dy): pass
Link these methods to the listener instance with the function names as the args; I have named the methods as they are defined in the listener class. Now when an action occurs, one of these methods will be run.
with Listener(on_move=on_move, on_click=on_click, on_scroll=on_scroll) as listener:
To make sure these are running, add some print statements to each method. Save and run the script. Move your mouse around a bit, you should see output like below.
def on_move(x, y): print ("Mouse moved") def on_click(x, y, button, pressed): print ("Mouse clicked") def on_scroll(x, y, dx, dy): print ("Mouse scrolled")
Using these print statements and the parameters provided, we can give more information when printing. Run this again to make sure it is working properly (example output below).
def on_move(x, y): print ("Mouse moved to ( , )".format(x, y)) def on_click(x, y, button, pressed): if pressed: print ('Mouse clicked at ( , ) with '.format(x, y, button)) def on_scroll(x, y, dx, dy): print ('Mouse scrolled at ( , )( , )'.format(x, y, dx, dy))
If you want this script to be run in the background. Click File -> Save As and save it with a .pyw file extension. Now when it is run outside IDLE there will be no console window and it will not look like it is running. But to make sure the console doesn’t appear, we need to first remove the print statements.
Import logging and setup the basic configuration as I have below. After that, change all print statements to logging.info.
logging.basicConfig(filename="mouse_log.txt", level=logging.DEBUG, format='%(asctime)s: %(message)s')
def on_move(x, y): logging.info("Mouse moved to ( , )".format(x, y)) def on_click(x, y, button, pressed): if pressed: logging.info('Mouse clicked at ( , ) with '.format(x, y, button)) def on_scroll(x, y, dx, dy): logging.info('Mouse scrolled at ( , )( , )'.format(x, y, dx, dy))
Now when the script is run, nothing should be printed to the console. This is because it is all being saved to the file declared in the basic configuration.
Save and close IDLE. Open the file named mouse_log.txt next to your python script; all the events should be logged in here.
The actual location of this file will be in the current working directory of where you run the script from
Just as a quick note, the Listener class is a thread which means as soon as it has joined to the main thread no code will be executed after the .join() until the Listener is stopped.
As stated here in the pynput docs on readthedocs.io, we can call pynput.mouse.Listener.stop anywhere in the script to stop the thread or return False from a callback to stop the listener. As shown in my video, we can also just call listener.stop() in one of the definitions due to the fact that that the listener is now in scope and is an instance os Listener.
from pynput.mouse import Listener import logging logging.basicConfig(filename="mouse_log.txt", level=logging.DEBUG, format='%(asctime)s: %(message)s') def on_move(x, y): logging.info("Mouse moved to ( , )".format(x, y)) def on_click(x, y, button, pressed): if pressed: logging.info('Mouse clicked at ( , ) with '.format(x, y, button)) def on_scroll(x, y, dx, dy): logging.info('Mouse scrolled at ( , )( , )'.format(x, y, dx, dy)) with Listener(on_move=on_move, on_click=on_click, on_scroll=on_scroll) as listener: listener.join()
Common Issues and Questions
ModuleNotFoundError/ImportError: No module named ‘pynput’
Did you install pynput? This error will not occur if you installed it properly. If you have multiple versions of Python, make sure you are installing pynput on the same version as what you are running the script with.
Syntax errors are caused by you and there is not much I can offer to fix it apart from telling you to read the error. They always say where the error is in the output using a ^. Generally people that get this issue have incorrect indentation, brackets in the wrong place or something spelt wrong. You can read about SyntaxError on Python’s docs here.
Owner of PyTutorials and creator of auto-py-to-exe. I enjoy making quick tutorials for people new to particular topics in Python and tools that help fix small things.