Skip to main content

SWUbanner

QtMDi (Qt Material Design icons)

license pypi version PyPI Python Version

Copyright 2023 Yaroshenko Dmytro (https://github.com/o-murphy)

The extension for QtAwesome with the latest variable icon fonts for Material Symbols

(Python 3, PySide, PyQt)

[!NOTE] Fonts in this package automatically updated, so it will always have the latest icons from Google

[!NOTE] The package is publishing to PyPi automatically, so it can have issues in some releases

[!NOTE] The package uses QtAwesome as it's backend, so it support all the feature provided by QtAwesome, for more see the docs

Installation

QtMDi is built on QtAwesome and qtpy, which is just an abstraction layer over Qt bindings - it doesn't ship a Qt binding itself, so you need to install one (PyQt5, PySide2, PyQt6 or PySide6) alongside it:

pip install QtMDi PyQt6

Install the latest release from PyPi:

pip install QtMDi

Install the latest updated version from github:

pip install https://github.com/o-murphy/QtMDi

Using qtmdi-browser as a standalone tool

If you just want to run the icon browser (see Available Icons) without installing QtMDi into a project, use uv tool install (or pipx) with a Qt binding as an extra dependency:

uv tool install qtmdi --with pyqt6
# or
uv tool install qtmdi --with pyside6

qtmdi-browser

Usage

Supported Fonts

QtAwesome identifies icons by their prefix and their icon name, separated by a period (.) character.

The following prefixes are currently available to use:

Example

Import qtawesome and qtmdi in your python file:

import qtawesome
import qtmdi

Icon creation example

# basic rounded
qtawesome.icon("mds-rounded-base.home")

# rounded with 700 width
qtawesome.icon("mds-rounded-700.home")

# rounded with 400 width
qtawesome.icon("mds-sharp-400.home")

# basic variablefont ttf based icon
qtawesome.icon("mdf-sharp.home")

Create an app

from qtpy import QtWidgets

class Example(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.lt = QtWidgets.QVBoxLayout(self)
        self.btn = QtWidgets.QToolButton(self)
        self.btn.setIcon(
            qtawesome.icon("mds-rounded-700.home"),
        )
        self.btn.setFixedSize(48, 48)
        self.btn.setIconSize(32, 32)
        self.lt.addWidget(self.btn)

Load extension on your app instance

import sys
from qtpy import QtWidgets
import qtawesome
import qtmdi


# Create an app
class Example(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.lt = QtWidgets.QVBoxLayout(self)
        self.btn = QtWidgets.QToolButton(self)
        self.btn.setIcon(
            qtawesome.icon("mds-rounded-700.home"),
        )
        self.btn.setFixedSize(48, 48)
        self.btn.setIconSize(32, 32)
        self.lt.addWidget(self.btn)
        
def run():
    app = QtWidgets.QApplication()
    
    # Load extension on your app instance
    qtmdi.load(app)
    
    qtawesome.dark(app)
    w = Example()
    w.show()
    sys.exit(app.exec_())
        
if __name__ == '__main__':    
    run()

[!NOTE] qtmdi.load(app) is lazy by default: it only registers which fonts are available, and reads/loads the actual font file the first time one of its icons is requested through qtawesome.icon(...). This keeps memory usage and startup time low when your app only ever uses a few styles/weights out of everything QtMDi ships.

Pass qtmdi.load(app, lazy=False) to load every shipped font immediately instead (this is what qtmdi-browser does, since it needs to list every icon right away).

If you know upfront exactly which fonts your app uses, restrict qtmdi to just those with load_only, e.g. qtmdi.load(app, load_only={"mds-rounded-700", "mdf"}). This works with both lazy (only those prefixes become loadable on demand) and lazy=False (only those prefixes get loaded immediately).

Available Icons

To see available icons run qtmdi-browser in your terminal

qtmdi-browser

Development

This project uses uv for dependency management and packaging.

Font binaries under src/qtmdi/icons and src/qtmdi/brands aren't committed to git (they're fetched fresh at build/CI time to keep the repo small) - after cloning, run the fetch scripts once to populate them locally. fetch_fonts.py downloads the Material Symbols variable fonts straight from Google's material-design-icons repository and generates the per-weight static files with fonttools; fetch_brand_icons.py downloads the Simple Icons font + metadata from its GitHub Releases. Neither needs npm/node/woff2:

# install dependencies (including dev tools)
uv sync

# fetch the fonts (one-time, or whenever you want the latest icons)
uv run python scripts/fetch_fonts.py
uv run python scripts/fetch_brand_icons.py
uv run python scripts/fix_font_families.py
uv run python scripts/create_symbols_charmap.py

# run the test suite
uv run pytest

# lint
uv run ruff check
uv run flake8 .

# launch the icon browser against your local checkout
uv run qtmdi-browser

Font binaries are refreshed automatically by the symbols-update workflow (via scripts/fetch_fonts.py and scripts/fetch_brand_icons.py), which also fixes the Material Symbols fonts' internal family names so weight/style selection resolves correctly in Qt (scripts/fix_font_families.py), regenerates icons/charmap.json (scripts/create_symbols_charmap.py), and writes manifest.json - a checksum of every font file, committed instead of the binaries themselves, so the workflow can tell whether the fonts actually changed and only cut a release when they did (scripts/write_font_manifest.py). You normally shouldn't need to touch any of these by hand.

Known issues

  • Filled icons not shown as expected
  • Grade property currently unsupported
  • Optical size property currently unsupported

License

Fonts bundled by QtMDi itself (mdf, mds, si)

Fonts available transitively through the QtAwesome dependency

QtMDi doesn't bundle the fonts below itself - they ship as part of the qtawesome package (a QtMDi dependency), which carries its own licensing for them; they're listed here only because QtMDi's load()/qtawesome.icon() gives you access to their prefixes too.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qtmdi-2.0.1.tar.gz (33.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qtmdi-2.0.1-py3-none-any.whl (33.7 MB view details)

Uploaded Python 3

File details

Details for the file qtmdi-2.0.1.tar.gz.

File metadata

  • Download URL: qtmdi-2.0.1.tar.gz
  • Upload date:
  • Size: 33.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for qtmdi-2.0.1.tar.gz
Algorithm Hash digest
SHA256 e523b6722bb851ca7bad255b205362324c4a8c6d6e00a7a9896e63a13aabf18d
MD5 8c96215c47d04164ff758ffabc5d5dd3
BLAKE2b-256 96b0a095b00344a3512ad82c3067af1cd93fe06eb3563b7e94dc61f656789517

See more details on using hashes here.

File details

Details for the file qtmdi-2.0.1-py3-none-any.whl.

File metadata

  • Download URL: qtmdi-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 33.7 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for qtmdi-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 19fbd5c4c1075516c5a94eadf7a3f57dfbc978e9ae3f3b8b34113c97a8ab47bd
MD5 644d7fa052929f4a9bacbd5902affe0d
BLAKE2b-256 ee862024731c56356d8c66ddbdc927ffa5b1eae391014e9d5643fc2c7bec50d8

See more details on using hashes here.

Release history Release notifications | RSS feed

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page