Title: Make a button sprite that changes color when the mouse is over it in Python and Pygame
This example extends the post Make a button sprite in Python and Pygame. See that post for information about making the basic button.
The first version of the ButtonSprite already has an is_at method that returns True if a specific point is above the button. This example uses that method to make the button change colors when the mouse is over it.
Unfortunately, this requires a tiny change to the main program in addition to changes to the ButtonSprite class.
Main Program
The main app class now adds the following statement in its event loop.
elif event.type == MOUSEMOTION:
self.mouse_moved(event)
If the program detects mouse movement, it calls the following mouse_moved event handler.
def mouse_moved(self, event):
'''See if we are over a button.'''
for sprite in self.all_sprites:
sprite.mouse_moved(event)
This code simply loops thorough the program's sprites (which are all buttons in this example) and calls their mouse_moved event handlers. That code is in the ...
Button Sprite
Here's the ButtonSprite class's mouse_moved event handler.
def mouse_moved(self, event):
'''Highlight or unhighlight as appropriate.'''
self.is_highlighted = self.is_at(event.pos)
This code just sets the button's is_highlighted property to True if the mouse is over the button. Then the following draw method uses that value to decide how to draw the button. (I've highlighted the new pieces of code in blue.)
def draw(self, surface):
'''Draw the button.'''
# If we should be highlighted, switch fg_color and bg_color.
if self.is_highlighted:
fg_color = self.highlight_fg_color
bg_color = self.highlight_bg_color
else:
fg_color = self.fg_color
bg_color = self.bg_color
# Fill the rectangle
if bg_color is not None:
pygame.draw.rect(surface, bg_color, self.rect,
border_radius=self.radius)
# Outline the rectangle
if self.border_width > 0:
pygame.draw.rect(surface, fg_color, self.rect,
width=self.border_width,
border_radius=self.radius)
# Draw the text.
draw_text(surface, self.text, self.position, self.alignment,
self.font, fg_color, self.antialias)
This method first checks the is_highlighted value to see if the mouse is over the button. If so, the code switches the roles of the foreground and background colors.
The code then draws the button as before, possibly with the colors switched.
Conclusion
Making the button show when the mouse is over it is pretty easy. The code just sets the is_highlighted value and then the draw method draws the button accordingly.
A more elaborate button could provide additional feedback. For example, the button could change colors in some other way when the mouse is pressed on it, revert to the highlighted state if you press the mouse down over the button but then drag it off, and so forth. You could also animate the button to make it jiggle or change size when it's highlighted.
All of that makes things more complicated, however, so I'm not going to bother. Feel free to download the example to experiment with it and add those sorts of enhancements.
|