GUI Experimental Features

class arcade.gui.experimental.Animation(*, duration: float = 0.3, ease: EasingFunction = <function Easing.LINEAR>, delay: float = 0.0, repeat: int | bool = 0, yoyo: bool = False, **properties: Any)[source]

Bases: TransitionBase

Tweens one or more properties of a widget over time.

Use arcade.gui.experimental.UIAnimatedGroup.animate() to create and start an animation:

anim = widget.animate(scale=1.08, angle=2.5, duration=0.15, ease=Easing.BACK_OUT)
anim.then(scale=1.0, angle=0.0, duration=0.15)   # runs afterwards
anim.on_finish(lambda: print("done"))
anim.stop()                                       # cancel this animation only

Start values are read from the widget when a segment starts, so animations always continue smoothly from the current state. To animate from a fixed value, set the property before animating (widget.alpha = 0; widget.animate(alpha=255)).

Conflicts are resolved per property: when a segment starts, it takes ownership of its properties and other running animations stop touching them - the rest of their properties keep animating. This means starting a new animation “wins” without cancelling unrelated animations.

An Animation implements the TransitionBase protocol and can be combined with the low level transition classes via + (sequential) and | (parallel).

Parameters:
  • duration – Duration of the first segment in seconds.

  • ease – Easing function for the first segment, see arcade.anim.Easing.

  • delay – Seconds to wait before the first segment starts.

  • repeat – How often to repeat the whole animation after its first run. True or a negative value repeats forever. Each iteration re-reads the start values, so relative targets (rel()) accumulate.

  • yoyo – If True, the animation plays backwards to its start values before it finishes (or repeats).

  • **properties – Attribute names mapped to target values, e.g. scale=1.0, alpha=255. Values wrapped in rel() are relative to the current value. A segment without properties acts as a pause.

property finished: bool

True if the animation completed or was stopped.

on_finish(callback: Callable[[], Any]) Animation[source]

Register a callback invoked once when the animation completes.

Not invoked when the animation is stopped via stop() or overwritten by other animations. Endlessly repeating animations never finish.

Parameters:

callback – Callable without arguments.

Returns:

The animation itself, for method chaining.

stop() None[source]

Stop the animation, leaving the properties at their current values.

The widget removes stopped animations automatically. on_finish callbacks are not invoked.

then(*, duration: float = 0.3, ease: EasingFunction = <function Easing.LINEAR>, delay: float = 0.0, **properties: Any) Animation[source]

Append a segment which runs after the previous one finished.

Accepts the same arguments as the constructor (except repeat and yoyo, which apply to the whole animation). A then() without properties acts as a pause:

widget.animate(alpha=0, duration=0.5).then(duration=0.1).on_finish(arcade.exit)
Returns:

The animation itself, for method chaining.

tick(subject: Any, dt: float) float[source]

Advance the animation, called by the owning widget.

Returns:

dt, which was not consumed

arcade.gui.experimental.rel(value: float) _Relative[source]

Mark an animation target as relative to the property’s current value.

# rotate 360 degrees counterclockwise from wherever the widget is now,
# forever (each iteration adds another turn)
widget.animate(angle=rel(-360), duration=8, repeat=True)

Only numeric values (and types supporting current + value) can be relative.

Parameters:

value – Offset added to the current value when the animation starts.

class arcade.gui.experimental.TransitionBase[source]

Bases: ABC

abstract property finished: bool
abstractmethod tick(subject, dt) float[source]

Update

Returns:

dt, which is not consumed

class arcade.gui.experimental.EventTransitionBase(*, duration: float, delay=0.0)[source]

Bases: TransitionBase, EventDispatcher

Extension of TransitionBase, providing hooks via

  • on_tick(subject, progress: float)

  • on_finish(subject)

Parameters:
  • duration – Duration of the transition in seconds

  • delay – Start transition after x seconds

property finished
on_finish(subject)[source]
on_tick(subject, progress)[source]
tick(subject, dt) float[source]
class arcade.gui.experimental.TransitionDelay(duration: float)[source]

Bases: EventTransitionBase

