Have you ever wondered if you could make your computer do things just by writing a few lines of code? Well, one of the coolest tricks you can teach your computer is to control the mouse cursor automatically. Today, we’re going to do just that!
In this tutorial, You’ll learn how to control your mouse in Python, we’ll dive into writing a Python script that not only moves the cursor across your screen but also uses it to draw letters! We’ll be using two essential Python libraries to help us with this task: pynput and screeninfo. These tools will give us the power to manipulate our mouse cursor with precision.
Let’s get started!
Table of Contents
Necessary Libraries
For this code to run correctly, you must install these libraries via your terminal or command prompt:
$ pip install pynput
$ pip install screeninfo
Imports
As usual, we begin by importing the libraries and modules necessary for this code to function:
- Our first import is the
time
library, which we use to add delays and slow down mouse movement through its various time-related functions. - Secondly, we import the
Controller
andButton
from thepynput.mouse
module, which allow us to control the mouse cursor and handle mouse button actions. - Finally, our third import is the
get_monitors
function from thescreeninfo
library, which provides us with detailed information about the screen dimensions and settings.
import time
from pynput.mouse import Controller, Button
from screeninfo import get_monitors
Initializing Mouse Controller
After importing the required libraries, our first step is to create an instance of the Controller class from the pynput.mouse
library so we can control the mouse cursor.
mouse = Controller()
Defining Functions
Now, let’s define our functions:
get_screen_center Function
The objective of this function is to calculate the center coordinates of the primary monitor. It starts by using the get_monitors
function to access the first monitor in the list. Then, it calculates center_x
by taking the width of the monitor and dividing it by 2 using integer division.
Similarly, it calculates center_y
by dividing the height of the monitor by 2, also using integer division. Finally, it returns both center_x
and center_y
, giving the center coordinates of the monitor.
def get_screen_center():
monitor = get_monitors()[0]
center_x = monitor.width // 2
center_y = monitor.height // 2
return center_x, center_y
move_to_position Function
This function’s job is to move the cursor to a specific position on the screen. It takes three parameters: x
and y
, which are the horizontal and vertical coordinates to which we want the cursor to move, and absolute
, an optional parameter.
When absolute
is set to True
(the default), it moves the cursor to the position (x
, y
), making the movement absolute. Otherwise, when it is set to False
, the cursor moves relatively to its current position by adding x
and y
pixels to the initial position, resulting in a new position (new_x + x
, new_y + y
).
def move_to_position(x, y, absolute=True):
if absolute:
mouse.position = (x, y)
else:
new_x, new_y = mouse.position
mouse.position = (new_x + x, new_y + y)
draw_letter Function
Basically, this function takes coordinates x
and y
, which represent the vertices, and moves the cursor relatively (since absolute
is set to False
) using move_to_position(x, y, False)
. It begins by pressing the left mouse button to start drawing. As it moves from one position to another, it incorporates a time delay of 0.2 seconds with time.sleep(0.2)
for better visibility of the cursor movement.
After completing the drawing of a letter, the mouse button is released, and there is a further time delay of 1 second with time.sleep(1)
, allowing each letter to be drawn clearly and aesthetically.
def draw_letter(vertices):
mouse.press(Button.left) # Press the left mouse button
for x, y in vertices:
move_to_position(x, y, False)
time.sleep(0.2) # Delay for visibility
mouse.release(Button.left) # Release the left mouse button
time.sleep(1) # Pause between letters
Drawing Letters
Here, we define a set of functions that provide vertices (coordinates), and then call the draw_letter()
function to move the cursor according to these vertices, thus drawing letters.
def draw_p():
vertices = [(0, -100), (50, 0), (0, 50), (-50, 0), (0, 150)]
draw_letter(vertices)
def draw_y():
vertices = [(-50, -100), (50, 100), (0, 0), (50, -100)]
draw_letter(vertices)
def draw_c():
vertices = [(50, 0), (0, -100), (-100, 0), (0, 100)]
draw_letter(vertices)
def draw_o():
vertices = [(0, -100), (50, 0), (0, 100), (-50, 0)]
draw_letter(vertices)
def draw_d():
vertices = [(0, -100), (50, 0), (0, 100), (-50, 0)]
draw_letter(vertices)
def draw_e():
vertices = [(0, -100), (100, 0), (0, 100), (-100, 0), (0, -50), (50, 0)]
draw_letter(vertices)
def draw_s():
vertices = [(0, -50), (50, 0), (0, -50), (-50, 0), (0, -50), (50, 0)]
draw_letter(vertices)
draw_word_pycodes Function
This one begins by calling the get_screen_center()
function to retrieve the center_x
and center_y
coordinates. It then uses these coordinates to calculate the initial cursor position (initial_x
and initial_y
) when running the script.
Subsequently, it calls the move_to_position()
function to move the cursor to this position in an absolute movement (since absolute
is set to default). After positioning the cursor, it starts calling functions to draw letters, moving the cursor relatively between each letter until all letters are drawn.
def draw_word_pycodes():
center_x, center_y = get_screen_center()
initial_x = center_x - 300 # Adjust starting position to fit larger letters
initial_y = center_y - 200
move_to_position(initial_x, initial_y) # Start position adjustment for the whole word
draw_p()
move_to_position(100, 0, False) # Relative move to the next letter start
draw_y()
move_to_position(100, 0, False)
draw_c()
move_to_position(100, 0, False)
draw_o()
move_to_position(100, 0, False)
draw_d()
move_to_position(100, 0, False)
draw_e()
move_to_position(100, 0, False)
draw_s()
Main Function
For this step, we start by defining the main function that triggers the draw_word_pycodes()
function. Then, we include a conditional statement that ensures this function can only be executed directly, not when imported as a module.
def main():
draw_word_pycodes()
if __name__ == "__main__":
main()
Full Code
import time
from pynput.mouse import Controller, Button
from screeninfo import get_monitors
mouse = Controller()
def get_screen_center():
monitor = get_monitors()[0]
center_x = monitor.width // 2
center_y = monitor.height // 2
return center_x, center_y
def move_to_position(x, y, absolute=True):
if absolute:
mouse.position = (x, y)
else:
new_x, new_y = mouse.position
mouse.position = (new_x + x, new_y + y)
def draw_letter(vertices):
mouse.press(Button.left) # Press the left mouse button
for x, y in vertices:
move_to_position(x, y, False)
time.sleep(0.2) # Delay for visibility
mouse.release(Button.left) # Release the left mouse button
time.sleep(1) # Pause between letters
def draw_p():
vertices = [(0, -100), (50, 0), (0, 50), (-50, 0), (0, 150)]
draw_letter(vertices)
def draw_y():
vertices = [(-50, -100), (50, 100), (0, 0), (50, -100)]
draw_letter(vertices)
def draw_c():
vertices = [(50, 0), (0, -100), (-100, 0), (0, 100)]
draw_letter(vertices)
def draw_o():
vertices = [(0, -100), (50, 0), (0, 100), (-50, 0)]
draw_letter(vertices)
def draw_d():
vertices = [(0, -100), (50, 0), (0, 100), (-50, 0)]
draw_letter(vertices)
def draw_e():
vertices = [(0, -100), (100, 0), (0, 100), (-100, 0), (0, -50), (50, 0)]
draw_letter(vertices)
def draw_s():
vertices = [(0, -50), (50, 0), (0, -50), (-50, 0), (0, -50), (50, 0)]
draw_letter(vertices)
def draw_word_pycodes():
center_x, center_y = get_screen_center()
initial_x = center_x - 300 # Adjust starting position to fit larger letters
initial_y = center_y - 200
move_to_position(initial_x, initial_y) # Start position adjustment for the whole word
draw_p()
move_to_position(100, 0, False) # Relative move to the next letter start
draw_y()
move_to_position(100, 0, False)
draw_c()
move_to_position(100, 0, False)
draw_o()
move_to_position(100, 0, False)
draw_d()
move_to_position(100, 0, False)
draw_e()
move_to_position(100, 0, False)
draw_s()
def main():
draw_word_pycodes()
if __name__ == "__main__":
main()
Happy Coding!
Explore our tutorials on the Python Standard Library here.