Skip to content

Commit

Permalink
match color to palette in qt
Browse files Browse the repository at this point in the history
  • Loading branch information
tlambert03 committed Oct 10, 2023
1 parent c991ce0 commit b3a29ec
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 9 deletions.
38 changes: 33 additions & 5 deletions src/magicgui/backends/_qtpy/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
from qtpy.QtGui import (
QFont,
QFontMetrics,
QIcon,
QImage,
QKeyEvent,
QPalette,
QPixmap,
QResizeEvent,
QTextDocument,
Expand Down Expand Up @@ -48,10 +50,13 @@ def _signals_blocked(obj: QtW.QWidget) -> Iterator[None]:
class EventFilter(QObject):
parentChanged = Signal()
valueChanged = Signal(object)
paletteChanged = Signal()

def eventFilter(self, obj: QObject, event: QEvent) -> bool:
if event.type() == QEvent.Type.ParentChange:
self.parentChanged.emit()
if event.type() == QEvent.Type.PaletteChange:
self.paletteChanged.emit()
return False


Expand Down Expand Up @@ -426,6 +431,8 @@ class QBaseButtonWidget(

def __init__(self, qwidg: type[QtW.QAbstractButton], **kwargs: Any) -> None:
super().__init__(qwidg, "isChecked", "setChecked", "toggled", **kwargs)
self._event_filter.paletteChanged.connect(self._update_icon)
self._icon: tuple[str | None, str | None] | None = None

def _mgui_set_text(self, value: str) -> None:
"""Set text."""
Expand All @@ -435,15 +442,36 @@ def _mgui_get_text(self) -> str:
"""Get text."""
return self._qwidget.text()

def _mgui_set_icon(self, value: str, color: str | None) -> None:
self._qwidget.setIcon(superqt.QIconifyIcon(value, color=color))
def _update_icon(self) -> None:
# Called when palette changes or icon is set
if self._icon is None:
return

value, color = self._icon
if not value:
self._qwidget.setIcon(QIcon())
return

if not color or color == "auto":
# use foreground color
pal = self._qwidget.palette()
color = pal.color(QPalette.ColorRole.WindowText).name()

try:
self._qwidget.setIcon(superqt.QIconifyIcon(value, color=color))
except (OSError, ValueError) as e:
warnings.warn(f"Could not set iconify icon: {e}", stacklevel=2)
self._icon = None # don't try again

def _mgui_set_icon(self, value: str | None, color: str | None) -> None:
self._icon = (value, color)
self._update_icon()


class PushButton(QBaseButtonWidget):
def __init__(self, **kwargs: Any) -> None:
QBaseValueWidget.__init__(
self, QtW.QPushButton, "isChecked", "setChecked", "clicked", **kwargs
)
super().__init__(QtW.QPushButton, **kwargs)
self._onchange_name = "clicked"
# make enter/return "click" the button when focused.
self._qwidget.setAutoDefault(True)

Expand Down
4 changes: 2 additions & 2 deletions src/magicgui/widgets/bases/_button_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,5 @@ def clicked(self) -> SignalInstance:
"""Alias for changed event."""
return self.changed

def set_icon(self, value: str, color: str | None) -> None:
self._widget._mgui_set_icon(str(value), color)
def set_icon(self, value: str | None, color: str | None = None) -> None:
self._widget._mgui_set_icon(value, color)
9 changes: 7 additions & 2 deletions src/magicgui/widgets/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,13 @@ class SupportsIcon(Protocol):
"""Widget that can be reoriented."""

@abstractmethod
def _mgui_set_icon(self, value: str, color: str | None) -> None:
"""Set icon. Value is a font-awesome v5 icon name."""
def _mgui_set_icon(self, value: str | None, color: str | None) -> None:
"""Set icon.
Value is an "prefix:name" from iconify: https://icon-sets.iconify.design
Color is any valid CSS color string.
Set value to `None` or an empty string to remove icon.
"""


@runtime_checkable
Expand Down

0 comments on commit b3a29ec

Please sign in to comment.