class arcade.gui.experimental.TransitionAttr(*, end, attribute, duration: float, start=None, ease_function=<function Easing.LINEAR>, delay=0.0, mutation_function: ~typing.Callable[[~typing.Any, str, float], None] = <built-in function setattr>)[source]

Bases: EventTransitionBase

Changes an attribute over time.

Parameters:
  • start – start value, if None, the subjects value is read via getattr

  • end – target value

  • attribute – attribute to set

  • duration – Duration of the transition in seconds

  • ease_function

  • delay – Start transition after x seconds

  • mutation_function – function to be used to set new value

on_tick(subject, progress)[source]
class arcade.gui.experimental.TransitionAttrIncr(*, increment: float, attribute, duration: float, ease_function=<function Easing.LINEAR>, delay=0.0, mutation_function: ~typing.Callable[[~typing.Any, str, float], None] = <built-in function setattr>)[source]

Bases: TransitionAttr

Changes an attribute over time.

Parameters:
  • increment – difference the value should be changed over time (can be negative)

  • attribute – attribute to set

  • duration – Duration of the transition in seconds

  • ease_function

  • delay – Start transition after x seconds

  • mutation_function – function to be used to set new value

on_tick(subject, progress)[source]
class arcade.gui.experimental.TransitionAttrSet(*, value: float, attribute, duration: float, mutation_function=<built-in function setattr>)[source]

Bases: EventTransitionBase

Set the attribute when expired.

Parameters:
  • value – value to set

  • attribute – attribute to set

  • duration – Duration of the transition in seconds

on_finish(subject)[source]
class arcade.gui.experimental.TransitionParallel(*transactions: TransitionBase)[source]

Bases: TransitionBase

A transition assembled by multiple transitions. Executing them in parallel.

add(transition: T) T[source]
property finished: bool
tick(subject, dt)[source]
class arcade.gui.experimental.TransitionChain(*transactions: TransitionBase)[source]

Bases: TransitionBase

A transition assembled by multiple transitions. Executing them sequential.

add(transition: T) T[source]
property finished: bool
tick(subject, dt)[source]
class arcade.gui.experimental.UIRenderGroup(*, child: UIWidget, **kwargs)[source]

Bases: UILayout

A widget that renders its single child onto an internal surface.

The surface is then drawn into the parent surface at render time with applied transformations (rotation, alpha, scale, tint). This makes it cheap to animate a whole subtree of widgets: as long as the child subtree does not change, only the cached surface is drawn again, the child widgets are not re-rendered.

The child is positioned at the bottom left of the group and resized to fill it, so the subtree lives in a local coordinate system starting at (0, 0). Mouse events are converted into this local coordinate system (including the inverse of rotation and scaling) before they are passed to the child.

Only allows a single child. size_hint, size_hint_min and size_hint_max are delegated to the child.

add(child: W, **kwargs) W[source]
alpha

Alpha value (0-255) applied to the whole subtree.

anchor

Point (in local coordinates) to rotate and scale around. Defaults to the center of the group.

angle

Rotation in degrees applied around anchor.

property child: UIWidget | None

The wrapped child widget.

do_layout()[source]

Place the child at (0, 0) filling the group.

The child subtree uses a local coordinate system, which is mapped into the parent surface when the cached surface is drawn.

offset_x

Horizontal translation offset applied when drawing the cached surface. Positive values shift the subtree to the right.

offset_y

Vertical translation offset applied when drawing the cached surface. Positive values shift the subtree upward.

scale

Scale factor applied around anchor. Shadows UIWidget.scale(), which resizes the rect instead.

size_hint

A property that transparently delegates reads, writes, and listener registration to a named Property on a child object.

This lets a parent widget expose a child’s property as its own, so callers can use bind() / unbind() on the parent without knowing about the child:

class UITextButton(UIWidget):
    _label: UILabel

    # Expose the label's "text" Property directly on the button.
    text = AliasProperty(lambda self: self._label, "text")

