SvgWidget

A Kivy widget for displaying SVG content using adaptive rasterization via the kivy.core.svg provider system.

Features

  • SVG loading from source (local file path or in-memory SVG bytes; AsyncSvgWidget additionally accepts HTTP/HTTPS URLs)

  • Efficient downscaling using mipmaps (enabled by default)

  • Re-rasterization at higher resolution when the display scale crosses an internal threshold

  • Limited runtime document customisation:

  • AsyncSvgWidget adds asynchronous HTTP/HTTPS loading

Difference from the SVG image provider

The SVG image provider (kivy.core.image) lets you use Image(source="file.svg") and renders once at a fixed size. SvgWidget differs in:

  • Adaptive re-rasterization - re-renders when scaling up beyond threshold

  • Mipmap-first - mipmaps enabled by default

  • ``current_color`` - CSS currentColor injection not available via the image pipeline

  • Element overrides - per-element visibility/opacity not available via the image pipeline

Basic usage

from kivy.uix.svg import SvgWidget

svg = SvgWidget(source='diagram.svg', size_hint=(None, None), size=(64, 64))

KV:

SvgWidget:
    source: 'diagram.svg'
    current_color: 1, 0, 0   # red currentColor
    on_load: print('SVG ready')

AsyncSvgWidget:
    source: 'https://example.com/diagram.svg'

SVG icon button

Combine ToggleButtonBehavior with SvgWidget to create a tappable icon that changes colour on toggle. This pattern works with any SVG that uses stroke="currentColor" or fill="currentColor". Most popular svg icon libraries use currentColor by default, including Lucide, Heroicons, and Tabler Icons.

# Python
from kivy.uix.behaviors import ToggleButtonBehavior
from kivy.uix.svg import SvgWidget

class StarIconToggleButton(ToggleButtonBehavior, SvgWidget):
    pass

# KV
<StarIconToggleButton>:
    source: 'star.svg'
    size_hint: None, None
    size: '64dp', '64dp'
    fit_mode: 'contain'
    mipmap: False
    current_color: 'gold' if self.activated else 'grey'

Added in version 3.0.0.

class kivy.uix.svg.AsyncSvgWidget(**kwargs)[source]

Bases: SvgWidget

Asynchronous variant of SvgWidget that downloads SVG files from HTTP/HTTPS URLs in a background thread.

Local file paths are loaded synchronously (same behaviour as SvgWidget). Remote URLs are downloaded in a daemon thread; the widget shows loading_texture while the download is in progress.

Note

The loading image and error image are taken from Kivy’s global Loader.loading_image and Loader.error_image, matching AsyncImage. To use a custom image, set these before creating any AsyncSvgWidget:: The loading image supports GIF animation.

from kivy.loader import Loader Loader.loading_image = ‘my_spinner.gif’ Loader.error_image = ‘my_error.png’

Example KV usage:

AsyncSvgWidget:
    source: 'https://example.com/icon.svg'
    on_load: print('downloaded and ready')
    on_error: print('failed:', args[1])
error_texture

Texture shown when loading or rendering fails.

Initialised to Loader.error_image.texture in __init__.

error_texture is an ObjectProperty and defaults to None.

get_norm_image_size()[source]

Return the display size after applying fit_mode.

While loading or showing an error placeholder the texture is drawn at its natural size (scale-down behaviour) regardless of fit_mode, so a small spinner GIF is never stretched to fill the widget. Once the SVG is ready the base class logic applies.

static is_uri(filename)[source]

Return True if filename is an HTTP or HTTPS URL.

Non-string values (e.g. bytes, pathlib.Path) always return False.

Parameters:

filename – Source value to test.

Return type:

bool

loading_texture

Initial texture shown the moment a load starts, before the first GIF frame callback fires.

Initialised to Loader.loading_image.texture in __init__. While loading is in progress the widget automatically tracks Loader.loading_image.texture so animated GIF placeholders play at full frame rate. The binding is removed as soon as the SVG is ready or an error occurs.

loading_texture is an ObjectProperty and defaults to None.

norm_image_size

Extends the base norm_image_size to also recompute when status changes.

