Skip to content

fxutils

Utility functions for the fxgui package.

Qt helpers every widget and application shares: UI loading, actions, shadows, menus, trees, window corners and wrapper lifetimes.

Examples:

>>> from fxgui.fxutils import load_ui
>>> ui = load_ui(parent_widget, "path/to/ui_file.ui")

Classes:

Name Description
TreeState

What is open, selected and current in a tree, named by row text.

Functions:

Name Description
add_shadow

Cast the theme's drop shadow under widget; it follows every switch.

add_submenu

Add and return a submenu titled label, owned by menu in C++.

children_of

Yield every child row of item.

create_action

Create a QAction owned by parent.

filter_tree

Tell mark for every row of tree whether text keeps it.

fit_columns

Widen each column to its widest row, collapsed rows too; never narrow.

focus_step

Return the widget after widget in the focus chain, or before it.

later

Run call once after ms milliseconds, unless owner died first.

load_ui

Load a Qt Designer UI file as a new widget parented to parent.

markdown_to_plain_text

Return text with its Markdown formatting removed.

popup_menu

Show menu at global position at, freeing it once it closes.

rehome

Give widget's Python wrapper back to its own parent's; return it.

repolish

Force re-evaluation of the stylesheet rules for a widget.

round_window_corners

Give widget's own window the corners and shadow of a flyout.

set_app_user_model_id

Tell Windows this process is its own application, app_id.

Classes

TreeState dataclass

TreeState(
    expanded: Tuple[_RowPath, ...] = (),
    selected: Tuple[_RowPath, ...] = (),
    current: Optional[_RowPath] = None,
    scroll: int = 0,
)

What is open, selected and current in a tree, named by row text.

Text survives a tree that is cleared and refilled; items do not.

Examples:

>>> state = fxutils.TreeState.of(tree)
>>> refill(tree)
>>> state.restore(tree)

Methods:

Name Description
of

Return what is open, selected and current in tree now.

restore

Put this state back on tree, skipping rows it no longer has.

Methods:

of classmethod
of(tree: QTreeWidget) -> TreeState

Return what is open, selected and current in tree now.

restore
restore(tree: QTreeWidget) -> None

Put this state back on tree, skipping rows it no longer has.

Focus goes before selection, since Qt selects what it focuses, and scroll goes last, since focusing scrolls.

Functions:

add_shadow

add_shadow(
    widget: QWidget, offset: Tuple[float, float] = (0, 0)
) -> QGraphicsDropShadowEffect

Cast the theme's drop shadow under widget; it follows every switch.

Examples:

>>> fxutils.add_shadow(card, offset=(0, 4))

add_submenu

add_submenu(menu: QMenu, label: str, before: Optional[QAction] = None) -> QMenu

Add and return a submenu titled label, owned by menu in C++.

menu.addMenu(label) makes one that dies with the first dropped Python wrapper of its action.

Parameters:

Name Type Description Default

before

Optional[QAction]

The item the submenu goes ahead of; the end when omitted.

None

children_of

children_of(item: QTreeWidgetItem) -> Iterator[QTreeWidgetItem]

Yield every child row of item.

create_action

create_action(
    parent: QWidget,
    name: str,
    trigger: Optional[Callable] = None,
    enable: bool = True,
    shortcut: Optional[str] = None,
    checkable: bool = False,
    icon_name: Optional[str] = None,
) -> QAction

Create a QAction owned by parent.

Parameters:

Name Type Description Default

parent

QWidget

Parent widget for the action.

required

name

str

Display name for the action.

required

trigger

Optional[Callable]

Called when the action is triggered.

None

enable

bool

Whether the action is enabled.

True

shortcut

Optional[str]

Keyboard shortcut (e.g., "Ctrl+S").

None

checkable

bool

Whether the action is checkable.

False

icon_name

Optional[str]

An fxicons name, drawn in the theme's colours.

None

