Skip to main content

pyside-iconify

Give QIcon a data source.

English | 中文 | 日本語 | 한국어 | Español | Français | Deutsch | Русский | Português (BR)

IconWidget("mdi:home", color="red")

One line, one icon. No SVG or PNG files to manage — icons are fetched on demand from the Iconify ecosystem by name and cached automatically. Everything still ends up as a standard QIcon, so it works with any widget that accepts icons.

This project is not affiliated with the Iconify project.

Why

Without With pyside-iconify
QIcon("assets/home.svg") get_icon("mdi:home")
Managing SVG/PNG files and resource paths Icons by name from the Iconify ecosystem
Multiple asset sets for colors and sizes color, size, rotate as parameters
Per-widget icon plumbing Standard QIcon, works everywhere
Manual light/dark theme icon variants Follows the widget's palette automatically

Quick start

Pick the Qt binding your application uses and install the matching extra:

# Install the line that matches the Qt binding you use.
pip install "pyside-iconify[pyside6]"   # you use PySide6 (also the default for type hints)
pip install "pyside-iconify[pyqt6]"     # you use PyQt6
pip install "pyside-iconify[pyqt5]"     # you use PyQt5
pip install "pyside-iconify[pyside2]"   # you use PySide2 (Python 3.10 only)

The extra installs the binding itself plus the type stubs for it. If the binding is already installed, plain pip install pyside-iconify works at runtime too (the library uses whichever binding your program has imported), but without the extra, non-PySide6 users get no precise type hints. See Choosing a Qt binding.

from PySide6.QtWidgets import QApplication, QPushButton
from pyside_iconify import IconWidget, get_icon

app = QApplication([])

# A standalone icon widget
icon = IconWidget("mdi:home", size=24, color="red")

# Or hand a standard QIcon to any widget
button = QPushButton("Settings")
button.setIcon(get_icon("mdi:cog", size=20))

app.exec()

That is the whole API for the common case. Icons are downloaded on first use, cached on disk, and rendered locally afterwards.