btn = UITextButton(text="Click me")
bind(btn, "text", lambda inst, val: print("new text:", val))
btn.text = "Updated"  # triggers the listener with inst=btn
Parameters:
  • child_getter – A callable (parent_instance) -> child_instance that returns the child object owning the real property. A plain attribute-name string (e.g. "_label") is also accepted as a convenience shorthand for lambda self: getattr(self, "_label").

  • child_prop_name – The attribute name of the Property on the child class to delegate to.

size_hint_max

A property that transparently delegates reads, writes, and listener registration to a named Property on a child object.

This lets a parent widget expose a child’s property as its own, so callers can use bind() / unbind() on the parent without knowing about the child:

class UITextButton(UIWidget):
    _label: UILabel

    # Expose the label's "text" Property directly on the button.
    text = AliasProperty(lambda self: self._label, "text")

btn = UITextButton(text="Click me")
bind(btn, "text", lambda inst, val: print("new text:", val))
btn.text = "Updated"  # triggers the listener with inst=btn
Parameters:
  • child_getter – A callable (parent_instance) -> child_instance that returns the child object owning the real property. A plain attribute-name string (e.g. "_label") is also accepted as a convenience shorthand for lambda self: getattr(self, "_label").

  • child_prop_name – The attribute name of the Property on the child class to delegate to.

size_hint_min

A property that transparently delegates reads, writes, and listener registration to a named Property on a child object.

This lets a parent widget expose a child’s property as its own, so callers can use bind() / unbind() on the parent without knowing about the child:

class UITextButton(UIWidget):
    _label: UILabel

    # Expose the label's "text" Property directly on the button.
    text = AliasProperty(lambda self: self._label, "text")

btn = UITextButton(text="Click me")
bind(btn, "text", lambda inst, val: print("new text:", val))
btn.text = "Updated"  # triggers the listener with inst=btn
Parameters:
  • child_getter – A callable (parent_instance) -> child_instance that returns the child object owning the real property. A plain attribute-name string (e.g. "_label") is also accepted as a convenience shorthand for lambda self: getattr(self, "_label").

  • child_prop_name – The attribute name of the Property on the child class to delegate to.

tint

Color multiplier applied to the whole subtree.

class arcade.gui.experimental.UIAnimatedGroup(*, child: UIWidget, **kwargs)[source]

Bases: UIRenderGroup, UIInteractiveWidget

An interactive UIRenderGroup which can animate itself.

This is the main entry point for GUI animations. It combines

Hover and click hit-testing runs against the group’s untransformed rect in parent space, so the trigger zone stays stable while the visuals are scaled or rotated. The child subtree still receives mouse events transformed into its local coordinate system.

React to state changes by binding to the group’s properties:

group = UIAnimatedGroup(child=UIFlatButton(text="Play"))

def on_hover_change():
    if group.hovered:
        group.animate(scale=1.08, duration=0.15, ease=Easing.BACK_OUT)
    else:
        group.animate(scale=1.0, duration=0.15)

bind(group, "hovered", on_hover_change)
Parameters:
  • child – The wrapped widget.

  • **kwargs – Passed on, e.g. interaction_buttons of UIInteractiveWidget.

add_transition(transition: T) T[source]

Add a low level transition, which is ticked with update time.

Most code should prefer animate().

animate(*, duration: float = 0.3, ease: EasingFunction = <function Easing.LINEAR>, delay: float = 0.0, repeat: int | bool = 0, yoyo: bool = False, **properties: Any) Animation[source]

Animate properties of this group over time.

group.animate(scale=1.08, duration=0.15, ease=Easing.BACK_OUT)
group.animate(alpha=0, duration=0.5).then(duration=0.1).on_finish(arcade.exit)
group.animate(scale=1.05, duration=0.6, ease=Easing.SINE, repeat=True, yoyo=True)

Start values are read when the animation starts. Starting a new animation takes over its properties from other running animations, which keep animating their remaining properties.

The transform properties (scale, angle, alpha, offset_x, offset_y, tint) animate the wrapped subtree visually, without affecting layouting.

