-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0f0542f
commit a8f0e4c
Showing
4 changed files
with
108 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from pyconify.qt import QIconify | ||
from qtpy.QtCore import QSize | ||
from qtpy.QtWidgets import QApplication, QPushButton | ||
|
||
app = QApplication([]) | ||
|
||
btn = QPushButton() | ||
icon = QIconify("iconamoon:3d-fill", color="cornflowerblue") | ||
btn.setIcon(icon) | ||
btn.setIconSize(QSize(30, 30)) | ||
btn.show() | ||
|
||
app.exec() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
from collections import defaultdict | ||
from pathlib import Path | ||
|
||
|
||
def update_type_hints(): | ||
from pyconify import api | ||
|
||
collections = api.collections() | ||
all_icons: defaultdict[str, set[str]] = defaultdict(set) | ||
|
||
for prefix in list(collections)[:1]: | ||
icons = api.collection(prefix) | ||
for icon_list in icons.get("categories", {}).values(): | ||
all_icons[prefix].update(icon_list) | ||
all_icons[prefix].update(icons.get("uncategorized", [])) | ||
|
||
module = "from typing import Literal\n\n" | ||
|
||
keys = [ | ||
f'"{prefix}:{name}"' | ||
for prefix, names in sorted(all_icons.items()) | ||
for name in sorted(names) | ||
] | ||
inner = ",\n ".join(keys) | ||
module += f"IconName = Literal[\n {inner}\n]\n" | ||
Path(__file__).parent.joinpath("_typing.py").write_text(module) | ||
|
||
|
||
update_type_hints() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
"""A Class for generating QIcons from SVGs with arbitrary colors at runtime.""" | ||
from typing import Literal | ||
|
||
from qtpy.QtCore import QByteArray, QPoint, QRect, QRectF, Qt | ||
from qtpy.QtGui import QIcon, QIconEngine, QImage, QPainter, QPixmap | ||
from qtpy.QtSvg import QSvgRenderer | ||
|
||
from pyconify.api import svg | ||
|
||
|
||
class QIconify(QIcon): | ||
def __init__( | ||
self, | ||
*key: str, | ||
color: str | None = None, | ||
flip: Literal["horizontal", "vertical", "horizontal,vertical"] | None = None, | ||
rotate: str | int | None = None, | ||
) -> None: | ||
if len(key) == 1: | ||
if ":" in key[0]: | ||
prefix, name = key[0].split(":") | ||
else: | ||
raise ValueError( | ||
"If only one argument is passed, it must be in the format " | ||
"'prefix:name'" | ||
) | ||
elif len(key) == 2: | ||
prefix, name = key | ||
else: | ||
raise ValueError( | ||
"QIconify must be initialized with either 1 or 2 arguments." | ||
) | ||
svg_bytes = svg(prefix, name, color=color, flip=flip, rotate=rotate) | ||
super().__init__(SVGBufferIconEngine(svg_bytes)) | ||
|
||
|
||
class SVGBufferIconEngine(QIconEngine): | ||
"""A custom QIconEngine that can render an SVG buffer.""" | ||
|
||
def __init__(self, xml: bytes | str | QByteArray) -> None: | ||
if isinstance(xml, str): | ||
xml = xml.encode("utf-8") | ||
self._data = QByteArray(xml) | ||
self._renderer = QSvgRenderer(self._data) | ||
self._renderer.setFramesPerSecond(20) | ||
super().__init__() | ||
|
||
def paint(self, painter: QPainter, rect, mode, state): | ||
"""Paint the icon in `rect` using `painter`.""" | ||
self._renderer.render(painter, QRectF(rect)) | ||
|
||
def clone(self): | ||
"""Required to subclass abstract QIconEngine.""" | ||
return SVGBufferIconEngine(self._data) | ||
|
||
def pixmap(self, size, mode, state): | ||
"""Return the icon as a pixmap with requested size, mode, and state.""" | ||
img = QImage(size, QImage.Format.Format_ARGB32) | ||
img.fill(Qt.GlobalColor.transparent) | ||
pixmap = QPixmap.fromImage(img, Qt.ImageConversionFlag.NoFormatConversion) | ||
painter = QPainter(pixmap) | ||
self.paint(painter, QRect(QPoint(0, 0), size), mode, state) | ||
return pixmap |