Examples:

>>> action = create_action(
...     window, "Save", trigger=save, shortcut="Ctrl+S",
...     icon_name="save")

filter_tree

filter_tree(
    tree: QTreeWidget,
    text: str,
    mark: Callable[[QTreeWidgetItem, bool], None] = _hide_unless,
) -> None

Tell mark for every row of tree whether text keeps it.

A row matches when any column holds text, ignoring case; empty text matches every row. A match keeps its whole subtree and its ancestors.

Parameters:

Name Type Description Default

tree

QTreeWidget

The tree to walk, top level down.

required

text

str

The text to find.

required

mark

Callable[[QTreeWidgetItem, bool], None]

Called with each row and its verdict; the default hides the rows the text drops.

_hide_unless

fit_columns

fit_columns(view: QTreeView) -> None

Widen each column to its widest row, collapsed rows too; never narrow.

resizeColumnToContents measures only the rows that are expanded.

focus_step

focus_step(widget, forward: bool = True)

Return the widget after widget in the focus chain, or before it.

later

later(ms: int, owner, call) -> None

Run call once after ms milliseconds, unless owner died first.

Stands in for QTimer.singleShot(ms, owner, call), which Houdini 21's PySide6 6.5 lacks. Call it on owner's thread: the timer is its child.

load_ui

load_ui(parent: QWidget, ui_file: str) -> QWidget

Load a Qt Designer UI file as a new widget parented to parent.

Raises:

Type Description
FileNotFoundError

If the specified UI file doesn't exist.

Examples:

>>> loaded_ui = load_ui(self, Path(__file__).with_suffix(".ui"))

markdown_to_plain_text cached

markdown_to_plain_text(text: str) -> str

Return text with its Markdown formatting removed.

Without the optional markdown package the text is returned as is.

popup_menu

popup_menu(menu: QMenu, at: QPoint) -> None

Show menu at global position at, freeing it once it closes.

popup rather than exec, whose own event loop no key-driven test can step through; a parented menu is never freed, so aboutToHide frees it.

rehome

rehome(widget)

Give widget's Python wrapper back to its own parent's; return it.

PySide files a widget a getter returns under the widget asked, and kills that one's wrapped children when it dies. Qt skips a setParent to the same parent; the binding files the wrapper back. A parent only C++ made is filed first, up to one Python made.

repolish

repolish(widget: QWidget) -> None

Force re-evaluation of the stylesheet rules for a widget.

Call after changing a Qt dynamic property that a stylesheet attribute selector depends on, e.g. MyBanner[level="error"] { ... }.

Parameters:

Name Type Description Default

widget

QWidget

The widget to unpolish/polish and repaint.

required

Examples:

>>> banner.setProperty("level", "error")
>>> fxutils.repolish(banner)

round_window_corners

round_window_corners(widget: QWidget) -> bool

Give widget's own window the corners and shadow of a flyout.

One DwmSetWindowAttribute call on Windows 11: the compositor clips and shades the window, and its geometry does not change. Nothing raises.

Parameters:

Name Type Description Default

widget

QWidget

A window; asking a child for its handle would make it native.

required

Returns:

Name Type Description
bool bool

Whether the compositor took the request; False off Windows 11.

Examples:

>>> fxutils.round_window_corners(panel)
True

set_app_user_model_id

set_app_user_model_id(app_id: str) -> bool

Tell Windows this process is its own application, app_id.

Windows groups taskbar buttons and picks their icon by this id, so a Python-run application otherwise wears the Python icon. Call before the first window exists: Windows reads the id when a window is made. A pinned shortcut must carry the same id. Nothing here raises.

Parameters:

Name Type Description Default

app_id

str

A machine-wide id, such as "Studio.Launcher".

required

Returns:

Name Type Description
bool bool

Whether Windows took it; always False off Windows.

Examples:

>>> fxutils.set_app_user_model_id("Studio.App")
True