Highlights

  • Theme aware — with no color set, icons follow the widget's text color and switch automatically between light and dark themes; disabled icons fade instead of turning gray (so multi-color icons fade correctly too)
  • Full color control — single color, {original: replacement} mapping for multi-color icons, and per-theme overrides (color_light_theme / color_dark_theme)
  • Sizes the way you think — numbers, (w, h), QSize, "24px", or "1.5em" (follows the widget's font)
  • HiDPI native — sizes are logical pixels; physical pixels are rendered per screen scale factor, no @2x/@3x asset sets
  • Loading vs. missing are distinct — loading shows blank, a confirmed miss shows a built-in placeholder and emits failed; optional fallback icon
  • QSS friendly — qss="toolbar primary" tags for grouping, style with native setStyleSheet(); priority: parameters → QSS → theme
  • Animation built in — spin, pulse, breathe, ping, bounce, plus the self-animating icons of line-md, meteocons and svg-spinners play as-is in IconWidget (SMIL only; see below)
  • Typed and logged — full type hints with py.typed, standard logging (silent by default)

Parameters

Shared by IconWidget and get_icon:

get_icon(name, *, size=24, color=None, color_light_theme=None,
         color_dark_theme=None, selected_color=None, opacity=1.0,
         width=None, height=None, rotate=0, rotate_overflow=False,
         spin=False, h_flip=False, v_flip=False)

IconWidget(name, *, ..., hover_color=None, animation=None,
           animation_period=None, animation_depth=None, autoplay=True,
           speed=1.0, qss=None, parent=None)
Parameter Meaning
name Icon name like "mdi:home", or inline icon data
size Number, (w, h), QSize, "24px", or "1.5em"
color A color, or a {original: replacement} mapping
color_light_theme / color_dark_theme Per-theme overrides, win over color
selected_color Color when the item is selected (item views)
hover_color IconWidget / set_icon hover color — explicit opt-in
opacity Overall opacity 0–1; multiplied with color alpha
width / height Non-square icons; win over size
rotate Any angle in degrees, auto-shrunk to avoid clipping
rotate_overflow Keep the original size while rotating; corners may clip
spin Continuous rotation for loading indicators
animation / animation_period IconWidget only: "spin", "pulse", "breathe", "ping" or "bounce"; seconds per cycle
autoplay / speed IconWidget only: play the icon's own SMIL animation automatically; playback speed multiplier
animation_depth How strong the animation is, 0–1 (defaults: pulse 0.25, breathe 0.7, ping 1, bounce 0.25). ping and bounce draw the icon at 1/(1+depth) of the widget to leave room for the ripple and the jump
h_flip / v_flip Horizontal / vertical flip
qss QSS grouping tags, IconWidget[qss~="tag"] selector (IconWidget only)

Colors accept CSS/SVG names, HEX 3/4/6/8 digit (#RRGGBBAA order), rgb()/rgba()/hsl()/hsla(), tuples, QColor, and Qt.GlobalColor. Unparseable colors raise instead of silently turning black.

Animated icons (SMIL)

Some Iconify sets (line-md, meteocons, svg-spinners, eos-icons, ...) ship icons that animate themselves. IconWidget plays them with no extra code:

IconWidget("line-md:loading-loop", size=48)       # loops
IconWidget("line-md:account")                     # draws itself once, then rests
IconWidget("meteocons:partly-cloudy-day-rain", size=96)
w = IconWidget("line-md:account", autoplay=False, speed=0.5)
w.play(); w.pause(); w.replay(); w.setSpeed(2)
w.isAnimated(), w.isPlaying()

get_icon() and set_icon() return a standard QIcon, which cannot move on its own, so they show the finished state of the animation. Use IconWidget for the animated version. is_animated("line-md:account") tells whether an icon carries an animation (it works without Qt).

Scope: only SMIL is supported (<animate>, <set>, <animateTransform>, <animateMotion> inside the SVG). Other kinds of animation, such as CSS animation, scripts, Lottie or GIF, are not played. An icon that uses a SMIL feature the library does not implement is drawn as a static image of its finished state and a warning is logged once.

Animated frames are cached as bitmaps (trading memory for speed). A long looping icon at a large size can take several MiB of the default 32 MiB cache; raise it with set_cache_limits() if you show many of them at once.

Offline packaging

For air-gapped machines or zero-external-dependency builds, pack icons at release time:

python -m pyside_iconify.pack -o icons.json
from pyside_iconify import load_bundle

load_bundle("icons.json")  # at app startup; works inside PyInstaller too

See src/pyside_iconify/pack.py and tests/test_pack_integration.py for the full CLI and API. Local data always takes priority over the network.

Performance

Three-layer cache (icon data → SVG text → rendered bitmaps) with a memory budget, per-frame work kept to a cache lookup and one drawPixmap. A 1000-row QListWidget builds in ~270 ms and scrolls at native speed. For large grids use item views with get_icon; IconWidget is meant for standalone icon slots.

Choosing a Qt binding

The same code runs on four bindings. Import your own binding as usual; the library follows it.

Binding Status Extra
PySide6 Supported, primary pyside-iconify[pyside6]
PyQt6 Supported pyside-iconify[pyqt6]
PyQt5 Compatible pyside-iconify[pyqt5]
PySide2 Compatible, Python 3.10 only pyside-iconify[pyside2]

How the binding is picked, in order:

  1. The environment variable PYSIDE_ICONIFY_QT_API (pyside6, pyqt6, pyqt5 or pyside2), if set.
  2. The binding your program already imported before pyside_iconify.
  3. The first installed one, in the order PySide6, PyQt6, PyQt5, PySide2.

Notes:

  • Never mix bindings in one process. If your program imported one binding and the environment variable names another, the library raises an error instead of guessing.
  • Type hints. The pyqt6, pyqt5 and pyside2 extras also install a small stub package (pyside-iconify-stubs-<binding>) so editors and type checkers see the classes of your binding (QIcon, QSize, ...) instead of Any. Installing it later fixes the hints too.
  • Qt5 and HiDPI. Qt5 only produces sharp icons on high-DPI screens when the application sets Qt.AA_UseHighDpiPixmaps before creating the QApplication. Qt6 does this by default.
  • PyQt licensing. PyQt5 and PyQt6 are available under the GPL v3 or a commercial license from Riverbank Computing. pyside-iconify itself is MIT and does not bundle Qt or PyQt, but if you choose PyQt, your application is subject to PyQt's license. PySide6 and PySide2 are LGPL.

Support scope

Item Scope
Python 3.10 – 3.14 (PySide2: 3.10 only, its last supported one)
Qt PySide6, PyQt6 (6.4+); PyQt5 (5.15.9+); PySide2 (5.15.2.1)
OS Windows, macOS, Linux (CI on macOS)

Development

uv sync --extra pyside6 --group test   # once: installs PySide6 and the test tools
uv run pytest -v                       # tests (set QT_QPA_PLATFORM=offscreen first)
uv run examples/smil_showcase.py       # run an example from examples/

The extras are mutually exclusive, so to try another Qt binding use a throwaway environment; your .venv stays on PySide6:

uv run --isolated --extra pyqt6 --group test pytest -v
uv run --isolated --extra pyqt6 examples/smil_showcase.py
# --extra pyqt5, or: --python 3.10 --extra pyside2

The files in examples/ import Qt through a small helper (examples/_qt.py) so that they run on every binding. In your own application, import your binding directly, as in the quick start.

License

MIT. Icon collections are subject to their own licenses; Qt is licensed separately by its copyright holders.

Metadata

Release files for pyside-iconify 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyside-iconify 1.2.0
File Size Uploaded Provenance
pyside_iconify-1.2.0.tar.gz 214.8 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pyside-iconify 1.2.0
File Interpreter ABI Platform
pyside_iconify-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 331.9 kB

Release files / pyside_iconify-1.2.0.tar.gz

Download URL pyside_iconify-1.2.0.tar.gz
Size 214.8 kB
Tags Source
SHA-256 checksum
How to use checksums
3f4528a3be7edd4715452d3f6259726dfeffd0551202975d5b1cd7533e6d2323
BLAKE2b-256 checksum
How to use checksums
6888c6de1f251d5b75ab3fa22d4c477b947ce146f1327c98c63f765ea2905a08
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Release files / pyside_iconify-1.2.0-py3-none-any.whl

Download URL pyside_iconify-1.2.0-py3-none-any.whl
Size 117.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e93a7aaaa1620092462f2f053e1ffd4906dca1774054d20b917a796c71c0a17f
BLAKE2b-256 checksum
How to use checksums
ed63d74d8e90face39f94dea75af936aa5ee792d613cbb4eef0f645c769752bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Security for pyside-iconify 1.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pyside_iconify-1.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page