Skip to content

Commit e60e9c4

Browse files
refactor: remove mdi6 fonticon dependency (#437)
* ci(pre-commit.ci): autoupdate updates: - [github.com/crate-ci/typos: v1.32.0 → v1](crate-ci/typos@v1.32.0...v1) - [github.com/astral-sh/ruff-pre-commit: v0.11.8 → v0.11.12](astral-sh/ruff-pre-commit@v0.11.8...v0.11.12) - [github.com/pre-commit/mirrors-mypy: v1.15.0 → v1.16.0](pre-commit/mirrors-mypy@v1.15.0...v1.16.0) * refactor: remove fonticons * fix docstring * update pre-commit * update pymmcore-plus typing * fix: fix property widget for pymmcore-plus 0.15.0 --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 824588d commit e60e9c4

26 files changed

Lines changed: 180 additions & 194 deletions

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ classifiers = [
4848
]
4949
dynamic = ["version"]
5050
dependencies = [
51-
'fonticon-materialdesignicons6 >=6.9.96',
5251
'pymmcore-plus[cli] >=0.14.0',
5352
'qtpy >=2.0',
5453
'superqt[quantity,cmap,iconify] >=0.7.1',

src/pymmcore_widgets/_icons.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
from __future__ import annotations
22

3-
from fonticon_mdi6 import MDI6
43
from pymmcore_plus import DeviceType
54

65
ICONS: dict[DeviceType, str] = {
7-
DeviceType.Any: MDI6.devices,
8-
DeviceType.AutoFocus: MDI6.auto_upload,
9-
DeviceType.Camera: MDI6.camera,
10-
DeviceType.Core: MDI6.checkbox_blank_circle_outline,
11-
DeviceType.Galvo: MDI6.mirror_variant,
12-
DeviceType.Generic: MDI6.dev_to,
13-
DeviceType.Hub: MDI6.hubspot,
14-
DeviceType.ImageProcessor: MDI6.image_auto_adjust,
15-
DeviceType.Magnifier: MDI6.magnify_plus,
16-
DeviceType.Shutter: MDI6.camera_iris,
17-
DeviceType.SignalIO: MDI6.signal,
18-
DeviceType.SLM: MDI6.view_comfy,
19-
DeviceType.Stage: MDI6.arrow_up_down,
20-
DeviceType.State: MDI6.state_machine,
21-
DeviceType.Unknown: MDI6.dev_to,
22-
DeviceType.XYStage: MDI6.arrow_all,
23-
DeviceType.Serial: MDI6.serial_port,
6+
DeviceType.Any: "mdi:devices",
7+
DeviceType.AutoFocus: "mdi:auto-upload",
8+
DeviceType.Camera: "mdi:camera",
9+
DeviceType.Core: "mdi:checkbox-blank-circle-outline",
10+
DeviceType.Galvo: "mdi:mirror-variant",
11+
DeviceType.Generic: "mdi:dev-to",
12+
DeviceType.Hub: "mdi:hubspot",
13+
DeviceType.ImageProcessor: "mdi:image-auto-adjust",
14+
DeviceType.Magnifier: "mdi:magnify-plus",
15+
DeviceType.Shutter: "mdi:camera-iris",
16+
DeviceType.SignalIO: "mdi:signal",
17+
DeviceType.SLM: "mdi:view-comfy",
18+
DeviceType.Stage: "mdi:arrow-up-down",
19+
DeviceType.State: "mdi:state-machine",
20+
DeviceType.Unknown: "mdi:dev-to",
21+
DeviceType.XYStage: "mdi:arrow-all",
22+
DeviceType.Serial: "mdi:serial-port",
2423
}

src/pymmcore_widgets/control/_camera_roi_widget.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from dataclasses import dataclass
44
from typing import Any, NamedTuple
55

6-
from fonticon_mdi6 import MDI6
76
from pymmcore_plus import CMMCorePlus, DeviceType
87
from qtpy.QtCore import QSize, Qt, Signal
98
from qtpy.QtWidgets import (
@@ -21,7 +20,7 @@
2120
QVBoxLayout,
2221
QWidget,
2322
)
24-
from superqt.fonticon import icon
23+
from superqt.iconify import QIconifyIcon
2524
from superqt.utils import signals_blocked
2625

2726
fixed_sizepolicy = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
@@ -180,7 +179,7 @@ def __init__(
180179

181180
self.crop_btn = QPushButton("Crop")
182181
self.crop_btn.setMinimumWidth(100)
183-
self.crop_btn.setIcon(icon(MDI6.crop, color=(0, 255, 0)))
182+
self.crop_btn.setIcon(QIconifyIcon("mdi:crop", color="green"))
184183
self.crop_btn.setIconSize(QSize(30, 30))
185184

186185
_bottom_layout.addWidget(self.snap_checkbox)

src/pymmcore_widgets/control/_live_button_widget.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22

33
from typing import Union
44

5-
from fonticon_mdi6 import MDI6
65
from pymmcore_plus import CMMCorePlus
76
from qtpy.QtCore import QSize, Qt
87
from qtpy.QtGui import QColor
98
from qtpy.QtWidgets import QPushButton, QWidget
10-
from superqt.fonticon import icon
9+
from superqt.iconify import QIconifyIcon
1110

1211
COLOR_TYPE = Union[
1312
QColor,
@@ -57,7 +56,7 @@ def __init__(
5756
self._mmc = mmcore or CMMCorePlus.instance()
5857
self._button_text_on: str = "Live"
5958
self._button_text_off: str = "Stop"
60-
self._icon_color_on: COLOR_TYPE = (0, 255, 0)
59+
self._icon_color_on: COLOR_TYPE = "green"
6160
self._icon_color_off: COLOR_TYPE = "magenta"
6261

6362
self.streaming_timer = None
@@ -118,7 +117,7 @@ def icon_color_on(self) -> COLOR_TYPE:
118117
@icon_color_on.setter
119118
def icon_color_on(self, color: COLOR_TYPE) -> None:
120119
if not self._mmc.isSequenceRunning():
121-
self.setIcon(icon(MDI6.video_outline, color=color))
120+
self.setIcon(QIconifyIcon("mdi:video-outline", color=color))
122121
self._icon_color_on = color
123122

124123
@property
@@ -133,7 +132,7 @@ def icon_color_off(self) -> COLOR_TYPE:
133132
@icon_color_off.setter
134133
def icon_color_off(self, color: COLOR_TYPE) -> None:
135134
if self._mmc.isSequenceRunning():
136-
self.setIcon(icon(MDI6.video_off_outline, color=color))
135+
self.setIcon(QIconifyIcon("mdi:video-off-outline", color=color))
137136
self._icon_color_off = color
138137

139138
def _create_button(self) -> None:
@@ -158,10 +157,12 @@ def _toggle_live_mode(self) -> None:
158157
def _set_icon_state(self, state: bool) -> None:
159158
"""Set the icon in the on or off state."""
160159
if state: # set in the off mode
161-
self.setIcon(icon(MDI6.video_off_outline, color=self._icon_color_off))
160+
self.setIcon(
161+
QIconifyIcon("mdi:video-off-outline", color=self._icon_color_off)
162+
)
162163
self.setText(self._button_text_off)
163164
else: # set in the on mode
164-
self.setIcon(icon(MDI6.video_outline, color=self._icon_color_on))
165+
self.setIcon(QIconifyIcon("mdi:video-outline", color=self._icon_color_on))
165166
self.setText(self._button_text_on)
166167

167168
def _on_sequence_started(self) -> None:

src/pymmcore_widgets/control/_shutter_widget.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@
33
import warnings
44
from typing import Any, Union
55

6-
from fonticon_mdi6 import MDI6
76
from pymmcore_plus import CMMCorePlus, DeviceType
87
from qtpy.QtCore import QSize, Qt
98
from qtpy.QtGui import QColor
109
from qtpy.QtWidgets import QCheckBox, QHBoxLayout, QPushButton, QSizePolicy, QWidget
11-
from superqt.fonticon import icon
10+
from superqt.iconify import QIconifyIcon
1211
from superqt.utils import signals_blocked
1312

14-
GRAY = (183, 183, 183)
15-
GREEN = (0, 255, 0)
13+
GRAY = "gray"
14+
GREEN = "green"
1615

1716
COLOR_TYPE = Union[
1817
QColor,
@@ -60,8 +59,8 @@ def __init__(
6059
self._is_multiShutter = False
6160
self.autoshutter = autoshutter
6261

63-
self._icon_open: str = MDI6.hexagon_outline
64-
self._icon_closed: str = MDI6.hexagon_slice_6
62+
self._icon_open: str = "mdi:hexagon-outline"
63+
self._icon_closed: str = "mdi:hexagon-slice-6"
6564
self._icon_color_open: COLOR_TYPE = GREEN
6665
self._icon_color_closed: COLOR_TYPE = GRAY
6766
self._icon_size: int = 25
@@ -92,7 +91,7 @@ def icon_open(self) -> str:
9291
9392
The icon_open.setter icon string should be any key recognizable as
9493
a superqt fonticon (e.g. mdi6.abacus).
95-
Default = MDI6.hexagon_outline (https://github.com/templarian/MaterialDesign).
94+
Default = 'mdi:hexagon-outline' (https://github.com/templarian/MaterialDesign).
9695
Note that MDI6 is installed by default, you must install other fonts
9796
if you want to use them.
9897
"""
@@ -101,7 +100,9 @@ def icon_open(self) -> str:
101100
@icon_open.setter
102101
def icon_open(self, icon_o: str) -> None:
103102
if self._mmc.getShutterOpen(self.shutter_device):
104-
self.shutter_button.setIcon(icon(icon_o, color=self._icon_color_open))
103+
self.shutter_button.setIcon(
104+
QIconifyIcon(icon_o, color=self._icon_color_open)
105+
)
105106
self._icon_open = icon_o
106107

107108
@property
@@ -111,7 +112,7 @@ def icon_closed(self) -> str:
111112
112113
The icon_closed.setter icon string should be any key recognizable as
113114
a superqt fonticon (e.g. mdi6.abacus).
114-
Default = MDI6.hexagon_slice_6 (https://github.com/templarian/MaterialDesign).
115+
Default = 'mdi:hexagon-slice-6' (https://github.com/templarian/MaterialDesign).
115116
Note that MDI6 is installed by default, you must install other fonts
116117
if you want to use them.
117118
"""
@@ -120,15 +121,17 @@ def icon_closed(self) -> str:
120121
@icon_closed.setter
121122
def icon_closed(self, icon_c: str) -> None:
122123
if not self._mmc.getShutterOpen(self.shutter_device):
123-
self.shutter_button.setIcon(icon(icon_c, color=self._icon_color_closed))
124+
self.shutter_button.setIcon(
125+
QIconifyIcon(icon_c, color=self._icon_color_closed)
126+
)
124127
self._icon_closed = icon_c
125128

126129
@property
127130
def icon_color_open(self) -> COLOR_TYPE:
128131
"""
129132
Set the button icon color for when the shutter is open.
130133
131-
Default = (0, 255, 0)
134+
Default = "green"
132135
133136
COLOR_TYPE = Union[QColor, int, str, Qt.GlobalColor, tuple[int, int, int, int],
134137
tuple[int, int, int]]
@@ -138,7 +141,7 @@ def icon_color_open(self) -> COLOR_TYPE:
138141
@icon_color_open.setter
139142
def icon_color_open(self, color: COLOR_TYPE) -> None:
140143
if self._mmc.getShutterOpen(self.shutter_device):
141-
self.shutter_button.setIcon(icon(self._icon_open, color=color))
144+
self.shutter_button.setIcon(QIconifyIcon(self._icon_open, color=color))
142145
self._icon_color_open = color
143146

144147
@property
@@ -156,7 +159,7 @@ def icon_color_closed(self) -> COLOR_TYPE:
156159
@icon_color_closed.setter
157160
def icon_color_closed(self, color: COLOR_TYPE) -> None:
158161
if not self._mmc.getShutterOpen(self.shutter_device):
159-
self.shutter_button.setIcon(icon(self._icon_closed, color=color))
162+
self.shutter_button.setIcon(QIconifyIcon(self._icon_closed, color=color))
160163
self._icon_color_closed = color
161164

162165
@property
@@ -212,7 +215,7 @@ def _create_wdg(self) -> None:
212215
sizepolicy_btn = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
213216
self.shutter_button.setSizePolicy(sizepolicy_btn)
214217
self.shutter_button.setIcon(
215-
icon(self._icon_closed, color=self._icon_color_closed)
218+
QIconifyIcon(self._icon_closed, color=self._icon_color_closed)
216219
)
217220
self.shutter_button.setIconSize(QSize(self._icon_size, self._icon_size))
218221
self.shutter_button.clicked.connect(self._on_shutter_btn_clicked)
@@ -345,12 +348,14 @@ def _on_shutter_checkbox_toggled(self, state: bool) -> None:
345348

346349
def _set_shutter_wdg_to_opened(self) -> None:
347350
self.shutter_button.setText(self._button_text_open)
348-
self.shutter_button.setIcon(icon(self._icon_open, color=self._icon_color_open))
351+
self.shutter_button.setIcon(
352+
QIconifyIcon(self._icon_open, color=self._icon_color_open)
353+
)
349354

350355
def _set_shutter_wdg_to_closed(self) -> None:
351356
self.shutter_button.setText(self._button_text_closed)
352357
self.shutter_button.setIcon(
353-
icon(self._icon_closed, color=self._icon_color_closed)
358+
QIconifyIcon(self._icon_closed, color=self._icon_color_closed)
354359
)
355360

356361
def _disconnect(self) -> None:

src/pymmcore_widgets/control/_snap_button_widget.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22

33
from typing import Union
44

5-
from fonticon_mdi6 import MDI6
65
from pymmcore_plus import CMMCorePlus
76
from qtpy.QtCore import QSize, Qt
87
from qtpy.QtGui import QColor
98
from qtpy.QtWidgets import QPushButton, QSizePolicy, QWidget
10-
from superqt.fonticon import icon
9+
from superqt.iconify import QIconifyIcon
1110
from superqt.utils import create_worker
1211

1312
COLOR_TYPES = Union[
@@ -71,7 +70,7 @@ def __init__(
7170

7271
def _create_button(self) -> None:
7372
self.setText("Snap")
74-
self.setIcon(icon(MDI6.camera_outline, color=(0, 255, 0)))
73+
self.setIcon(QIconifyIcon("mdi:camera-outline", color="green"))
7574
self.setIconSize(QSize(30, 30))
7675
self.clicked.connect(self._snap)
7776

src/pymmcore_widgets/control/_stage_widget.py

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
from itertools import product
44
from typing import TYPE_CHECKING, cast
55

6-
from fonticon_mdi6 import MDI6
6+
from pyconify import svg_path
77
from pymmcore_plus import CMMCorePlus, DeviceType, Keyword
8-
from qtpy.QtCore import QEvent, QObject, Qt, QTimerEvent, Signal
8+
from qtpy.QtCore import QEvent, QObject, QSize, Qt, QTimerEvent, Signal
99
from qtpy.QtGui import QContextMenuEvent
1010
from qtpy.QtWidgets import (
1111
QCheckBox,
@@ -20,7 +20,7 @@
2020
QVBoxLayout,
2121
QWidget,
2222
)
23-
from superqt.fonticon import icon, setTextIcon
23+
from superqt.iconify import QIconifyIcon
2424
from superqt.utils import signals_blocked
2525

2626
from ._q_stage_controller import QStageMoveAccumulator
@@ -34,18 +34,18 @@
3434

3535
MOVE_BUTTONS: dict[str, tuple[int, int, int, int]] = {
3636
# btn glyph (r, c, xmag, ymag)
37-
MDI6.chevron_triple_up: (0, 3, 0, 3),
38-
MDI6.chevron_double_up: (1, 3, 0, 2),
39-
MDI6.chevron_up: (2, 3, 0, 1),
40-
MDI6.chevron_down: (4, 3, 0, -1),
41-
MDI6.chevron_double_down: (5, 3, 0, -2),
42-
MDI6.chevron_triple_down: (6, 3, 0, -3),
43-
MDI6.chevron_triple_left: (3, 0, -3, 0),
44-
MDI6.chevron_double_left: (3, 1, -2, 0),
45-
MDI6.chevron_left: (3, 2, -1, 0),
46-
MDI6.chevron_right: (3, 4, 1, 0),
47-
MDI6.chevron_double_right: (3, 5, 2, 0),
48-
MDI6.chevron_triple_right: (3, 6, 3, 0),
37+
"mdi:chevron-triple-up": (0, 3, 0, 3),
38+
"mdi:chevron-double-up": (1, 3, 0, 2),
39+
"mdi:chevron-up": (2, 3, 0, 1),
40+
"mdi:chevron-down": (4, 3, 0, -1),
41+
"mdi:chevron-double-down": (5, 3, 0, -2),
42+
"mdi:chevron-triple-down": (6, 3, 0, -3),
43+
"mdi:chevron-triple-left": (3, 0, -3, 0),
44+
"mdi:chevron-double-left": (3, 1, -2, 0),
45+
"mdi:chevron-left": (3, 2, -1, 0),
46+
"mdi:chevron-right": (3, 4, 1, 0),
47+
"mdi:chevron-double-right": (3, 5, 2, 0),
48+
"mdi:chevron-triple-right": (3, 6, 3, 0),
4949
}
5050

5151

@@ -58,21 +58,20 @@ def __init__(self, glyph: str, xmag: int, ymag: int, parent: QWidget | None = No
5858
self.setFlat(True)
5959
self.setFocusPolicy(Qt.FocusPolicy.NoFocus)
6060
self.setCursor(Qt.CursorShape.PointingHandCursor)
61-
setTextIcon(self, glyph)
6261
self.setStyleSheet(
63-
"""
64-
MoveStageButton {
62+
f"""
63+
MoveStageButton {{
6564
border: none;
6665
background: transparent;
67-
color: rgb(0, 180, 0);
66+
image: url({svg_path(glyph, color="rgb(0, 180, 0)")});
6867
font-size: 36px;
69-
}
70-
MoveStageButton:hover:!pressed {
71-
color: rgb(0, 255, 0);
72-
}
73-
MoveStageButton:pressed {
74-
color: rgb(0, 100, 0);
75-
}
68+
}}
69+
MoveStageButton:hover:!pressed {{
70+
image: url({svg_path(glyph, color="lime")});
71+
}}
72+
MoveStageButton:pressed {{
73+
image: url({svg_path(glyph, color="green")});
74+
}}
7675
"""
7776
)
7877

@@ -107,7 +106,8 @@ def __init__(self, device: str, core: CMMCorePlus, parent: QWidget | None = None
107106
super().__init__(parent=parent)
108107
self._device = device
109108
self._core = core
110-
self.setIcon(icon(MDI6.close_octagon, color=(255, 0, 0)))
109+
self.setIcon(QIconifyIcon("bi:sign-stop-fill", color="red"))
110+
self.setIconSize(QSize(24, 24))
111111
self.setToolTip("Halt stage movement")
112112
self.setText("STOP!")
113113
self.clicked.connect(self._on_clicked)

src/pymmcore_widgets/device_properties/_device_property_table.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from qtpy.QtCore import Qt
88
from qtpy.QtGui import QColor
99
from qtpy.QtWidgets import QAbstractScrollArea, QTableWidget, QTableWidgetItem, QWidget
10-
from superqt.fonticon import icon
10+
from superqt.iconify import QIconifyIcon
1111

1212
from pymmcore_widgets._icons import ICONS
1313
from pymmcore_widgets._util import NoWheelTableWidget
@@ -130,7 +130,7 @@ def _rebuild_table(self) -> None:
130130
item = QTableWidgetItem(f"{prop.device}-{prop.name}{extra}")
131131
item.setData(self.PROP_ROLE, prop)
132132
if icon_string := ICONS.get(prop.deviceType()):
133-
item.setIcon(icon(icon_string, color="Gray"))
133+
item.setIcon(QIconifyIcon(icon_string, color="Gray"))
134134
self.setItem(i, 0, item)
135135

136136
try:

0 commit comments

Comments
 (0)