Parameters:
  • duration – Duration of the animation in seconds.

  • ease – Easing function, see arcade.anim.Easing.

  • delay – Seconds to wait before the animation starts.

  • repeat – How often to repeat the animation, True repeats forever.

  • yoyo – If True, the animation plays backwards to its start values before it finishes (or repeats).

  • **properties – Attribute names mapped to target values, e.g. scale=1.08. Values wrapped in rel() are relative to the current value.

Returns:

The running Animation, which can be extended with .then(...), observed with .on_finish(...) and cancelled with .stop().

clear_transitions()[source]

Remove all transitions from this group.

Finished transitions are removed automatically.

This also stops all running animations, including animations of other code. Prefer Animation.stop() or starting a new animation for the same properties, which takes them over automatically.

on_event(event: UIEvent) bool | None[source]
class arcade.gui.experimental.UIPasswordInput(*, x: float = 0, y: float = 0, width: float = 100, height: float = 25, text: str = '', font_name=('Arial',), font_size: float = 12, text_color: tuple[int, int, int] | tuple[int, int, int, int] = (255, 255, 255, 255), multiline=False, caret_color: tuple[int, int, int] | tuple[int, int, int, int] = (255, 255, 255, 255), border_color: Color | None = (255, 255, 255, 255), border_width: int = 2, size_hint=None, size_hint_min=None, size_hint_max=None, style: dict[str, UIInputTextStyle] | None = None, **kwargs)[source]

Bases: UIInputText

A password input field. The text is hidden with asterisks.

Hint: It is recommended to set a background color to prevent full render cycles when the caret blinks.

do_render(surface: Surface)[source]

Override to render the text as asterisks.

on_event(event: UIEvent) bool | None[source]

Remove new lines from the input, which are not allowed in passwords.

class arcade.gui.experimental.scroll_area.UIScrollBar(scroll_area: UIScrollArea, vertical: bool = True)[source]

Bases: UIWidget

Scroll bar for a UIScrollLayout.

Indicating the current view position of the scroll area. Supports mouse dragging to scroll the content.

do_render(surface: Surface)[source]

Render the scroll bar.

on_event(event: UIEvent) bool | None[source]
class arcade.gui.experimental.UIScrollArea(*, x: float = 0, y: float = 0, width: float = 300, height: float = 300, children: Iterable[UIWidget] = (), size_hint=None, size_hint_min=None, size_hint_max=None, canvas_size=None, overscroll_x=False, overscroll_y=False, scroll_speed: float | None = None, invert_scroll: bool | None = None, **kwargs)[source]

Bases: UILayout

A widget that can scroll its children.

Children are laid out on an internal canvas, which resizes itself to fit all children (at least the size of the scroll area itself). The visible part of the canvas is controlled by scroll_x and scroll_y (both range from 0 at the start of the content to a negative value at the end).

For a typical scrollable list, add a container with size_hint=(1, 0) (fill the width of the scroll area, grow to the natural content height) like UIBoxLayout.

Scrolling is supported via mouse wheel, UIScrollBar and, while the mouse hovers the widget, the keyboard (arrow keys, PageUp/PageDown, Home/End).

Note

Content containing labels may finish sizing only during the first layout pass and render on the following frame. Single-frame capture pipelines (e.g. CI screenshots) should draw two frames.

This widget is experimental, the API might change.

Parameters:
  • x – x position of the widget

  • y – y position of the widget

  • width – width of the widget

  • height – height of the widget

  • children – children of the widget

  • size_hint – size hint of the widget

  • size_hint_min – minimum size hint of the widget

  • size_hint_max – maximum size hint of the widget

  • canvas_size – deprecated, the canvas is sized automatically to fit all children

  • overscroll_x – allow over scrolling in x direction (scroll past the end)

  • overscroll_y – allow over scrolling in y direction (scroll past the end)

  • scroll_speed – speed of scrolling in pixels per scroll event, defaults to scroll_speed

  • invert_scroll – invert the scroll direction, defaults to invert_scroll

  • **kwargs – passed to UIWidget

add(child: W, **kwargs) W[source]

Add a child to the widget.

do_layout()[source]

Layout the children of the widget.

do_render(surface: Surface)[source]

Renders the scolled surface into the given surface.

