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.5.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.5-py3-none-any.whl (33.7 MB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: qtmdi-2.0.5.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.5.tar.gz
Algorithm Hash digest
SHA256 7f1937be627606fd314927b223fd1fa95b5fa7ba66a8e7282014fb5f855d2ef1
MD5 f49350adc5d9d592ebec49d7426f5496
BLAKE2b-256 4530d0d9d1739055d4fae1654f19587d0473d43fa57ef073702ddb0930995b51

See more details on using hashes here.

File details

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

File metadata

  • Download URL: qtmdi-2.0.5-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.5-py3-none-any.whl
Algorithm Hash digest
SHA256 e1b16b4004bfc2ba450d817a9d4800657f01efe57741cd0e148b4dfa8e51838b
MD5 2a4c5844dbc9e83ad3900d88915c21bb
BLAKE2b-256 aa43bb707795b231521db48871e0bb4d715af5a9e300af3c271a6b80426ac68e

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