Read the mouse in pygame: MOUSEBUTTONDOWN and MOUSEBUTTONUP events for clicks, pygame.mouse.get_pos() and get_pressed() for its state, clickable buttons with collidepoint, and dragging objects.
▶This page includes runnable editors. Edit, run, and see output instantly.
The mouse, like the keyboard, comes as events (a button went down) and as state (where the pointer is now). This program draws a dot where you click and a ring that follows the pointer:
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 320))
clock = pygame.time.Clock()
dots = []
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
dots.append(event.pos)
elif event.button == 3:
dots.clear()
screen.fill((250, 248, 240))
for pos in dots:
pygame.draw.circle(screen, (230, 80, 90), pos, 10)
pygame.draw.circle(screen, (60, 60, 80), pygame.mouse.get_pos(), 16, width=2)
pygame.display.flip()
clock.tick(60)
pygame.quit()
Press Play and click in the game. A right click clears the dots.
Mouse events
Event
Attributes
MOUSEBUTTONDOWN
pos (x, y), button
MOUSEBUTTONUP
pos, button
MOUSEMOTION
pos, rel (movement since the last event), buttons (which are held)
MOUSEWHEEL
x, y (wheel steps; y is positive when scrolling up)
event.button is 1 for left, 2 for middle and 3 for right.
Mouse state
Function
Returns
pygame.mouse.get_pos()
The pointer's (x, y)
pygame.mouse.get_pressed()
Three booleans: left, middle, right held now
pygame.mouse.get_rel()
Movement since the last call
pygame.mouse.set_visible(False)
Hides the system pointer (draw your own crosshair)
A clickable button
A button is a Rect plus a check: is the click inside it? Rect.collidepoint answers that.
The button lights up under the pointer and counts clicks. Menus, inventory slots and level select screens are built the same way.
Dragging
Dragging uses all three events: pick up on MOUSEBUTTONDOWN if the click is on the object, move on MOUSEMOTION by event.rel, drop on MOUSEBUTTONUP.
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 320))
clock = pygame.time.Clock()
boxes = [pygame.Rect(60 + i * 130, 130, 70, 70) for i in range(3)]
colors = [(240, 100, 100), (100, 200, 120), (100, 150, 240)]
held = None
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
for i, box in enumerate(boxes):
if box.collidepoint(event.pos):
held = i
elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:
held = None
elif event.type == pygame.MOUSEMOTION and held is not None:
boxes[held].move_ip(event.rel)
screen.fill((245, 242, 235))
for box, color in zip(boxes, colors):
pygame.draw.rect(screen, color, box, border_radius=10)
pygame.display.flip()
clock.tick(60)
pygame.quit()
Drag the boxes around. For one finger on a touch screen, pygame turns taps into mouse events too, so the same code works there.
Frequently Asked Questions
How do I get the mouse position in pygame?
x, y = pygame.mouse.get_pos() returns the pointer's position in the window, in pixels from the top-left corner. Click events also carry it as event.pos.
How do I detect a mouse click?
Check for event.type == pygame.MOUSEBUTTONDOWN in the event loop. event.button is 1 for the left button, 2 for the middle and 3 for the right.
How do I make a clickable button in pygame?
Keep a Rect for the button, and on MOUSEBUTTONDOWN check button_rect.collidepoint(event.pos). Draw the button with a different color when collidepoint(pygame.mouse.get_pos()) is true for a hover effect.