texture_update(*largs)[source]

No-op - prevents the inherited synchronous load path.

class kivy.uix.svg.SvgWidget(**kwargs)[source]

Bases: Widget

Widget that displays an SVG document using adaptive rasterization.

The SVG is rasterized to a Texture via the kivy.core.svg provider. The texture is re-created when the display size grows beyond _RERENDER_THRESHOLD times the current raster size, keeping the image sharp at larger scales without wasting GPU memory at smaller ones.

Downscaling is handled efficiently by OpenGL mipmaps (mipmap defaults to True).

color

Tint colour applied via the canvas Color instruction.

color is a ColorProperty and defaults to [1, 1, 1, 1] (opaque white - no tint).

current_color

RGB colour injected for the CSS currentColor keyword at render time.

Every currentColor token in the SVG source is replaced with this colour before rasterization. Changing this property triggers a re-render at the current raster size.

Per the SVG spec, currentColor is a pure RGB value - opacity is a separate concern expressed via fill-opacity / stroke-opacity attributes in the SVG source. Only the red, green and blue components of this property are used; the alpha component is ignored.

current_color is a ColorProperty and defaults to [0, 0, 0, 1] (black).

element_overrides

Per-element render overrides keyed by SVG element id.

Each value is a dict with optional keys:

  • 'visible' (bool) - False forces opacity to 0.

  • 'opacity' (float 0.0-1.0) - overrides the SVG native opacity when the element is visible.

Absent keys fall back to SVG defaults. Changing this property triggers a re-render at the current raster size.

Example:

svg.element_overrides = {
    'badge':     {'visible': False},
    'highlight': {'opacity': 0.5},
}

element_overrides is a DictProperty and defaults to {}.

fit_mode

Scaling mode for display within the widget bounds.

Identical in meaning to fit_mode.

Available options:

  • "scale-down" - never upscales; preserves aspect ratio.

  • "fill" - stretches to fill the widget; ignores aspect ratio.

  • "contain" - fits inside widget; may upscale; preserves ratio.

  • "cover" - fills widget; may crop; preserves ratio.

fit_mode is an OptionProperty and defaults to 'scale-down'.

get_element_ids()[source]

Return a list of all SVG element id values in the document.

The list is built once at load time. Returns an empty list if the SVG has not been loaded yet, and logs a warning.

Return type:

list[str]

get_element_opacity(element_id)[source]

Return the current opacity override for element_id.

Returns 1.0 for elements with no opacity override.

Parameters:

element_id (str) – The SVG element id.

Return type:

float

get_norm_image_size()[source]

Return the display size of the SVG after applying fit_mode.

Mirrors get_norm_image_size() exactly.

hide_element(element_id)[source]

Hide the SVG element with the given id.

Convenience wrapper for set_element_visible(element_id, False).

Parameters:

element_id (str) – The SVG element id attribute value.

is_element_visible(element_id)[source]

Return whether the element with element_id is currently visible.

Returns True for elements with no override (SVG default).

Parameters:

element_id (str) – The SVG element id.

Return type:

bool

loaded

True once the SVG has been successfully loaded and the first texture is ready. Resets to False when source changes or reload() is called.

Use this as a guard before calling element manipulation methods:

if svg.loaded:
    svg.hide_element('badge')

loaded is a BooleanProperty and defaults to False.

mipmap

Enable mipmap generation on the rasterized texture.

Mipmaps allow efficient GPU downscaling without aliasing artefacts. Defaults to True (unlike Image).

Changing this property after load triggers a re-rasterization.

mipmap is a BooleanProperty and defaults to True.

norm_image_size

The portion of the widget area actually occupied by the rendered image after fit_mode geometry is applied.

For example, with fit_mode='contain' on a 400x400 widget displaying a 400x250 SVG, norm_image_size returns [400, 250] — the image fills the full width but only part of the height.

Use this to center an overlay on the rendered content, to do hit-testing against the visible image region, or to place a sibling widget alongside the actual (not padded) image area.

Note

Do not use norm_image_size to drive the widget size. get_norm_image_size() reads self.size internally, so binding size: self.norm_image_size creates the same circular dependency as texture_size. Use viewbox_size for that purpose.

