Skip to content
13 changes: 6 additions & 7 deletions demo/model_app.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from typing import List

from fonticon_fa6 import FA6S
from qtpy.QtCore import QFile, QFileInfo, QSaveFile, Qt, QTextStream
from qtpy.QtWidgets import QApplication, QFileDialog, QMessageBox, QTextEdit

Expand Down Expand Up @@ -160,7 +159,7 @@ class CommandId:
ACTIONS: List[types.Action] = [
types.Action(
id="new_file",
icon=FA6S.file_circle_plus,
icon="fa6-solid:file-circle-plus",
title="New",
keybindings=[types.StandardKeyBinding.New],
status_tip="Create a new file",
Expand All @@ -169,7 +168,7 @@ class CommandId:
),
types.Action(
id="open_file",
icon=FA6S.folder_open,
icon="fa6-solid:folder-open",
title="Open...",
keybindings=[types.StandardKeyBinding.Open],
status_tip="Open an existing file",
Expand All @@ -178,7 +177,7 @@ class CommandId:
),
types.Action(
id="save_file",
icon=FA6S.floppy_disk,
icon="fa6-solid:floppy-disk",
title="Save",
keybindings=[types.StandardKeyBinding.Save],
status_tip="Save the document to disk",
Expand All @@ -203,7 +202,7 @@ class CommandId:
),
types.Action(
id="cut",
icon=FA6S.scissors,
icon="fa6-solid:scissors",
title="Cut",
keybindings=[types.StandardKeyBinding.Cut],
enablement="copyAvailable",
Expand All @@ -213,7 +212,7 @@ class CommandId:
),
types.Action(
id="copy",
icon=FA6S.copy,
icon="fa6-solid:copy",
title="Copy",
keybindings=[types.StandardKeyBinding.Copy],
enablement="copyAvailable",
Expand All @@ -223,7 +222,7 @@ class CommandId:
),
types.Action(
id="paste",
icon=FA6S.paste,
icon="fa6-solid:paste",
title="Paste",
keybindings=[types.StandardKeyBinding.Paste],
status_tip="Paste the clipboard's contents into the current selection",
Expand Down
16 changes: 7 additions & 9 deletions demo/multi_file/actions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from typing import List

from fonticon_fa6 import FA6S

from app_model.types import Action, KeyBindingRule, KeyCode, KeyMod, MenuRule

from . import functions
Expand All @@ -11,31 +9,31 @@
Action(
id=CommandId.OPEN,
title="Open",
icon=FA6S.folder_open,
icon="fa6-solid:folder-open",
callback=functions.open_file,
menus=[MenuRule(id=MenuId.FILE)],
keybindings=[KeyBindingRule(primary=KeyMod.CtrlCmd | KeyCode.KeyO)],
),
Action(
id=CommandId.CLOSE,
title="Close",
icon=FA6S.window_close,
icon="fa6-solid:window-close",
callback=functions.close,
menus=[MenuRule(id=MenuId.FILE)],
keybindings=[KeyBindingRule(primary=KeyMod.CtrlCmd | KeyCode.KeyW)],
),
Action(
id=CommandId.UNDO,
title="Undo",
icon=FA6S.undo,
icon="fa6-solid:undo",
callback=functions.undo,
menus=[MenuRule(id=MenuId.EDIT, group="1_undo_redo")],
keybindings=[KeyBindingRule(primary=KeyMod.CtrlCmd | KeyCode.KeyZ)],
),
Action(
id=CommandId.REDO,
title="Redo",
icon=FA6S.rotate_right,
icon="fa6-solid:rotate-right",
callback=functions.redo,
menus=[MenuRule(id=MenuId.EDIT, group="1_undo_redo")],
keybindings=[
Expand All @@ -45,23 +43,23 @@
Action(
id=CommandId.CUT,
title="Cut",
icon=FA6S.cut,
icon="fa6-solid:cut",
callback=functions.cut,
menus=[MenuRule(id=MenuId.EDIT, group="3_copypaste")],
keybindings=[KeyBindingRule(primary=KeyMod.CtrlCmd | KeyCode.KeyX)],
),
Action(
id=CommandId.COPY,
title="Copy",
icon=FA6S.copy,
icon="fa6-solid:copy",
callback=functions.copy,
menus=[MenuRule(id=MenuId.EDIT, group="3_copypaste")],
keybindings=[KeyBindingRule(primary=KeyMod.CtrlCmd | KeyCode.KeyC)],
),
Action(
id=CommandId.PASTE,
title="Paste",
icon=FA6S.paste,
icon="fa6-solid:paste",
callback=functions.paste,
menus=[MenuRule(id=MenuId.EDIT, group="3_copypaste")],
keybindings=[KeyBindingRule(primary=KeyMod.CtrlCmd | KeyCode.KeyV)],
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ dependencies = [
[project.optional-dependencies]
test = ["pytest>=6.0", "pytest-cov"]
test-qt = ["pytest-qt", "fonticon-fontawesome6"]
qt = ["qtpy", "superqt"]
qt = ["qtpy", "superqt[iconify]"]
dev = [
"black",
"ipython",
Expand Down
5 changes: 3 additions & 2 deletions src/app_model/backends/qt/_qaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
cast,
)

from qtpy.QtWidgets import QAction

from app_model import Application
from app_model.expressions import Expr
from app_model.types import ToggleRule
Expand All @@ -23,9 +21,12 @@
from ._util import to_qicon

if TYPE_CHECKING:
from PyQt6.QtGui import QAction
from qtpy.QtCore import QObject

from app_model.types import CommandRule, MenuItem
else:
from qtpy.QtWidgets import QAction


class QCommandAction(QAction):
Expand Down
7 changes: 5 additions & 2 deletions src/app_model/backends/qt/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@

def to_qicon(icon: Icon, theme: Literal["dark", "light"] = "dark") -> QIcon:
"""Create QIcon from Icon."""
from superqt import fonticon
from superqt import QIconifyIcon, fonticon

if icn := getattr(icon, theme, ""):
return fonticon.icon(icn)
if ":" in icn:
return QIconifyIcon(icn)
else:
return fonticon.icon(icn)
return QIcon() # pragma: no cover
5 changes: 4 additions & 1 deletion src/app_model/types/_command_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ class CommandRule(_BaseModel):
icon: Optional[Icon] = Field(
None,
description="(Optional) Icon used to represent this command, e.g. on buttons "
"or in menus. These may be superqt fonticon keys, such as `fa6s.arrow_down`",
"or in menus. These may be [iconify keys](https://icon-sets.iconify.design), "
"such as `fa6-solid:arrow-down`, or "
"[superqt.fonticon](https://pyapp-kit.github.io/superqt/utilities/fonticon/)"
" keys, such as `fa6s.arrow_down`",
)
enablement: Optional[expressions.Expr] = Field(
None,
Expand Down
14 changes: 10 additions & 4 deletions src/app_model/types/_icon.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,19 @@ class Icon(_BaseModel):

dark: Optional[str] = Field(
None,
description="Icon path when a dark theme is used. These may be superqt "
"fonticon keys, such as `fa6s.arrow_down`",
description="Icon path when a dark theme is used. These may be "
"[iconify keys](https://icon-sets.iconify.design), such as "
"`fa6-solid:arrow-down`, or "
"[superqt.fonticon](https://pyapp-kit.github.io/superqt/utilities/fonticon/)"
" keys, such as `fa6s.arrow_down`",
)
light: Optional[str] = Field(
None,
description="Icon path when a light theme is used. These may be superqt "
"fonticon keys, such as `fa6s.arrow_down`",
description="Icon path when a light theme is used. These may be "
"[iconify keys](https://icon-sets.iconify.design), such as "
"`fa6-solid:arrow-down`, or "
"[superqt.fonticon](https://pyapp-kit.github.io/superqt/utilities/fonticon/)"
" keys, such as `fa6s.arrow_down`",
)

@classmethod
Expand Down
5 changes: 4 additions & 1 deletion src/app_model/types/_menu_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,10 @@ class SubmenuItem(_MenuItemBase):
icon: Optional[Icon] = Field(
None,
description="(Optional) Icon used to represent this submenu. "
"These may be superqt fonticon keys, such as `fa6s.arrow_down`",
"These may be [iconify keys](https://icon-sets.iconify.design), "
"such as `fa6-solid:arrow-down`, or "
"[superqt.fonticon](https://pyapp-kit.github.io/superqt/utilities/fonticon/)"
" keys, such as `fa6s.arrow_down`",
)
enablement: Optional[expressions.Expr] = Field(
None,
Expand Down
6 changes: 3 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

UNDO_ICON = FA6S.rotate_left
except ImportError:
UNDO_ICON = "fa6s.undo"
UNDO_ICON = "fa6-solid:undo"

FIXTURES = Path(__file__).parent / "fixtures"

Expand Down Expand Up @@ -113,7 +113,7 @@ def build_app(name: str = "complete_test_app") -> FullApp:
Action(
id=Commands.COPY,
title="Copy",
icon="fa6s.copy",
icon="fa6-solid:copy", # iconify font style works too
callback=app.mocks.copy,
menus=[{"id": Menus.EDIT, "group": "2_copy_paste"}],
keybindings=[{"primary": KeyMod.CtrlCmd | KeyCode.KeyC}],
Expand All @@ -131,7 +131,7 @@ def build_app(name: str = "complete_test_app") -> FullApp:
id=Commands.REDO,
title="Redo",
tooltip="Redo it!",
icon="fa6s.rotate_right",
icon="fa6-solid:rotate-right",
enablement="allow_undo_redo",
callback="fake_module:run_me", # this is a function in fixtures
keybindings=[{"primary": "Ctrl+Shift+Z"}],
Expand Down
2 changes: 0 additions & 2 deletions tests/test_qt/test_qactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
from app_model.types import Action, MenuItem, ToggleRule

if TYPE_CHECKING:
pass

from app_model import Application
from conftest import FullApp

Expand Down