'How to change cursor in pygame?

I have a button in my pygame program.
Whenever my cursor is hovering over the button, I want the cursor to change to this:enter image description here

I already know how to get the position of the mouse and when it is pressed. I just need to know how to change the cursor.



Solution 1:[1]

In case you want to create and use your own colorfully customized cursor from an image (and display different cursors depending on where you are in the game, e.g. in the menu or "ingame").

Here is the procedure:

  • set mouse visibility to false
  • create a customized image you want to use as cursor
  • create a rect from that customized cursor image
  • update the rects position to your (invisible) mouse position
  • draw the image at the location of the rect

Here is a short code example:

pygame.mouse.set_visible(False)
cursor_img_rect = cursor_img.get_rect()

while True:
    # in your main loop update the position every frame and blit the image    
    cursor_img_rect.center = pygame.mouse.get_pos()  # update position 
    gameDisplay.blit(cursor, cursor_rect) # draw the cursor

Solution 2:[2]

You know: Pygame only supports black and white cursors for the system. You can load cursors in PyGame with pygame.cursors.load_xbm, Read the full article here, for more
If you wanna detect cursor hovering the item, which (100,100) to (200,200) is the item position, this is the code:

if event.type == pygame.MOUSEMOTION:
    x, y = event.pos
    if ( x in range(100,100)) and (y in range(200,200)):
        print("Hovering over the item!")
        new_cursor()
    else: default_cursor()

Solution 3:[3]

pygame.mouse.set_cursor()

Pygame Cursor Constant           Description
--------------------------------------------
pygame.SYSTEM_CURSOR_ARROW       arrow
pygame.SYSTEM_CURSOR_IBEAM       i-beam
pygame.SYSTEM_CURSOR_WAIT        wait
pygame.SYSTEM_CURSOR_CROSSHAIR   crosshair
pygame.SYSTEM_CURSOR_WAITARROW   small wait cursor
                                 (or wait if not available)
pygame.SYSTEM_CURSOR_SIZENWSE    double arrow pointing
                                 northwest and southeast
pygame.SYSTEM_CURSOR_SIZENESW    double arrow pointing
                                 northeast and southwest
pygame.SYSTEM_CURSOR_SIZEWE      double arrow pointing
                                 west and east
pygame.SYSTEM_CURSOR_SIZENS      double arrow pointing
                                 north and south
pygame.SYSTEM_CURSOR_SIZEALL     four pointed arrow pointing
                                 north, south, east, and west
pygame.SYSTEM_CURSOR_NO          slashed circle or crossbones
pygame.SYSTEM_CURSOR_HAND        hand

for example:
pygame.mouse.set_cursor(pygame.SYSTEM_CURSOR_HAND)

Solution 4:[4]

I recommend colliding the point into the rect that the "button" is in.(collidepoint function). Or alternatively use if x in range(button x range) and x in range (button y range).

Once you do collidepoint you can set cursor visibility to False and then draw an image/ rect/ circle at the coordinates of the cursor. It will create the change the cursor effect.

Use pygame.org. It is a helpful site for pygame.

I'll show you my code for this to help you out:

# --- Libraries --- #

# Import pygame
import pygame

# INITialize pygame


pygame.init() 
# --- Window & Cursor --- #

# Open a WINDOW of size [500, 300]
window=pygame.display.set_mode([500,300]) 

# SET_VISIBLE of cursor to False
pygame.mouse.set_visible(False) 
# Set the variable cursor_size to 10
cursor_size=10


#### ---- MAIN LOOP ---- ####
running=True 
# Create a variable called running with value True
while running: 

# Loop while running



    # --- Event Loop --- #

    # Create an EVENT LOOP
    for event in pygame.event.get(): 

        # Check for the QUIT event
        if event.type==pygame.QUIT: 
            running=False 

            # Set running to False
            # ---> TEST AFTER THIS LINE <--- #



        # --- The cursor increases size while clicking --- #

        # Check if the event TYPE is MOUSEBUTTONDOWN

        if event.type==pygame.MOUSEBUTTONDOWN: 
            cursor_size=20
            # Set cursor_size to 20
            # ---> TEST AFTER THIS LINE <--- #


        # Otherwise if the event TYPE is MOUSEBUTTONUP
        elif event.type==pygame.MOUSEBUTTONUP: 
            cursor_size=10
        
 


    # GET_POSition of mouse and store it in x, y
    x,y=pygame.mouse.get_pos() 
    # ---> TEST AFTER THIS LINE <--- #



    # --- Draw --- #

    # FILL the window with WHITE
    window.fill((215,158,222)) 


    # Draw a CIRCLE of any COLOR at position (x, y)
    # with cursor_size
    pygame.draw.circle(window,(255,255,255),(x,y),cursor_size,10) 


    # FLIP the display
    pygame.display.flip() 
    # ---> TEST AFTER THIS LINE <--- #




# Turn in your Coding Exercise.

Solution 5:[5]

One thing about blitting a custom cursor to the screen of every frame is that its position will be affected by the frame rate however small that delay is. So the exact x y coordinates of the mouse click might not line up exactly with the drawn image. If all you want is the hand cursor another option might be to add this line

pygame.mouse.set_cursor(pygame.cursors.Cursor(pygame.SYSTEM_CURSOR_HAND))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Peyman Majidi
Solution 3 Ninja Adober Gab
Solution 4
Solution 5 Gavriel Cohen