norm_image_size is an AliasProperty and is read-only.

reload()[source]

Discard the current SVG document and reload from source.

Resets loaded and status immediately; the new texture is available after the next successful rasterization.

reset_element_overrides()[source]

Clear all element visibility and opacity overrides.

Triggers a re-render that restores all elements to their SVG defaults.

set_element_opacity(element_id, opacity)[source]

Set the opacity override for an SVG element by its id.

Stores the override in element_overrides and triggers a re-render. If the SVG is not yet loaded, the override is still stored.

If element_id is not found in the document, a warning is logged.

Parameters:
  • element_id (str) – The SVG element id.

  • opacity (float) – Opacity value 0.0 (transparent) - 1.0 (opaque).

set_element_visible(element_id, visible)[source]

Set the visibility of an SVG element by its id.

Stores the override in element_overrides and triggers a re-render. If the SVG is not yet loaded, the override is still stored and will be applied when the document loads.

If element_id is not found in the document, a warning is logged but the override is still stored.

Parameters:
  • element_id (str) – The SVG element id.

  • visible (bool) – True to show, False to hide.

show_element(element_id)[source]

Show the SVG element with the given id.

Convenience wrapper for set_element_visible(element_id, True).

Parameters:

element_id (str) – The SVG element id attribute value.

source

SVG source - a file path, raw bytes, or (for AsyncSvgWidget) an HTTP/HTTPS URL.

The type determines how the SVG is loaded:

  • str or pathlib.Path - resolved via resource_find and loaded from the local filesystem.

  • bytes or bytearray - loaded directly as in-memory SVG data; no file I/O is performed. Useful for embedding SVG content in code.

When passing bytes, Kivy forwards them to the SVG renderer unchanged. No encoding conversion is performed, so the byte sequence must already match the encoding declared in the SVG (e.g. encoding="utf-8" or encoding="gb2312"). Use open(path, 'rb') or an explicit str.encode(encoding) call to produce correctly encoded bytes; the proper encoding is the caller’s responsibility.

Setting this property automatically triggers a load and rasterize.

source is an ObjectProperty and defaults to None.

status

Current load state.

Value

Meaning

empty

No source set

loading

Source set; loading in progress

ready

SVG loaded and texture available

error

Load or render failed

loaded is always equivalent to status == 'ready'. Use whichever reads more clearly: status when you need to distinguish between states (e.g. show a spinner while 'loading', an error icon on 'error'), or loaded for a simple boolean guard (if self.loaded:).

status is an OptionProperty and defaults to 'empty'.

texture

Current rasterized Texture.

Updated after every successful rasterization (including re-renders on scale-up).

texture is an ObjectProperty and defaults to None.

texture_size

Pixel dimensions of the current texture.

Updated whenever texture changes. Reflects the size at which the SVG was last rasterized, which equals the widget size at render time.

Use this to read back the rendered resolution (for example, to pass to a shader or to report in a UI label).

Note

Do not use texture_size to drive the widget size (e.g. size: self.texture_size in KV). The widget must have a non-zero size before rasterization can produce a texture, so this creates a circular dependency that leaves the widget invisible. Use viewbox_size instead.

texture_size is a ListProperty and defaults to [0, 0].

texture_update(*largs)[source]

Load (or reload) the SVG from source and rasterize.

Called automatically when source changes. Can also be called manually to force a reload.

viewbox_size

Intrinsic SVG dimensions from the viewBox or width/height attributes. Set at load time, before rasterization; [0, 0] before any source is loaded.

This is the correct property to use when you want the widget to display at the SVG’s natural pixel size. Because viewbox_size is populated before the deferred rasterize fires, a KV binding like:

SvgWidget:
    size_hint: None, None
    size: self.viewbox_size

works without a circular dependency: the size is known by the time the first rasterization is scheduled, so the texture is produced at exactly the right dimensions.

Contrast with texture_size (set after rasterization, so it cannot safely drive the widget size) and norm_image_size (depends on self.size internally, same circular problem).

viewbox_size is a ListProperty and defaults to [0, 0].