Hover Behaviors¶
morphui.uix.behaviors.hover
¶
Hover behaviors for Kivy widgets.
This module provides two hover behaviors:
- MorphHoverBehavior: Basic hover detection (enter/leave events)
- MorphHoverEnhancedBehavior: Advanced hover with edge/corner detection
Choose the appropriate behavior based on your needs: - Use MorphHoverBehavior for simple hover effects - Use MorphHoverEnhancedBehavior for complex position-aware interactions
MorphHoverBehavior(**kwargs)
¶
Bases: EventDispatcher
Basic hover behavior that detects mouse enter and leave events.
This is a lightweight behavior that provides core hover functionality without the overhead of edge and corner detection. Use this when you only need basic hover states for simple effects like color changes, cursor updates, or simple animations.
Events
- :meth:
on_enter: Fired when mouse enters the widget - :meth:
on_leave: Fired when mouse leaves the widget
Properties
- :attr:
hover_enabled: Enable/disable hover detection - :attr:
hovered: Current hover state - :attr:
enter_pos: Position where mouse entered (widget coords) - :attr:
leave_pos: Position where mouse left (widget coords) - :attr:
current_pos: Current mouse position (widget coords)
Examples:
Simple hover color change:
from kivy.uix.label import Label
from morphui.uix.behaviors.hover import MorphHoverBehavior
class HoverLabel(MorphHoverBehavior, Label):
def on_enter(self):
self.color = (1, 0, 0, 1) # Red on hover
def on_leave(self):
self.color = (1, 1, 1, 1) # White when not hovering
Hover with position tracking:
class PositionTracker(MorphHoverBehavior, Widget):
def on_enter(self):
print(f"Mouse entered at: {self.enter_pos}")
def on_leave(self):
print(f"Mouse left at: {self.leave_pos}")
hover_enabled = BooleanProperty(True)
class-attribute
instance-attribute
¶
Enable or disable hover behavior and event detection.
When set to False, the behavior will not track mouse position or fire hover events, effectively disabling all hover functionality. This is useful for temporarily disabling hover effects without removing the behavior from the widget.
Setting this to False will also clear any current hover state and stop all hover-related event dispatching until re-enabled.
:attr:hover_enabled is a :class:~kivy.properties.BooleanProperty
and defaults to True.
Examples:
hovered = BooleanProperty(False)
class-attribute
instance-attribute
¶
Indicates whether the mouse is currently over the widget.
This property is automatically updated based on mouse position and widget bounds. You can bind to this property to react to hover state changes.
:attr:hovered is a :class:~kivy.properties.BooleanProperty
and defaults to False.
is_displayed
property
¶
Check if widget is displayed (has root window).
on_mouse_pos(instance, pos)
¶
Handle mouse position changes from Window.
This method is automatically called whenever the mouse moves. It updates hover state and position tracking based on collision detection with the widget bounds.
| PARAMETER | DESCRIPTION |
|---|---|
instance
|
The Window instance (unused)
TYPE:
|
pos
|
Mouse position in window coordinates
TYPE:
|
on_enter()
¶
Event fired when mouse enters the widget.
Override this method in subclasses to add custom hover
behavior. The mouse position where the widget was entered
is available in :attr:enter_pos.
on_leave()
¶
Event fired when mouse leaves the widget.
Override this method in subclasses to add custom hover
behavior. The mouse position where the widget was left
is available in :attr:leave_pos.
MorphHoverEnhancedBehavior(**kwargs)
¶
Bases: MorphHoverBehavior
Enhanced hover behavior with edge and corner detection.
This behavior extends the base hover functionality with detailed edge and corner detection. It's ideal for widgets that need to respond differently based on where the mouse is positioned within the widget bounds.
Additional Events (beyond base hover)
- :meth:
on_enter_edge: Fired when mouse enters any edge - :meth:
on_leave_edge: Fired when mouse leaves any edge - :meth:
on_enter_corner: Fired when mouse enters any corner - :meth:
on_leave_corner: Fired when mouse leaves any corner
Additional Properties
- :attr:
hovered_edges: List of currently hovered edges - :attr:
hovered_corner: Currently hovered corner - :attr:
edge_detection_size: Size of edge detection area in pixels - Individual edge properties: left_edge_hovered, right_edge_hovered, etc.
Common Use Cases
- Resizable widgets with visual resize handles
- Tooltips that change based on widget area
- Cursor changes for different widget regions
- Complex hover animations based on position
Examples:
Resizable widget with visual feedback:
from kivy.uix.widget import Widget
from kivy.core.window import Window
from morphui.uix.behaviors.hover import MorphHoverEnhancedBehavior
class ResizableWidget(MorphHoverEnhancedBehavior, Widget):
def on_enter_edge(self, edge):
if edge in ['left', 'right']:
Window.set_system_cursor('size_we') # Horizontal resize
else:
Window.set_system_cursor('size_ns') # Vertical resize
def on_enter_corner(self, corner):
if corner in ['top-left', 'bottom-right']:
Window.set_system_cursor('size_nwse')
else:
Window.set_system_cursor('size_nesw')
def on_leave(self):
Window.set_system_cursor('arrow') # Reset cursor
Dynamic tooltips:
class SmartTooltip(MorphHoverEnhancedBehavior, Widget):
def on_enter_edge(self, edge):
self.show_tooltip(f"Drag {edge} edge to resize")
def on_enter_corner(self, corner):
self.show_tooltip(f"Drag {corner} corner to resize diagonally")
def on_enter(self):
if not self.hovered_edges:
self.show_tooltip("Click to select widget")
hovered_edges = ListProperty([])
class-attribute
instance-attribute
¶
List of edges currently being hovered over.
Contains edge names from ['left', 'right', 'top', 'bottom'] that are currently under the mouse cursor. Updated automatically based on mouse position and edge_detection_size.
:attr:hovered_edges is a :class:~kivy.properties.ListProperty
and defaults to an empty list.
hovered_corner = StringProperty(None, options=(NAME.CORNERS), allownone=True)
class-attribute
instance-attribute
¶
The corner currently being hovered over.
Automatically determined from hovered_edges when exactly two adjacent edges are hovered. Possible values are corner names or None.
:attr:hovered_corner is a :class:~kivy.properties.StringProperty
and defaults to None.
left_edge_hovered = BooleanProperty(False)
class-attribute
instance-attribute
¶
Whether the left edge is currently hovered.
:attr:left_edge_hovered is a :class:~kivy.properties.BooleanProperty
and defaults to False.
right_edge_hovered = BooleanProperty(False)
class-attribute
instance-attribute
¶
Whether the right edge is currently hovered.
:attr:right_edge_hovered is a :class:~kivy.properties.BooleanProperty
and defaults to False.
top_edge_hovered = BooleanProperty(False)
class-attribute
instance-attribute
¶
Whether the top edge is currently hovered.
:attr:top_edge_hovered is a :class:~kivy.properties.BooleanProperty
and defaults to False.
bottom_edge_hovered = BooleanProperty(False)
class-attribute
instance-attribute
¶
Whether the bottom edge is currently hovered.
:attr:bottom_edge_hovered is a :class:~kivy.properties.BooleanProperty
and defaults to False.
edge_detection_size = NumericProperty(dp(4))
class-attribute
instance-attribute
¶
Size of the edge area for detection in pixels.
Determines how many pixels from the widget edge count as "edge area" for hover detection. Larger values make edges easier to target but reduce the center area.
:attr:edge_detection_size is a :class:~kivy.properties.NumericProperty
and defaults to 4.
get_hovered_corner()
¶
Determine corner from currently hovered edges.
| RETURNS | DESCRIPTION |
|---|---|
str | None
|
Corner name if exactly two adjacent edges are hovered, None otherwise. |
get_hovered_edges()
¶
Get list of currently hovered edges.
| RETURNS | DESCRIPTION |
|---|---|
List[str]
|
List of edge names that are currently hovered. |
on_mouse_pos(instance, pos)
¶
Enhanced mouse position handling with edge detection.
Extends the base behavior to also calculate edge and corner hover states based on mouse position within the widget.
| PARAMETER | DESCRIPTION |
|---|---|
instance
|
The Window instance
TYPE:
|
pos
|
Mouse position in window coordinates
TYPE:
|
on_left_edge_hovered(instance, hovered)
¶
Handle left edge hover state changes.
on_right_edge_hovered(instance, hovered)
¶
Handle right edge hover state changes.
on_top_edge_hovered(instance, hovered)
¶
Handle top edge hover state changes.
on_bottom_edge_hovered(instance, hovered)
¶
Handle bottom edge hover state changes.
on_hovered_corner(instance, corner)
¶
Handle corner hover state changes.
Dispatches enter/leave corner events when the corner changes.
| PARAMETER | DESCRIPTION |
|---|---|
instance
|
The widget instance
TYPE:
|
corner
|
New corner value
TYPE:
|
on_enter_edge(edge)
¶
Event fired when mouse enters any edge.
The edge names are 'left', 'right', 'top', and 'bottom'. This
event is triggered whenever the mouse cursor moves into the edge
area defined by the edge_detection_size property. You can override this
method in subclasses to implement custom behavior when an edge
is entered.
| PARAMETER | DESCRIPTION |
|---|---|
edge
|
The edge being entered
TYPE:
|
Examples:
on_leave_edge(edge)
¶
Event fired when mouse leaves any edge.
The edge names are 'left', 'right', 'top', and 'bottom'. This
event is triggered whenever the mouse cursor moves out of the
edge area defined by the edge_detection_size property. You can override
this method in subclasses to implement custom behavior when an
edge is left.
| PARAMETER | DESCRIPTION |
|---|---|
edge
|
The edge being left
TYPE:
|
on_enter_corner(corner)
¶
Event fired when mouse enters any corner.
The corner names are 'top-left', 'top-right', 'bottom-left', and 'bottom-right'. This event is triggered whenever the mouse cursor moves into a corner area defined by the intersection of two adjacent edges. You can override this method in subclasses to implement custom behavior when a corner is entered.
| PARAMETER | DESCRIPTION |
|---|---|
corner
|
The corner being entered
TYPE:
|
Examples:
on_leave_corner(corner)
¶
Event fired when mouse leaves any corner.
The corner names are 'top-left', 'top-right', 'bottom-left', and 'bottom-right'. This event is triggered whenever the mouse cursor moves out of a corner area defined by the intersection of two adjacent edges. You can override this method in subclasses to implement custom behavior when a corner is left.
| PARAMETER | DESCRIPTION |
|---|---|
corner
|
The corner being left
TYPE:
|