invert_scroll: bool = False

Default for inverting the scroll direction.

on_event(event: UIEvent) bool | None[source]

Handle scrolling of the widget.

remove(child: UIWidget)[source]

Remove a child from the widget.

scroll_speed: float = 15.0

Default scroll speed in pixels per scroll event.

scroll_x

An observable property which triggers observers when changed.

def log_change(instance, value):
    print("Something changed")

class MyObject:
    name = Property()

my_obj = MyObject()
bind(my_obj, "name", log_change)
unbind(my_obj, "name", log_change)

my_obj.name = "Hans"
# > Something changed

Properties provide a less verbose way to implement the observer pattern in comparison to using the property decorator.

Parameters:
  • default – Default value which is returned, if no value set before

  • default_factory – A callable which returns the default value. Will be called with the property and the instance

scroll_y

An observable property which triggers observers when changed.

def log_change(instance, value):
    print("Something changed")

class MyObject:
    name = Property()

my_obj = MyObject()
bind(my_obj, "name", log_change)
unbind(my_obj, "name", log_change)

my_obj.name = "Hans"
# > Something changed

Properties provide a less verbose way to implement the observer pattern in comparison to using the property decorator.

Parameters:
  • default – Default value which is returned, if no value set before

  • default_factory – A callable which returns the default value. Will be called with the property and the instance

class arcade.gui.experimental.typed_text_input.UITypedTextInput(parsed_type: type[~arcade.gui.experimental.typed_text_input.T], *, to_str: ~collections.abc.Callable[[~arcade.gui.experimental.typed_text_input.T], str] = <built-in function repr>, from_str: ~collections.abc.Callable[[str], ~arcade.gui.experimental.typed_text_input.T] | None = None, emit_parse_exceptions: bool = True, x: float = 0, y: float = 0, width: float = 100, height: float = 24, text: str = '', font_name=('Arial',), font_size: float = 12, text_color: tuple[int, int, int] | tuple[int, int, int, int] = (0, 0, 0, 255), error_color: tuple[int, int, int] | tuple[int, int, int, int] = (255, 0, 0, 255), multiline=False, size_hint=None, size_hint_min=None, size_hint_max=None, **kwargs)[source]

Bases: UIInputText, Generic[T]

A text box which auto-converts to and from a type.

The simplest usage is passing a type() which supports repr() and allows a single str as an argument:

self.float_input = UITypedTextInput(float, text="0.0")

In the example above, setting self.float_input.text to "string" will:

  1. Set both the text and the caret to the error_color passed at creation

  2. Re-raise the ValueError from float("string")

To stop error propagation, pass You can customize your conversion to and from strings by overriding the following arguments with custom callable objects:

Argument

Default

to_str

repr()

from_str

the parsed_type

Important

This class is meant to handle simple types in simple dev and test tools.

As a general rule, if you need to highlight a specific syntax error, this class is not the right tool.

Parameters:
  • parsed_type – The type to require. This is not meant to be changed after creation.

  • from_str – A type or other callable() which converts a str to an instance of parsed_type. It may raise exceptions and perform cleaning of text.

  • to_str – A callable() which converts parsed_type instances to str.

  • x – an X position (see UIInputText).

  • y – an X position (see UIInputText).

  • width – an X axis width (see UIInputText).

  • height – a Y axis height (see UIInputText).

  • text – The initial text to display.

  • font_name – (see UIInputText).

  • text_color – The color to use for non-error text.

  • error_color – The color to use when to_str or from_str raised an exception.

  • multiline – See UIInputText.

  • size_hint – See UIInputText.

  • size_hint_min – See UIInputText.

  • size_hint_max – See UIInputText.

on_event(event: UIEvent) bool | None[source]
property parsed_type: type[T]

Get the type this input field expects to parse.

Note

This is not meant to be changed after creation.

property text: str

Get/set the text of the widget.

In addition to basic behavior from UITextWidget, this also performs validation. To silence error propagation from validation, set emit_parse_exceptions to False.

property value: T

The current instance of parsed_type.

Setting this automatically updates the text of the widget.