fxwidgets
¶
The fxgui widgets, each in its own private module, exported here.
Classes:
| Name | Description |
|---|---|
FXAccordion |
A multi-section collapsible accordion widget. |
FXApplication |
Customized QApplication class. |
FXAvatar |
A circle showing a person's photo, or their initials on a disc. |
FXBreadcrumb |
A path of clickable segments, with optional back and forward. |
FXCamelCaseValidator |
Accept camelCase letters: a lowercase start, no digits or symbols. |
FXCapitalizedLetterValidator |
Accept letters only; |
FXCheckableComboBox |
A combo whose popup stays open while several rows are ticked. |
FXCodeBlock |
A read-only code block with syntax highlighting and theme styling. |
FXCollapsibleWidget |
A header that slides its content open and shut on a click. |
FXCommand |
One row of the palette, and what picking it does. |
FXCommandPalette |
A frameless popup over |
FXCommandRow |
A toolbar fixed in place: no handle, no floating, nothing to hide it. |
FXConfirmDeleteDialog |
Ask for a word, typed exactly, before an act with no undo. |
FXDropZone |
A drag and drop zone widget for file and folder selection. |
FXElidedLabel |
A QLabel that cuts its text with an ellipsis when it does not fit. |
FXEmojiButton |
A round icon button that opens an |
FXEmojiPicker |
A popup grid of emoji; picking one emits it and closes the popup. |
FXFilePathWidget |
A path field with a Browse button, a drop target and a validity mark. |
FXFilteredTree |
A tree under a filter bar, with expand-all and collapse-all buttons. |
FXFloatingDialog |
A floating dialog that appears at the cursor's position. |
FXFlowLayout |
Lay widgets out left to right, wrapping to a new line when full. |
FXIconButton |
A round, flat icon button, filled with the accent when checked. |
FXIconLabel |
A label that draws a QIcon when painted, so it takes theme inks then. |
FXIconLineEdit |
A line edit with an icon inside it, on the left or the right. |
FXJoinedGroup |
Widgets side by side in one button outline, with a divider between. |
FXKeyboardTree |
A tree whose rows a keyboard reaches as well as a mouse. |
FXKeycap |
A keyboard shortcut drawn as keys, one cap per key. |
FXLettersUnderscoreValidator |
Accept letters and underscores, and digits if allowed. |
FXLoadingOverlay |
A loading spinner centred over the parent widget. |
FXLoadingSpinner |
A quarter arc of the accent running round a muted ring. |
FXLowerCaseValidator |
Lowercase typed letters; accept digits or underscores if allowed. |
FXMainWindow |
Customized QMainWindow class. |
FXMentionEdit |
A text box that offers people by name after an |
FXNotificationBanner |
A notification card that slides in at the parent's top right. |
FXOutputLogHandler |
Logging handler that sends records to an output log widget. |
FXOutputLogWidget |
A read-only log pane with ANSI colours, search and a throttle. |
FXPasswordLineEdit |
A password field whose eye icon shows or hides what was typed. |
FXPrimaryButton |
The main action of a form, drawn on the theme's accent. |
FXProgressCard |
A card showing a task's progress: a title, a bar, a status icon. |
FXPygmentsHighlighter |
Syntax highlighter using Pygments for multi-language support. |
FXRangeSlider |
A slider with two handles for a low and a high value. |
FXRatingWidget |
A row of stars to click, with a preview under the pointer. |
FXResizedScrollArea |
A scroll area that can fit its content. |
FXSearchBar |
A line edit with a search icon, Qt's clear button and a debounce. |
FXSeating |
Seat a panel in the screen corner nearest its tray icon; slide it in. |
FXSingleInstance |
A lock on a local socket name; a second start wakes the first. |
FXSingleton |
Metaclass for Qt classes that are singletons. |
FXSortedTreeWidgetItem |
A row that sorts by its |
FXSplashScreen |
A splash screen: the image, a panel with the title, and a progress bar. |
FXSplitButton |
A split button whose click and dropdown both have keys. |
FXStatusBar |
Customized QStatusBar class. |
FXStatusDot |
A filled circle in a feedback colour, or grey for no state. |
FXStatusItem |
An icon and a word on a status bar, flat, lit when it is clickable. |
FXSystemTray |
A tray icon whose menu opens on a left click too, ending in Quit. |
FXTagChip |
A single removable tag chip. |
FXTagInput |
A field whose Enter turns the text into a chip; a chip's x removes it. |
FXThreadLine |
A line over a thread, from a comment's face into each reply's face. |
FXThumbnailDelegate |
Paint rows as a thumbnail, a title, a description and status marks. |
FXTimelineSlider |
A timeline/scrubber widget for DCC applications. |
FXToggleSwitch |
An on/off switch that slides, as tall as a push button. |
FXValidatedLineEdit |
A line edit that provides visual feedback when input is rejected. |
Functions:
| Name | Description |
|---|---|
align_labels |
Give the labels of every form in |
apply_tip |
Set a rich tooltip on |
code_color |
Return the colour code highlighting gives |
fix_wrapped_heights |
Give every word-wrapped label under |
grab_screen_region |
Let the user drag out a region of |
keycap |
Render a keyboard shortcut as rich text, one keycap per key. |
tip |
Build the HTML for a rich tooltip. |
Classes¶
FXAccordion
¶
FXAccordion(
parent: Optional[QWidget] = None,
exclusive: bool = True,
animation_duration: int = 150,
)
Bases: QWidget
A multi-section collapsible accordion widget.
Uses FXCollapsibleWidget for each section. By default, only one section can be open at a time (exclusive mode).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
bool
|
If True, only one section can be open at a time. |
True
|
|
int
|
Duration of expand/collapse animation in ms. |
150
|
Signals
section_expanded: Emitted when a section is expanded (section index). section_collapsed: Emitted when a section is collapsed (section index).
Examples:
>>> accordion = FXAccordion()
>>> accordion.add_section("General", general_content, icon="settings")
>>> accordion.add_section("Advanced", advanced_content, icon="tune")
>>> accordion.add_section("Info", info_content, icon="info")
Methods:
| Name | Description |
|---|---|
__iter__ |
Iterate over sections. |
__len__ |
Return the number of sections. |
add_section |
Add a section titled |
collapse_all |
Collapse all sections. |
collapse_section |
Collapse the section at |
exclusive |
Return whether only one section can be open at a time. |
expand_all |
Expand all sections. |
expand_section |
Expand the section at |
get_section |
Return the section at |
remove_section |
Remove the section at |
set_exclusive |
Set whether only one section can be open at a time. |
Methods:¶
add_section
¶
collapse_section
¶
collapse_section(index: int) -> None
Collapse the section at index; out of range does nothing.
expand_all
¶
expand_section
¶
expand_section(index: int) -> None
Expand the section at index; out of range does nothing.
get_section
¶
get_section(index: int) -> Optional[FXCollapsibleWidget]
Return the section at index, or None out of range.
FXApplication
¶
Bases: QApplication
Customized QApplication class.
On initialization, the application loads the previously saved theme from persistent storage. If no theme was saved, defaults to "dark".
Note
Qt allows a single QApplication per process. When one already exists
and is not an FXApplication (e.g. inside Houdini, Maya, or Nuke),
calling FXApplication() returns the host's application instance
untouched instead of raising RuntimeError. fxgui styling is NOT
applied to the host application in that case; fxgui's windows,
dialogs, tray menu and splash register themselves as themed roots.
FXAvatar
¶
FXAvatar(
name: str = "",
parent: Optional[QWidget] = None,
*,
size: int = 26,
pixmap: Optional[QPixmap] = None
)
Bases: QWidget
A circle showing a person's photo, or their initials on a disc.
The disc colour comes from the name, so one person keeps one colour in every thread and across runs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
The person's name; its first two words give the initials. |
''
|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
int
|
The circle's diameter, in logical pixels. |
26
|
|
Optional[QPixmap]
|
A photo, cropped to the circle. Replaces the initials. |
None
|
Examples:
Methods:
| Name | Description |
|---|---|
color |
Return the disc colour the name picks. |
initials |
Return the initials drawn on the disc, empty for no name. |
name |
Return the person's name. |
paintEvent |
Paint the photo or the initials disc. |
set_name |
Show |
set_pixmap |
Show |
set_size |
Resize the circle to |
FXBreadcrumb
¶
FXBreadcrumb(
parent: Optional[QWidget] = None,
separator: str = "chevron_right",
home_icon: str = "home",
show_navigation: bool = False,
path_separator: str = "/",
home_path: Optional[List[str]] = None,
tab_stops: bool = True,
)
Bases: QWidget
A path of clickable segments, with optional back and forward.
A double-click opens an editor to type a path; Escape or a click away closes it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
str
|
Icon name for separator between segments. |
'chevron_right'
|
|
str
|
Icon name for the home/root segment. |
'home'
|
|
bool
|
Show back/forward navigation buttons. |
False
|
|
str
|
Character used to join path segments in edit mode. |
'/'
|
|
Optional[List[str]]
|
Path segments to navigate to when home is clicked. If None, navigates to the first segment only. |
None
|
|
bool
|
Whether the segments and the back and forward buttons take Tab stops. False leaves them to the mouse; the path editor keeps its own. |
True
|
Signals
segment_clicked: Emitted when a segment is clicked (index, path list). home_clicked: Emitted when the home segment is clicked. path_edited: Emitted when user submits a typed path (raw string). navigated_back: Emitted when navigating back in history. navigated_forward: Emitted when navigating forward in history.
Examples:
>>> breadcrumb = FXBreadcrumb(show_navigation=True)
>>> breadcrumb.set_path(["Home", "Projects", "MyProject", "Assets"])
>>> breadcrumb.segment_clicked.connect(
... lambda idx, path: print(f"Navigate to: {'/'.join(path[:idx+1])}")
... )
>>> breadcrumb.path_edited.connect(lambda text: print(f"User typed: {text}"))
Methods:
| Name | Description |
|---|---|
append_segment |
Append |
can_go_back |
Check if back navigation is available. |
can_go_forward |
Check if forward navigation is available. |
clear |
Clear the breadcrumb path. |
clear_history |
Clear the navigation history. |
enterEvent |
Brighten the strip while the pointer is anywhere over the path. |
enter_edit_mode |
Switch to edit mode with the line edit visible. |
eventFilter |
Enter the editor on a double-click; leave it on Escape or away. |
exit_edit_mode |
Close the editor without submitting, as |
go_back |
Step back through the history; return whether it moved. |
go_forward |
Step forward through the history; return whether it moved. |
home_path |
Return where a home click goes; None means the first segment. |
is_editing |
Check if currently in edit mode. |
leaveEvent |
Return the strip to its resting fill. |
navigate_to |
Cut the path after |
path |
Return the current path segments. |
pop_segment |
Remove and return the last segment, or None on an empty path. |
set_edit_placeholder |
Set the hint the path editor shows while it is empty. |
set_home_path |
Set the path a home click goes to; None means the first segment. |
set_path |
Show |
Methods:¶
enterEvent
¶
Brighten the strip while the pointer is anywhere over the path.
Not a :hover rule: once the path is drawn, the widget directly
under the pointer is a segment, never the strip.
eventFilter
¶
Enter the editor on a double-click; leave it on Escape or away.
While the editor is up this widget also filters the application: a press on a heading or a window's background moves no focus.
exit_edit_mode
¶
Close the editor without submitting, as Escape does.
Public: a window-level Escape shortcut fires before this widget
sees the key, so such a window calls this itself.
home_path
¶
Return where a home click goes; None means the first segment.
pop_segment
¶
Remove and return the last segment, or None on an empty path.
set_edit_placeholder
¶
set_edit_placeholder(text: str) -> None
Set the hint the path editor shows while it is empty.
set_home_path
¶
Set the path a home click goes to; None means the first segment.
FXCamelCaseValidator
¶
FXCapitalizedLetterValidator
¶
Bases: QValidator
Accept letters only; fixup capitalises the first.
Examples:
>>> from qtpy.QtWidgets import QLineEdit
>>> line_edit = QLineEdit()
>>> line_edit.setValidator(FXCapitalizedLetterValidator())
Methods:
| Name | Description |
|---|---|
fixup |
Automatically capitalize the first letter. |
validate |
Allow only letters; a lowercase start waits for |
FXCheckableComboBox
¶
Bases: QComboBox
A combo whose popup stays open while several rows are ticked.
A plain QComboBox closes its popup on the first click, so ticking
three values would take three openings. Here a click or Space ticks
the row and the popup stays; the closed combo reads the ticked rows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
Signals
checked_changed: The ticked rows' texts, in row order.
Examples:
>>> combo = FXCheckableComboBox()
>>> combo.add_items(["render", "cache", "plate"])
>>> combo.set_checked_items(["cache"])
Methods:
| Name | Description |
|---|---|
add_items |
Add one unticked row per text. |
checked_items |
Return the ticked rows' texts, in row order. |
display_text |
Return what the closed combo reads: the ticked rows, joined. |
eventFilter |
Tick a row on a click or Space, and keep the popup open. |
paintEvent |
Draw the combo with the ticked rows as its text. |
set_checked_items |
Tick exactly the rows whose text is in |
FXCodeBlock
¶
Bases: QWidget
A read-only code block with syntax highlighting and theme styling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
The code string to display. |
''
|
|
str
|
The programming language (e.g., "python", "javascript"). |
'python'
|
|
Optional[QWidget]
|
The parent widget. |
None
|
Example
code = ''' ... def hello(): ... print("Hello, World!") ... ''' code_block = FXCodeBlock(code)
Methods:
| Name | Description |
|---|---|
code |
Return the code shown. |
set_code |
Show |
set_language |
Highlight |
FXCollapsibleWidget
¶
FXCollapsibleWidget(
parent: Optional[QWidget] = None,
title: str = "",
icon: Optional[Union[QIcon, str]] = None,
animation_duration: int = 150,
max_content_height: int = 300,
)
Bases: QWidget
A header that slides its content open and shut on a click.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
str
|
Title displayed in the header. |
''
|
|
Optional[Union[QIcon, str]]
|
Optional icon to display before the title. Can be a QIcon, an icon name string (for fxicons), or None. |
None
|
|
int
|
Duration of expand/collapse animation in ms. |
150
|
|
int
|
Maximum height of the open content area; taller content scrolls. 0 means no limit. |
300
|
Signals
expanded: Emitted when the widget is expanded. collapsed: Emitted when the widget is collapsed.
Examples:
>>> from qtpy.QtWidgets import QLabel, QVBoxLayout
>>> collapsible = FXCollapsibleWidget(title="Settings")
>>> layout = QVBoxLayout()
>>> layout.addWidget(QLabel("Option 1"))
>>> layout.addWidget(QLabel("Option 2"))
>>> collapsible.set_content_layout(layout)
>>>
>>> # With an icon
>>> collapsible_with_icon = FXCollapsibleWidget(
... title="Settings",
... icon="settings"
... )
Initialize the collapsible section.
Methods:
| Name | Description |
|---|---|
animation_duration |
Return the animation duration in milliseconds. |
collapse |
Hide the content, sliding shut unless |
eventFilter |
Toggle on a left click anywhere on the header. |
expand |
Show the content, sliding open unless |
icon |
Return the icon before the title, or None. |
is_expanded |
Return whether the widget is expanded. |
max_content_height |
Return the open content area's cap; 0 means no limit. |
set_animation_duration |
Set the animation duration in milliseconds. |
set_content_layout |
Put |
set_content_widget |
Show |
set_icon |
Set an icon to display before the title. |
set_max_content_height |
Set the open content area's cap, at once if it is open. |
set_title |
Set the title text. |
title |
Return the title text. |
toggle |
Toggle the expanded/collapsed state. |
Methods:¶
collapse
¶
collapse(animate: bool = True) -> None
Hide the content, sliding shut unless animate is False.
eventFilter
¶
eventFilter(watched: QObject, event: QEvent) -> bool
Toggle on a left click anywhere on the header.
expand
¶
expand(animate: bool = True) -> None
Show the content, sliding open unless animate is False.
max_content_height
¶
max_content_height() -> int
Return the open content area's cap; 0 means no limit.
set_animation_duration
¶
set_animation_duration(value: int) -> None
Set the animation duration in milliseconds.
set_content_layout
¶
Put content_layout on a new widget as the content.
set_icon
¶
FXCommand
dataclass
¶
FXCommand(
label: str,
run: Optional[Callable[[], None]] = None,
keys: str = "",
section: str = "",
enabled: bool = True,
tip: str = "",
icon: str = "",
choices: Optional[Callable[[], List[FXCommand]]] = None,
key: str = "",
)
One row of the palette, and what picking it does.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
What the row reads. |
required |
|
Optional[Callable[[], None]]
|
Called when the row is picked; unused where |
None
|
|
str
|
Its shortcut, as |
''
|
|
str
|
The group it belongs to, shown beside the label and matched by the search. |
''
|
|
bool
|
False shows the row greyed; picking it shows |
True
|
|
str
|
Shown under the list while the row is current. |
''
|
|
str
|
An icon's name, drawn left of the label: a material one, or
|
''
|
|
Optional[Callable[[], List[FXCommand]]]
|
Picking the row lists what this returns, in place, to pick
one; a choice with its own |
None
|
|
str
|
What the palette remembers the row by; the label where empty. Give one where the label changes, as "Show Log" and "Hide Log". |
''
|
FXCommandPalette
¶
FXCommandPalette(
window: QWidget,
commands: Callable[[], List[FXCommand]],
recent: Sequence[str] = (),
)
Bases: QFrame
A frameless popup over window's commands; Enter runs, Escape closes.
Every typed word must appear, in order, in a row's label and section. Rows run lately come first, the latest on top, as in VS Code; then rows where the words start words.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
QWidget
|
The window the palette opens over. |
required |
|
Callable[[], List[FXCommand]]
|
Returns the commands each time the palette opens. |
required |
|
Sequence[str]
|
The keys run lately, the latest first, to start from. |
()
|
Signals
recent_changed: The keys run lately, the latest first, after a run; store them to keep the order across sessions.
Examples:
>>> palette = FXCommandPalette(window, lambda: [
... FXCommand("Collapse all", tree.collapseAll, "Ctrl+-"),
... ])
>>> palette.open_commands(position="top")
Methods:
| Name | Description |
|---|---|
keyPressEvent |
Move with the arrows and pages; Escape closes. |
open_commands |
Open on the window's commands, at |
open_go_to |
Open on the rows |
rank |
Return how well |
Methods:¶
keyPressEvent
¶
Move with the arrows and pages; Escape closes.
open_commands
¶
Open on the window's commands, at position in the window.
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
open_go_to
¶
open_go_to(
load: GoTo,
select: Callable[[str], None],
placeholder: str = "Type a name, or > for a command",
loading: str = "Loading",
position: str = "center",
) -> None
Open on the rows load hands back; picking one selects its id.
A leading > switches to the commands. Until load calls back,
the list reads loading.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
GoTo
|
Called once with a callback taking |
required |
|
Callable[[str], None]
|
Called with the picked row's id. |
required |
|
str
|
What the empty field says. |
'Type a name, or > for a command'
|
|
str
|
What the list says until the rows land. |
'Loading'
|
|
str
|
Where in the window it opens; one of |
'center'
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
FXCommandRow
¶
FXCommandRow(
title: str = "Command row",
parent: Optional[QWidget] = None,
margins: Optional[Tuple[int, int, int, int]] = None,
spacing: Optional[int] = None,
icon_size: int = 17,
)
Bases: QToolBar
A toolbar fixed in place: no handle, no floating, nothing to hide it.
Its margins and spacing hold through style and theme changes, which otherwise reset a toolbar's layout to the style's own.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
The toolbar's window title. Defaults to "Command row". |
'Command row'
|
|
Optional[QWidget]
|
Parent widget. Defaults to |
None
|
|
Optional[Tuple[int, int, int, int]]
|
Left, top, right and bottom, in pixels. Defaults to the style's own. |
None
|
|
Optional[int]
|
Between controls, in pixels. Defaults to the style's own. |
None
|
|
int
|
The side of its tool button icons. Defaults to 17. |
17
|
Examples:
Methods:
| Name | Description |
|---|---|
changeEvent |
Put the margins back after a style change resets them. |
FXConfirmDeleteDialog
¶
FXConfirmDeleteDialog(
parent: Optional[QWidget] = None,
*,
title: str,
body: str,
confirm_word: str
)
Bases: QDialog
Ask for a word, typed exactly, before an act with no undo.
Delete opens only while the field holds confirm_word exactly, and it
is never the default button, so a stray Enter destroys nothing.
Clicking the word copies it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
str
|
The window title, naming what is going. |
required |
|
str
|
What will be destroyed, including that it cannot be undone. |
required |
|
str
|
What has to be typed. |
required |
Examples:
>>> dialog = FXConfirmDeleteDialog(
... window, title="Delete beauty v004",
... body="This cannot be undone.", confirm_word="beauty")
>>> if dialog.exec():
... delete_version()
Methods:
| Name | Description |
|---|---|
copy_word |
Put the confirmation word on the clipboard. |
eventFilter |
Copy the word when its label is clicked. |
FXDropZone
¶
FXDropZone(
parent: Optional[QWidget] = None,
title: str = "Drag and Drop Files Here",
description: str = "or use the Browse Files... button below",
accept_mode: str = "files",
extensions: Optional[Set[str]] = None,
multiple: bool = True,
icon_name: str = "upload_file",
show_formats: bool = True,
show_buttons: bool = True,
show_tree: bool = True,
)
Bases: QWidget
A drag and drop zone widget for file and folder selection.
The zone takes drops on its placeholder and on its file list alike: neither child accepts drops, so Qt hands them to the zone.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
str
|
Main title text displayed in the drop zone. |
'Drag and Drop Files Here'
|
|
str
|
Description text displayed below the title. |
'or use the Browse Files... button below'
|
|
str
|
What to accept: 'files', 'folders' or 'both'. |
'files'
|
|
Optional[Set[str]]
|
Allowed file extensions, such as {'.png', '.JPG'}; case and a missing leading dot do not matter. None accepts all. |
None
|
|
bool
|
Whether to allow multiple file/folder selection. |
True
|
|
str
|
Icon name to display (default: 'upload_file'). |
'upload_file'
|
|
bool
|
Whether to display accepted formats below title. |
True
|
|
bool
|
Whether to show Browse/Clear buttons. |
True
|
|
bool
|
Whether to show file tree after files are dropped. |
True
|
Raises:
| Type | Description |
|---|---|
ValueError
|
|
Signals
files_dropped: Emitted when files/folders are dropped or selected. Passes a list of Path objects. files_cleared: Emitted when files are cleared. file_removed: Emitted when a single file is removed from the tree. Passes the Path that was removed. drag_entered: Emitted when a valid drag enters the drop zone. drag_left: Emitted when a drag leaves the drop zone.
Examples:
>>> # Accept image files only with tree view
>>> drop_zone = FXDropZone(
... title="Drop Images Here",
... description="or use the Browse Files... button below",
... extensions={'.png', '.jpg', '.exr'},
... show_tree=True
... )
>>> drop_zone.files_dropped.connect(lambda paths: print(paths))
>>>
>>> # Accept folders only (no tree)
>>> folder_zone = FXDropZone(
... title="Drop Project Folder",
... accept_mode='folders',
... show_tree=False
... )
Methods:
| Name | Description |
|---|---|
accept_mode |
Return the accept mode: 'files', 'folders' or 'both'. |
add_files |
Add the paths not held yet, saying |
clear |
Remove every file and say |
description |
Return the description text. |
dragEnterEvent |
Accept a drag that carries a path the zone takes. |
dragLeaveEvent |
Return the area to rest. |
dropEvent |
Add the accepted paths; edge the area in error if none were. |
extensions |
Return the accepted extensions, lowercase with a leading dot. |
file_tree |
Return the file tree widget, or None without |
has_files |
Return whether files have been added. |
multiple |
Return whether multiple selection is enabled. |
selected_files |
Return the list of selected files. |
set_accept_mode |
Set the accept mode: 'files', 'folders' or 'both'. |
set_description |
Set the description text. |
set_extensions |
Set the accepted extensions; None or none at all accepts all. |
set_files |
Replace the selected files, saying nothing. |
set_icon |
Show the fxicons icon |
set_multiple |
Set whether multiple selection is enabled. |
set_title |
Set the title text. |
title |
Return the title text. |
Methods:¶
dragEnterEvent
¶
Accept a drag that carries a path the zone takes.
dropEvent
¶
Add the accepted paths; edge the area in error if none were.
extensions
¶
Return the accepted extensions, lowercase with a leading dot.
file_tree
¶
file_tree() -> Optional[QTreeWidget]
Return the file tree widget, or None without show_tree.
set_accept_mode
¶
set_accept_mode(value: str) -> None
Set the accept mode: 'files', 'folders' or 'both'.
Raises:
| Type | Description |
|---|---|
ValueError
|
|
set_extensions
¶
Set the accepted extensions; None or none at all accepts all.
FXElidedLabel
¶
FXElidedLabel(
text: str = "",
parent: Optional[QWidget] = None,
mode: TextElideMode = ElideRight,
)
Bases: QLabel
A QLabel that cuts its text with an ellipsis when it does not fit.
On one line the text is cut where mode says. With wordWrap() on
and a maximum height set, it is cut from the right at the last line
that fits; mode has no meaning across wrapped lines.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
The label's text. |
''
|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
TextElideMode
|
Where one line is cut. |
ElideRight
|
Examples:
Methods:
| Name | Description |
|---|---|
changeEvent |
Re-elide text in a new font. |
elided_text |
Return the text as painted, shortened to fit the label. |
event |
Show the whole text as the tip of a cut label with no tip set. |
minimumSizeHint |
Return no width and one line's height, so the label can shrink. |
mode |
Return where one line is cut when it does not fit. |
resizeEvent |
Re-elide text when the label is resized. |
setText |
Set the text and store the full text for elision. |
set_mode |
Cut one line where |
sizeHint |
Ask for the room the whole text needs, on one line. |
text |
Return the whole text that was set, not the shortened one. |
FXEmojiButton
¶
FXEmojiButton(
parent: Optional[QWidget] = None,
emojis: Optional[Sequence[str]] = None,
size: int = 28,
)
Bases: FXIconButton
A round icon button that opens an FXEmojiPicker just below itself.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
Optional[Sequence[str]]
|
The emoji to offer. Defaults to |
None
|
|
int
|
The circle's diameter, in logical pixels. |
28
|
Signals
emoji_picked(str): The emoji picked.
Examples:
Methods:
| Name | Description |
|---|---|
attach |
Insert each picked emoji at |
open_picker |
Show the popup just below the button, or above it near the bottom. |
picker |
Return the popup, built on first use. |
FXEmojiPicker
¶
FXEmojiPicker(
parent: Optional[QWidget] = None,
emojis: Optional[Sequence[str]] = None,
columns: int = 8,
)
Bases: QFrame
A popup grid of emoji; picking one emits it and closes the popup.
Arrow keys move through the grid, Enter or Space picks, Escape closes without picking.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget; the popup stays its child. |
None
|
|
Optional[Sequence[str]]
|
The emoji to offer. Defaults to |
None
|
|
int
|
How many emoji per row. |
8
|
Signals
emoji_picked(str): The emoji picked.
Examples:
>>> picker = FXEmojiPicker(button)
>>> picker.emoji_picked.connect(editor.insertPlainText)
>>> picker.popup_at(button.mapToGlobal(QPoint(0, button.height())))
Methods:
| Name | Description |
|---|---|
buttons |
Return the grid's buttons, one per emoji, in order. |
columns |
Return how many emoji each row holds. |
eventFilter |
Move through the grid with the arrows, pick with Enter or Space. |
mousePressEvent |
Close on a press outside, without reopening from the anchor. |
popup_at |
Show the popup at global |
FXFilePathWidget
¶
FXFilePathWidget(
parent: Optional[QWidget] = None,
mode: str = "file",
placeholder: str = "Select path...",
file_filter: str = "All Files (*)",
default_path: Optional[str] = None,
validate: bool = True,
)
Bases: QWidget
A path field with a Browse button, a drop target and a validity mark.
The check runs on a worker thread, so a share that does not answer stalls the mark, never the window.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
str
|
Selection mode: 'file', 'files', 'folder' or 'save'. |
'file'
|
|
str
|
Placeholder text. |
'Select path...'
|
|
str
|
File filter for file dialogs (e.g., "Images (*.png *.jpg)"). |
'All Files (*)'
|
|
Optional[str]
|
Default path for the file dialog. |
None
|
|
bool
|
Whether to show validation indicator. |
True
|
Raises:
| Type | Description |
|---|---|
ValueError
|
|
Signals
path_changed: Emitted when the path changes. path_valid: Whether the path exists as the mode asks, after each check.
Examples:
>>> path_widget = FXFilePathWidget(mode='file', file_filter="Python (*.py)")
>>> path_widget.path_changed.connect(lambda p: print(f"Path: {p}"))
>>>
>>> # Folder mode
>>> folder_widget = FXFilePathWidget(mode='folder')
Methods:
| Name | Description |
|---|---|
clear |
Clear the path input. |
dragEnterEvent |
Handle drag enter for file drops. |
dropEvent |
Handle file drop. |
is_valid |
Return whether the current path is valid. |
path |
Return the current path. |
set_file_filter |
Set the dialogs' filter, such as "Images (*.png *.jpg)". |
set_mode |
Set the mode: 'file', 'files', 'folder' or 'save'. |
set_path |
Set the path shown. |
FXFilteredTree
¶
FXFilteredTree(
tree: Optional[FXKeyboardTree] = None,
placeholder: str = "Filter...",
actions: Optional[QLayout] = None,
parent: Optional[QWidget] = None,
)
Bases: QWidget
A tree under a filter bar, with expand-all and collapse-all buttons.
Typing on the tree goes to the bar, and the bar narrows the tree with
fxutils.filter_tree: a match keeps its subtree and its ancestors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[FXKeyboardTree]
|
The tree to wrap; a new |
None
|
|
str
|
What the empty filter bar says. |
'Filter...'
|
|
Optional[QLayout]
|
A row of buttons under the tree, if any. |
None
|
|
Optional[QWidget]
|
The parent widget. |
None
|
FXFloatingDialog
¶
FXFloatingDialog(
parent: Optional[QWidget] = None,
icon: Optional[QPixmap] = None,
title: Optional[str] = None,
popup: bool = False,
)
Bases: QDialog
A floating dialog that appears at the cursor's position.
It closes when any mouse button except the right one is pressed, and is deleted once closed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. Defaults to |
None
|
|
Optional[QPixmap]
|
The title's icon. Defaults to a home icon in the theme's icon color. |
None
|
|
Optional[str]
|
The dialog title. Defaults to "Floating Dialog". |
None
|
|
bool
|
Whether it closes on a click outside, as a menu does.
A popup casts no painted shadow. Defaults to |
False
|
Methods:
| Name | Description |
|---|---|
mousePressEvent |
Close on a press of any button but the right one. |
set_dialog_icon |
Set the title's icon; |
set_dialog_title |
Set the title; |
show_under_cursor |
Centre the dialog on the cursor at its final size and run it. |
FXFlowLayout
¶
Bases: QLayout
Lay widgets out left to right, wrapping to a new line when full.
A QHBoxLayout asks for every item's width at once, so a row of tags
in a narrow dock widens the dock; this one grows taller instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Widget the layout is set on. |
None
|
|
int
|
Gap in pixels between items, across and down; the pane gap by default. |
PANE_GAP
|
Examples:
>>> flow = FXFlowLayout()
>>> for tag in ("comp", "lighting", "fx"):
... flow.addWidget(QLabel(tag))
Methods:
| Name | Description |
|---|---|
addItem |
Keep |
count |
Return how many items are laid out. |
expandingDirections |
Grow in neither direction: the width decides the height. |
hasHeightForWidth |
Say the height follows the width, as a wrap does. |
heightForWidth |
Return the height wrapping into |
itemAt |
Return the item at |
minimumSize |
Return the widest single item: nothing narrower can hold it. |
setGeometry |
Place every item inside |
sizeHint |
Return the minimum size: asking for more would widen the parent. |
takeAt |
Remove and return the item at |
FXIconButton
¶
FXIconButton(
icon: str,
parent: Optional[QWidget] = None,
*,
tip: str = "",
checkable: bool = False,
checked_icon: Optional[str] = None,
size: Optional[int] = None
)
Bases: QToolButton
A round, flat icon button, filled with the accent when checked.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
A material icon name. |
required |
|
Optional[QWidget]
|
Parent widget. |
None
|
|
str
|
The tooltip, set through |
''
|
|
bool
|
Whether a click toggles the button. |
False
|
|
Optional[str]
|
The icon shown while checked. Defaults to |
None
|
|
Optional[int]
|
The circle's diameter, in logical pixels. Defaults to a push button's height. |
None
|
Examples:
>>> eye = FXIconButton("visibility_off", bar, tip="Show to client",
... checkable=True, checked_icon="visibility")
FXIconLabel
¶
Bases: QLabel
A label that draws a QIcon when painted, so it takes theme inks then.
A QLabel pixmap is baked once; an fxicons icon here follows every theme switch with no signal. Disabled draws the icon's Disabled mode.
Examples:
>>> label = FXIconLabel(size=18)
>>> fxicons.set_icon(label, "info", color="feedback_info_foreground")
Methods:
| Name | Description |
|---|---|
icon |
Return the icon drawn. |
iconSize |
Return the size the icon is drawn at. |
minimumSizeHint |
Return the size hint: the icon is not drawn smaller. |
paintEvent |
Draw the icon in the mode the enabled state asks for. |
pixmap |
Return the icon as drawn now, or the plain pixmap without one. |
setIcon |
Draw |
setIconSize |
Draw the icon at |
sizeHint |
Return the icon size plus the margins. |
Methods:¶
FXIconLineEdit
¶
FXIconLineEdit(
parent: Optional[QWidget] = None,
icon_name: Optional[str] = None,
icon_position: str = "left",
)
Bases: QLineEdit
A line edit with an icon inside it, on the left or the right.
The icon is a QLineEdit.addAction action, so Qt places it and keeps
it out of the Tab chain.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
The parent widget. |
None
|
|
Optional[str]
|
The icon to show; |
None
|
|
str
|
|
'left'
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
FXJoinedGroup
¶
Bases: QFrame
Widgets side by side in one button outline, with a divider between.
A child with keyboard focus lights the whole outline in the accent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
Examples:
>>> group = FXJoinedGroup(composer)
>>> group.add_widget(status_combo)
>>> group.add_widget(FXPrimaryButton("Post", group))
Methods:
| Name | Description |
|---|---|
add_widget |
Append |
event |
Re-place the children when one is deleted or moved elsewhere. |
eventFilter |
Re-place the children when one is shown or hidden. |
Methods:¶
FXKeyboardTree
¶
FXKeyboardTree(parent: Optional[QWidget] = None)
Bases: QTreeWidget
A tree whose rows a keyboard reaches as well as a mouse.
- The Menu key and Shift+F10 emit
customContextMenuRequestedat the current row, so one handler builds every row menu. - Enter runs the primary act set with
set_primary_act. - Typing goes to the field set with
type_into, rather than Qt's keyboard search, which on a lazy tree finds only loaded rows.
Methods:
| Name | Description |
|---|---|
keyPressEvent |
Route the menu keys, Enter and typing, then let Qt have the rest. |
open_current_menu |
Ask for the current row's menu, as a right-click on it would. |
set_primary_act |
Run |
type_into |
Send what is typed on this tree to |
Methods:¶
keyPressEvent
¶
Route the menu keys, Enter and typing, then let Qt have the rest.
open_current_menu
¶
open_current_menu() -> bool
Ask for the current row's menu, as a right-click on it would.
Returns:
| Type | Description |
|---|---|
bool
|
Whether there was a current row to ask about. |
set_primary_act
¶
Run act on the current row on Enter; None gives Enter back.
type_into
¶
FXKeycap
¶
Bases: QWidget
A keyboard shortcut drawn as keys, one cap per key.
Each cap is round at the button radius, and its look is a registered rule, so it follows every theme switch.
Examples:
Methods:
| Name | Description |
|---|---|
keys |
Return the key sequence as it was given. |
set_keys |
Show |
FXLettersUnderscoreValidator
¶
FXLettersUnderscoreValidator(
allow_numbers: bool = False, parent: Optional[QWidget] = None
)
Bases: QRegularExpressionValidator
Accept letters and underscores, and digits if allowed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
bool
|
If |
False
|
|
Optional[QWidget]
|
Parent widget. |
None
|
Examples:
>>> from qtpy.QtWidgets import QLineEdit
>>> line_edit = QLineEdit()
>>> line_edit.setValidator(FXLettersUnderscoreValidator(allow_numbers=True))
FXLoadingOverlay
¶
FXLoadingOverlay(
parent: Optional[QWidget] = None,
message: Optional[str] = None,
dim: bool = True,
block_input: bool = True,
size: int = 48,
)
Bases: QWidget
A loading spinner centred over the parent widget.
By default the overlay dims the parent and takes its mouse, for a long
operation the user must wait out. A view still usable while its rows
load passes dim=False, block_input=False.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget to overlay. |
None
|
|
Optional[str]
|
Optional message to display below the spinner. |
None
|
|
bool
|
Whether to darken the parent behind the spinner. |
True
|
|
bool
|
Whether the overlay takes the parent's mouse. |
True
|
|
int
|
The spinner's diameter in pixels. |
48
|
Examples:
>>> overlay = FXLoadingOverlay(my_widget, "Loading assets...")
>>> overlay.show()
>>> # ... do some work ...
>>> overlay.hide()
Methods:
| Name | Description |
|---|---|
eventFilter |
Cover the parent again when it resizes. |
hideEvent |
Stop the spinner. |
paintEvent |
Paint the semi-transparent background, if dimming. |
showEvent |
Cover the parent, come to the front and start the spinner. |
FXLoadingSpinner
¶
FXLoadingSpinner(
parent: Optional[QWidget] = None,
size: Optional[int] = None,
line_width: Optional[int] = None,
color: str = "accent_primary",
)
Bases: QWidget
A quarter arc of the accent running round a muted ring.
The animation runs only while the spinner can be seen.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
Optional[int]
|
Size of the spinner in pixels. Defaults to a button's height. |
None
|
|
Optional[int]
|
Width of the ring. Defaults to a tenth of |
None
|
|
str
|
The arc's color: a theme token name, followed through a
switch, or a colour. Defaults to |
'accent_primary'
|
Examples:
>>> spinner = FXLoadingSpinner(size=32)
>>> spinner.start()
>>> # ... do some work ...
>>> spinner.stop()
Methods:
| Name | Description |
|---|---|
hideEvent |
Pause the animation while nothing can see it. |
is_spinning |
Return whether the spinner is started. |
paintEvent |
Paint the muted ring, then the arc over it. |
set_color |
Set the arc's color: a theme token name or a colour. |
showEvent |
Resume the animation a hide paused. |
start |
Start the animation, and show the spinner if it has a parent. |
stop |
Stop the animation. |
Methods:¶
FXLowerCaseValidator
¶
FXLowerCaseValidator(
allow_numbers: bool = False,
allow_underscores: bool = False,
parent: Optional[QWidget] = None,
)
Bases: QRegularExpressionValidator
Lowercase typed letters; accept digits or underscores if allowed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
bool
|
If |
False
|
|
bool
|
If |
False
|
|
Optional[QWidget]
|
Parent widget. |
None
|
Examples:
>>> from qtpy.QtWidgets import QLineEdit
>>> line_edit = QLineEdit()
>>> line_edit.setValidator(FXLowerCaseValidator(allow_numbers=True))
Methods:
| Name | Description |
|---|---|
validate |
Lowercase the input, then check it against the pattern. |
FXMainWindow
¶
FXMainWindow(
parent: Optional[QWidget] = None,
icon: Optional[Union[str, QIcon]] = None,
title: Optional[str] = None,
size: Optional[Tuple[int, int]] = None,
documentation: Optional[str] = None,
project: Optional[str] = None,
version: Optional[str] = None,
company: Optional[str] = None,
ui_file: Optional[str] = None,
fit_to_contents: bool = False,
framed: bool = False,
)
Bases: QMainWindow
Customized QMainWindow class.
The window's icon and name sit at the menu bar's right end, in
title_corner; set_banner_text and set_banner_icon change them.
The project, version and company live on the status bar's items, which
the About dialog reads.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. Defaults to |
None
|
|
Optional[Union[str, QIcon]]
|
The window's icon: a path to an image, or a |
None
|
|
Optional[str]
|
Title of the window, and the name in the menu bar corner.
Defaults to |
None
|
|
Optional[Tuple[int, int]]
|
Window size as width and height. Defaults to 500 x 600. |
None
|
|
Optional[str]
|
URL the Help menu's Documentation opens; the entry
is disabled without a valid one. Defaults to |
None
|
|
Optional[str]
|
The status bar's project. Defaults to |
None
|
|
Optional[str]
|
The status bar's version. Defaults to |
None
|
|
Optional[str]
|
The status bar's company. Defaults to |
None
|
|
Optional[str]
|
A Designer file loaded as the central widget, kept as
|
None
|
|
bool
|
Whether to grow to the layout's own |
False
|
|
bool
|
Whether to draw the window as a frame around its panes.
The menu bar, toolbars, status bar and the window behind the
central widget paint the theme's |
False
|
Attributes:
| Name | Type | Description |
|---|---|---|
title_corner |
QWidget
|
The widget at the menu bar's right end
holding |
main_menu, |
window_menu, theme_menu, help_menu (QMenu
|
fxgui's
menus on the current menu bar, or |
refresh_action |
QAction
|
Ctrl+Alt+R, on no menu; an application adds it where its refresh belongs. |
Methods:
| Name | Description |
|---|---|
add_corner_widget |
Add |
center_on_screen |
Center the window on the primary screen's available area. |
documentation |
Return the URL Help > Documentation opens, or |
event |
Route status tips after the items; watch a framed window's bands. |
eventFilter |
Fit the corner to the bar, re-place it, and flatten framed bands. |
setMenuBar |
Set the menu bar; it gets fxgui's menus, the corner and the frame. |
setStatusBar |
Set the status bar; a framed window paints it in the frame. |
setWindowTitle |
Set the window title; |
set_banner_icon |
Set the icon in the menu bar corner. |
set_banner_text |
Set the name in the menu bar corner. |
set_documentation |
Set the URL Help > Documentation opens; no valid URL disables it. |
showEvent |
Grow once to the layout's own size, if this window asked to. |
toggle_theme |
Switch every fxgui window to the next available theme. |
Attributes¶
Methods:¶
add_corner_widget
¶
Add widget to the menu bar corner, left of the icon and name.
The corner is placed again whenever widget grows or shrinks.
center_on_screen
¶
documentation
¶
Return the URL Help > Documentation opens, or None.
event
¶
event(event: QEvent) -> bool
Route status tips after the items; watch a framed window's bands.
eventFilter
¶
eventFilter(watched: QObject, event: QEvent) -> bool
Fit the corner to the bar, re-place it, and flatten framed bands.
setMenuBar
¶
setMenuBar(menu_bar: Optional[QMenuBar]) -> None
Set the menu bar; it gets fxgui's menus, the corner and the frame.
None removes the bar and fxgui's menus with it; the corner waits
for the next bar.
setStatusBar
¶
setStatusBar(status_bar: Optional[QStatusBar]) -> None
Set the status bar; a framed window paints it in the frame.
setWindowTitle
¶
setWindowTitle(title: str) -> None
Set the window title; None or empty reads "Window".
set_banner_icon
¶
set_documentation
¶
Set the URL Help > Documentation opens; no valid URL disables it.
showEvent
¶
Grow once to the layout's own size, if this window asked to.
Grow-only, so a larger requested size stays, and once, so a window dragged smaller is not pushed back out. Bounded by the screen the window is on.
FXMentionEdit
¶
Bases: QPlainTextEdit
A text box that offers people by name after an @.
A chosen person is written as @<their name>; mentions answers who
the text still names. Two people of one name are offered with their
ids. Ctrl+Enter emits submitted, Escape cancelled.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
int
|
How many lines tall the box is. |
3
|
|
bool
|
Whether Escape closes the box, so it takes Escape before any window shortcut does. |
False
|
Signals
submitted: Ctrl+Enter was pressed. cancelled: Escape was pressed with no name list open.
Examples:
>>> box = FXMentionEdit(card)
>>> box.set_people({"anne.martin": "Anne Martin"})
>>> box.submitted.connect(lambda: post(box.toPlainText()))
Methods:
| Name | Description |
|---|---|
changeEvent |
Hold the lines again in the font and frame a sheet hands it. |
event |
Claim Escape from window shortcuts when the box closes on it. |
insert_mention |
Write |
kept |
Return the text and who it names, for |
keyPressEvent |
Submit on Ctrl+Enter; an open name list takes Enter and Escape. |
mentions |
Return the ids the text still names, in the order chosen. |
reset |
Empty the box and forget who was named. |
restore |
Put back what |
set_people |
Offer |
Methods:¶
changeEvent
¶
Hold the lines again in the font and frame a sheet hands it.
insert_mention
¶
insert_mention(person: str) -> None
Write person as @<name>, replacing an @ being typed.
kept
¶
Return the text and who it names, for restore to put back.
keyPressEvent
¶
Submit on Ctrl+Enter; an open name list takes Enter and Escape.
restore
¶
Put back what kept returned, the cursor at its end.
FXNotificationBanner
¶
FXNotificationBanner(
parent: Optional[QWidget] = None,
message: str = "",
severity_type: Optional[int] = None,
timeout: Optional[int] = None,
actions: Optional[Mapping[str, Callable[[], None]]] = None,
closable: bool = True,
width: int = 320,
logger: Optional[Logger] = None,
title: Optional[str] = None,
icon: Optional[str] = None,
margin: int = 16,
top: Optional[int] = None,
spacing: int = PANE_GAP,
)
Bases: QFrame
A notification card that slides in at the parent's top right.
Cards on one parent stack, and close up when one is dismissed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
The widget the card sits on; it positions the card. |
None
|
|
str
|
The notification message, rich text. |
''
|
|
Optional[int]
|
CRITICAL, ERROR, WARNING, SUCCESS, INFO or DEBUG;
None for a plain card with |
None
|
|
Optional[int]
|
Milliseconds before it dismisses itself; 0 never. Defaults to 5000, and to 0 for ERROR and CRITICAL: an error waits for the artist to read it. |
None
|
|
Optional[Mapping[str, Callable[[], None]]]
|
Buttons as |
None
|
|
bool
|
Whether to show a close button. |
True
|
|
int
|
The card's fixed width. |
320
|
|
Optional[Logger]
|
Logs the message when shown, at the severity's level. |
None
|
|
Optional[str]
|
Replaces the severity's title. |
None
|
|
Optional[str]
|
An icon name replacing the severity's icon. |
None
|
|
int
|
From the parent's right edge. |
16
|
|
Optional[int]
|
From the parent's top to the first banner. Defaults to
|
None
|
|
int
|
Between stacked notifications; the pane gap. |
PANE_GAP
|
Signals
closed: Emitted when the banner is closed.
Examples:
>>> # Simple notification - auto-positions and stacks
>>> banner = FXNotificationBanner(
... parent=window,
... message="File saved successfully!",
... severity_type=SUCCESS,
... )
>>> banner.show()
>>>
>>> # Custom notification
>>> banner = FXNotificationBanner(
... parent=window,
... message="New version available!",
... title="Update",
... icon="system_update",
... )
>>> banner.show()
>>>
>>> # Interactive notification - waits for the artist to answer
>>> banner = FXNotificationBanner(
... parent=window,
... message="Publish failed on 3 shots.",
... severity_type=ERROR,
... actions={"Retry": retry_publish, "Open log": open_log},
... )
>>> banner.show()
Methods:
| Name | Description |
|---|---|
add_action |
Add an action button to the banner. |
dismiss |
Dismiss the notification with slide-out animation to the right. |
eventFilter |
Keep the banner at the parent's right edge as it resizes. |
message |
Return the message the banner says. |
set_message |
Show |
set_timeout |
Set the timeout in ms, 0 for none; a shown card counts from now. |
set_top |
Set the first banner's distance from the parent's top. |
show |
Show the notification with slide-in animation from the right. |
Methods:¶
add_action
¶
eventFilter
¶
eventFilter(obj, event) -> bool
Keep the banner at the parent's right edge as it resizes.
set_timeout
¶
set_timeout(timeout: int) -> None
Set the timeout in ms, 0 for none; a shown card counts from now.
show
¶
Show the notification with slide-in animation from the right.
Automatically calculates position based on other active notifications for the same parent widget, stacking them vertically with spacing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
bool
|
If a banner on the same parent already says this message, show nothing and delete this one. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
Whether the banner was shown. |
FXOutputLogHandler
¶
FXOutputLogHandler(log_widget: FXOutputLogWidget)
Bases: Handler
Logging handler that sends records to an output log widget.
The widget is held weakly: once it is deleted the handler removes itself from every logger instead of raising on each record.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
FXOutputLogWidget
|
The |
required |
Methods:
| Name | Description |
|---|---|
detach |
Remove this handler from the root logger and every named logger. |
emit |
Send a record to the widget, or detach if the widget is gone. |
Attributes:
| Name | Type | Description |
|---|---|---|
log_widget |
Optional[FXOutputLogWidget]
|
The widget records go to, or |
Attributes¶
log_widget
property
¶
log_widget: Optional[FXOutputLogWidget]
The widget records go to, or None once it is gone.
Methods:¶
FXOutputLogWidget
¶
FXOutputLogWidget(
parent: Optional[QWidget] = None,
max_blocks: int = 0,
hang_indent: Optional[Union[str, Pattern]] = None,
)
Bases: QWidget
A read-only log pane with ANSI colours, search and a throttle.
Records reach it through an FXOutputLogHandler added to a logger,
or through append_log and append_many.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
int
|
How many lines the pane keeps before Qt prunes the
oldest, as a terminal's scrollback does. Defaults to |
0
|
|
Optional[Union[str, Pattern]]
|
A regular expression matching a record's header, such as its time, level and logger name. A wrapped record's later lines then start under the end of the match, not at column 0. Nothing is added to the text, so a copy gives the original. |
None
|
Signals
log_message: Emitted with a message and its level when a record is received (for thread-safe delivery).
Examples:
>>> import logging
>>> from fxgui import fxwidgets
>>> log_widget = fxwidgets.FXOutputLogWidget()
>>> logging.root.addHandler(fxwidgets.FXOutputLogHandler(log_widget))
Methods:
| Name | Description |
|---|---|
append_log |
Queue text for the pane; every record queued is shown. |
append_many |
Queue |
clear_log |
Clear the log output. |
eventFilter |
Send Shift+Enter in the search field to the previous match. |
keyPressEvent |
Open search on Ctrl+F; close it on Escape. |
show_all_levels |
Show every line again, as Show all does. |
show_levels |
Show only records from |
show_search |
Show the search bar and put the cursor in it. |
Methods:¶
append_log
¶
Queue text for the pane; every record queued is shown.
The first record of a burst is written at once, the rest on the throttle's ticks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Text to append (may contain ANSI color codes). |
required |
|
int
|
The record's logging level, which |
NOTSET
|
append_many
¶
eventFilter
¶
eventFilter(watched: QObject, event: QEvent) -> bool
Send Shift+Enter in the search field to the previous match.
show_levels
¶
Show only records from minimum up to, not including, below.
The defaults show every line. While filtered, a bar under the log names the filter and offers Show all, and lines appended without a level stay hidden.
FXPasswordLineEdit
¶
FXPasswordLineEdit(
parent: Optional[QWidget] = None, icon_position: str = "right"
)
Bases: FXIconLineEdit
A password field whose eye icon shows or hides what was typed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
The parent widget. |
None
|
|
str
|
|
'right'
|
FXPrimaryButton
¶
FXPrimaryButton(
text: Union[str, QWidget, None] = "",
parent: Optional[QWidget] = None,
*,
icon: Optional[str] = None
)
Bases: QPushButton
The main action of a form, drawn on the theme's accent.
The look lives in the theme stylesheet under
QPushButton[fxRole="primary"], so any QPushButton given that
property matches it too.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Union[str, QWidget, None]
|
The button's label, or its parent as with QPushButton. |
''
|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
Optional[str]
|
A material icon name, drawn in the on-accent icon colour. |
None
|
Examples:
Methods:
| Name | Description |
|---|---|
enterEvent |
Draw the icon in the hover fill's ink. |
leaveEvent |
Draw the icon in the resting fill's ink. |
set_icon_name |
Draw the material icon |
FXProgressCard
¶
FXProgressCard(
parent: Optional[QWidget] = None,
title: str = "Task",
description: Optional[str] = None,
progress: int = 0,
status: Optional[int] = None,
show_percentage: bool = True,
icon: Optional[str] = None,
)
Bases: QFrame
A card showing a task's progress: a title, a bar, a status icon.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
str
|
Card title. |
'Task'
|
|
Optional[str]
|
Optional description text. |
None
|
|
int
|
Initial progress value (0-100). |
0
|
|
Optional[int]
|
Status icon type (SUCCESS, ERROR, WARNING, INFO, etc.). |
None
|
|
bool
|
Whether to show percentage text. |
True
|
|
Optional[str]
|
Optional icon name to display next to the title. |
None
|
Signals
progress_changed: Emitted when progress changes. completed: Emitted when progress reaches 100%.
Examples:
>>> card = FXProgressCard(
... title="Rendering",
... description="Frame 50/100",
... progress=50
... )
>>> card.set_progress(75)
Methods:
| Name | Description |
|---|---|
set_description |
Set the description; empty hides it. |
set_progress |
Show |
set_status |
Show severity |
set_title |
Set the card title. |
FXPygmentsHighlighter
¶
Bases: QSyntaxHighlighter
Syntax highlighter using Pygments for multi-language support.
The whole document is lexed once per change; each block then takes its slice of the tokens, and records the token type at its end as its state so Qt carries a change (an opened string) to the blocks below.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
QTextDocument
|
The QTextDocument to highlight. |
required |
|
str
|
The programming language name (e.g., "python", "javascript"). |
'python'
|
Example
highlighter = FXPygmentsHighlighter(text_edit.document(), "python")
Methods:
| Name | Description |
|---|---|
highlightBlock |
Apply the document's tokens that fall inside this block. |
language |
Return the language highlighted, "text" for an unknown one. |
refresh_formats |
Rebuild the formats for the current theme and rehighlight. |
set_language |
Highlight |
FXRangeSlider
¶
FXRangeSlider(
parent: Optional[QWidget] = None,
minimum: int = 0,
maximum: int = 100,
low: Optional[int] = None,
high: Optional[int] = None,
show_values: bool = True,
)
Bases: QWidget
A slider with two handles for a low and a high value.
Arrows move the active handle, Page keys a tenth of the range, Space switches handle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
int
|
Minimum value of the range. |
0
|
|
int
|
Maximum value of the range. |
100
|
|
Optional[int]
|
Initial low value. |
None
|
|
Optional[int]
|
Initial high value. |
None
|
|
bool
|
Whether to show value labels. |
True
|
Signals
range_changed: Emitted when either handle changes (low, high). low_changed: Emitted when the low value changes. high_changed: Emitted when the high value changes.
Examples:
>>> slider = FXRangeSlider(minimum=0, maximum=100)
>>> slider.range_changed.connect(lambda l, h: print(f"Range: {l}-{h}"))
>>> slider.set_values(25, 75)
Methods:
| Name | Description |
|---|---|
high |
Return the high value. |
keyPressEvent |
Adjust the active handle from the keyboard. |
leaveEvent |
Handle mouse leave. |
low |
Return the low value. |
minimumSizeHint |
Return the minimum size. |
mouseMoveEvent |
Handle mouse move. |
mousePressEvent |
Handle mouse press. |
mouseReleaseEvent |
Handle mouse release. |
paintEvent |
Paint the groove, the span between the handles, and the values. |
set_high |
Set the high value, held between the low value and the maximum. |
set_low |
Set the low value, held between the minimum and the high value. |
set_maximum |
Set the maximum value; the minimum and the handles follow it. |
set_minimum |
Set the minimum value; the maximum and the handles follow it. |
set_values |
Set both values, clamped; signal only what moved. |
sizeHint |
Return the preferred size. |
Methods:¶
keyPressEvent
¶
Adjust the active handle from the keyboard.
Left/Down and Right/Up move the active handle by 1, PageUp/PageDown by 10% of the range, Home/End jump it to the extremes, and Space switches between the low and high handle.
paintEvent
¶
Paint the groove, the span between the handles, and the values.
set_high
¶
set_high(value: int) -> None
Set the high value, held between the low value and the maximum.
set_low
¶
set_low(value: int) -> None
Set the low value, held between the minimum and the high value.
set_maximum
¶
set_maximum(maximum: int) -> None
Set the maximum value; the minimum and the handles follow it.
set_minimum
¶
set_minimum(minimum: int) -> None
Set the minimum value; the maximum and the handles follow it.
set_values
¶
Set both values, clamped; signal only what moved.
FXRatingWidget
¶
FXRatingWidget(
parent: Optional[QWidget] = None,
max_rating: int = 5,
initial_rating: float = 0,
allow_half: bool = False,
icon_size: int = 20,
filled_icon: str = "star",
empty_icon: str = "star_border",
half_icon: str = "star_half",
)
Bases: QWidget
A row of stars to click, with a preview under the pointer.
Arrows step the rating, digits set it, Home and End jump, Delete clears.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
int
|
Maximum number of stars. |
5
|
|
float
|
Initial rating value. |
0
|
|
bool
|
Whether to allow half-star ratings. |
False
|
|
int
|
Size of star icons in pixels. |
20
|
|
str
|
Icon name for filled stars. |
'star'
|
|
str
|
Icon name for empty stars. |
'star_border'
|
|
str
|
Icon name for half-filled stars. |
'star_half'
|
Signals
rating_changed: Emitted when the rating changes.
Examples:
>>> rating = FXRatingWidget(max_rating=5, initial_rating=3)
>>> rating.rating_changed.connect(lambda r: print(f"Rating: {r}"))
Methods:
| Name | Description |
|---|---|
clear_rating |
Clear the rating (set to 0). |
keyPressEvent |
Adjust the rating from the keyboard. |
leaveEvent |
Drop the hover preview. |
mouseMoveEvent |
Preview the rating under the pointer. |
mousePressEvent |
Handle mouse click to set rating. |
paintEvent |
Paint a focus indicator under the star labels when focused. |
rating |
Return the current rating. |
set_rating |
Set the rating, clamped and rounded; |
FXResizedScrollArea
¶
FXResizedScrollArea(
parent: Optional[QWidget] = None,
floor: Optional[int] = None,
cap: Optional[int] = None,
)
Bases: QScrollArea
A scroll area that can fit its content.
Given a floor or a cap, its minimum height is its content's height,
held between the two, and follows the content as rows come and go: the
area grows with a short list and scrolls a long one. Qt loses the
content's height a few layouts deep, so it is read here.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
Optional[int]
|
The least height, in pixels, however short the content. |
None
|
|
Optional[int]
|
The most height the content may ask for; past it, it scrolls. |
None
|
Examples:
Methods:
| Name | Description |
|---|---|
minimumSizeHint |
Return the content's height between |
viewportEvent |
Tell the layout outside when the content's height changes. |
FXSearchBar
¶
FXSearchBar(
parent: Optional[QWidget] = None,
placeholder: str = "Search...",
debounce_ms: int = 300,
)
Bases: FXIconLineEdit
A line edit with a search icon, Qt's clear button and a debounce.
It is one Tab stop: the icon and the clear button are line edit actions, which take no focus.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
str
|
Placeholder text. |
'Search...'
|
|
int
|
How long typing pauses before |
300
|
Signals
search_changed: The text, once typing pauses. search_submitted: The text, on Enter; cancels a pending change.
Examples:
>>> search = FXSearchBar(placeholder="Search assets...")
>>> search.search_changed.connect(lambda text: print(text))
FXSeating
¶
FXSeating(panel: QWidget)
Seat a panel in the screen corner nearest its tray icon; slide it in.
The corner nearest the icon, else the pointer (the icon is in the
overflow flyout), else the lower right; EDGE_GAP off both edges, as
Windows seats its own flyouts. A panel not yet on screen rises into its
seat while it fades up.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
QWidget
|
The top-level widget to seat. |
required |
Examples:
>>> seating = FXSeating(panel)
>>> tray.activated.connect(
... lambda _r: seating.show_at(tray.geometry(), QCursor.pos())
... )
Methods:
| Name | Description |
|---|---|
anchor_point |
Return the tray icon's middle, else |
center |
Centre the panel on its screen and forget the anchor. |
clamp |
Return |
popup_corner |
Return where a panel of |
screen_for |
Return the anchor's screen, else the panel's own. |
seat |
Move the panel against its last anchor at its real size. |
show_at |
Seat the panel against this anchor and bring it to the front. |
stop |
Abandon an entrance and leave the panel opaque; call on hide. |
Methods:¶
anchor_point
staticmethod
¶
Return the tray icon's middle, else cursor, else None.
clamp
staticmethod
¶
clamp(corner: QPoint, size: QSize, screen: QRect, gap: int = 0) -> QPoint
Return corner moved so a size rect sits gap inside screen.
popup_corner
classmethod
¶
Return where a panel of size puts its top-left, inside screen.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
QSize
|
The panel's real size; a never-shown panel's |
required |
|
QRect
|
|
required |
|
Optional[QPoint]
|
The pointer for a clicked show, None for an automatic one. |
required |
|
QRect
|
The target screen's |
required |
screen_for
¶
Return the anchor's screen, else the panel's own.
The anchor's, not the panel's: on two monitors the panel may be a screen away.
seat
¶
Move the panel against its last anchor at its real size.
Call from the panel's resizeEvent too. Does nothing before the
first show_at.
FXSingleInstance
¶
Bases: QObject
A lock on a local socket name; a second start wakes the first.
Put the user in name so two accounts on one machine each get their
own copy. QtNetwork is imported on claim, so a host without it can
still import fxgui.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
The socket name to hold, such as |
required |
|
Optional[QObject]
|
Parent object. |
None
|
Signals
woken: Another start asked for this copy; show the window.
Raises:
| Type | Description |
|---|---|
RuntimeError
|
From |
Examples:
>>> instance = FXSingleInstance(f"my-app-{getpass.getuser()}")
>>> if not instance.claim():
... sys.exit(0) # the running copy has been woken
>>> instance.woken.connect(window.show)
Methods:
| Name | Description |
|---|---|
claim |
Take the name, or wake the copy that holds it and return False. |
FXSingleton
¶
Bases: type(QObject)
Metaclass for Qt classes that are singletons.
A call returns the live instance, shown and raised, or builds one when
there is none or Qt has deleted it. Each subclass gets its own. A call
that finds a live instance ignores its arguments, so a menu entry can
call MyWindow(parent=host) every time; reset_instance first to
build with new ones.
Examples:
>>> from fxgui import fxwidgets
>>>
>>> class MySingletonWindow(fxwidgets.FXMainWindow, metaclass=fxwidgets.FXSingleton):
... pass
>>>
>>> window1 = MySingletonWindow()
>>> window2 = MySingletonWindow()
>>> assert window1 is window2 # Same instance
Methods:
| Name | Description |
|---|---|
reset_instance |
Forget the instance, so the next call builds a new one. |
FXSortedTreeWidgetItem
¶
Bases: QTreeWidgetItem
A row that sorts by its SORT_ROLE key, else naturally by its text.
Natural order puts "v9" before "v10". Keyed rows come before keyless
ones, so mixing the two still gives one order. A key lives on its own
role since Qt stores display and edit data together. Never
super().__lt__(): it re-enters this override through Shiboken and
recurses until segfault.
Methods:
| Name | Description |
|---|---|
__lt__ |
Compare by the sort column's key, else by its natural text. |
FXSplashScreen
¶
FXSplashScreen(
image_path: Optional[str] = None,
icon: Optional[str] = None,
title: Optional[str] = None,
information: Optional[str] = None,
show_progress_bar: bool = False,
project: Optional[str] = None,
version: Optional[str] = None,
company: Optional[str] = None,
fade_in: bool = False,
overlay_opacity: float = 1.0,
corner_radius: int = 0,
border_width: int = 0,
border_color: Optional[str] = None,
)
Bases: QSplashScreen
A splash screen: the image, a panel with the title, and a progress bar.
showMessage writes in the panel. A click hides it, as Qt's own does.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[str]
|
The image, cropped to 16:9. Defaults to fxgui's. |
None
|
|
Optional[str]
|
A path to the icon beside the title. Defaults to fxgui's. |
None
|
|
Optional[str]
|
The title. Defaults to "Untitled". |
None
|
|
Optional[str]
|
The text under the title. Defaults to |
None
|
|
bool
|
Whether the progress bar shows before
|
False
|
|
Optional[str]
|
The copyright line's project. Defaults to |
None
|
|
Optional[str]
|
The copyright line's version. Defaults to |
None
|
|
Optional[str]
|
The copyright line's company. Defaults to |
None
|
|
bool
|
Whether to fade in over a second when shown. Defaults to
|
False
|
|
float
|
The panel's opacity, 0.0 to 1.0. Defaults to 1.0. |
1.0
|
|
int
|
The corner radius, in pixels. Defaults to 0. |
0
|
|
int
|
The border width, in pixels. Defaults to 0, none. |
0
|
|
Optional[str]
|
The border color. Defaults to |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
|
Methods:
| Name | Description |
|---|---|
event |
Handle an event, skipping Qt's wait in the Show event. |
paintEvent |
Draw the image clipped to the rounded corners. |
set_progress |
Show the progress bar at |
showEvent |
Fade in over a second, if asked to. |
FXSplitButton
¶
FXSplitButton(parent: Optional[QWidget] = None)
Bases: QToolButton
A split button whose click and dropdown both have keys.
A plain MenuButtonPopup answers only Space. Enter clicks it, and
DROPDOWN_KEYS open the menu through popup, since showMenu runs an
event loop of its own.
Methods:
| Name | Description |
|---|---|
dropdown_hint |
Return |
keyPressEvent |
Click on Enter and open the menu on |
settle |
Leave the button only what it still has to do. |
sizeHint |
Return Qt's width at a push button's height. |
FXStatusBar
¶
FXStatusBar(
parent: Optional[QWidget] = None,
project: Optional[str] = None,
version: Optional[str] = None,
company: Optional[str] = None,
)
Bases: QStatusBar
Customized QStatusBar class.
The accent line and the border under it are painted along the top,
except on the frame (fxstyle.mark_as_frame) or after
hide_status_line. add_item puts FXStatusItems on the left,
before the message, which never hides them, or on the right, before
the company. set_busy(True) runs a line along the same top band,
framed or not, so waiting moves no layout.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. Defaults to |
None
|
|
Optional[str]
|
The project item's text. Defaults to |
None
|
|
Optional[str]
|
The version item's text. Defaults to |
None
|
|
Optional[str]
|
The company item's text. Defaults to |
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
icon_label |
QLabel
|
The icon label. |
message_label |
QLabel
|
The message label. |
project_label |
FXStatusItem
|
The project, plain until
|
version_label |
FXStatusItem
|
The version, likewise. |
company_label |
FXStatusItem
|
The company, likewise. |
Methods:
| Name | Description |
|---|---|
add_item |
Put |
clearMessage |
Clear the message and its tint. |
event |
Repaint when |
ground |
Return the colour the bar is painted now: a tint, or its own. |
hideEvent |
Stop the busy line's timer while nobody can see it. |
hide_status_line |
Hide the accent line and the border under it. |
is_busy |
Return whether the busy line runs. |
items |
Return every status item on the bar, shown or not. |
paintEvent |
Paint the bar, then its accent line or busy line along the top. |
set_busy |
Run the busy line along the top edge, or stop it. |
set_status_line_colors |
Paint the accent line as a gradient from |
showEvent |
Run the busy line again, if it ran when the bar hid. |
showMessage |
Display a message in the status bar with a specified severity. |
show_status_line |
Show the accent line and border, unless the bar is on the frame. |
show_tip |
Write a hover tip where messages go, after the items. |
tint |
Return the colour a message tints the bar now, or |
Methods:¶
add_item
¶
add_item(item: FXStatusItem, side: str = 'left') -> None
Put item on the bar, after the items already on that side.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
FXStatusItem
|
The item to add. |
required |
|
str
|
"left", before the message, or "right", before the company. |
'left'
|
Raises:
| Type | Description |
|---|---|
ValueError
|
|
paintEvent
¶
Paint the bar, then its accent line or busy line along the top.
set_status_line_colors
¶
Paint the accent line as a gradient from color_a to color_b.
showMessage
¶
showMessage(
message: str,
severity_type: int = INFO,
duration: float = 2.5,
time: bool = True,
logger: Optional[Logger] = None,
set_color: bool = True,
)
Display a message in the status bar with a specified severity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
The message to be displayed. |
required |
|
int
|
The severity level of the message.
Should be one of |
INFO
|
|
float
|
The duration in seconds for which
the message should be displayed. Defaults to |
2.5
|
|
bool
|
Whether to display the current time before
the message. Defaults to |
True
|
|
Logger
|
A logger object to log the message.
Defaults to |
None
|
|
bool
|
Whether to tint the bar in the severity's
colors until the message goes. Defaults to |
True
|
Examples:
To display a critical error message with a red background
show_status_line
¶
Show the accent line and border, unless the bar is on the frame.
FXStatusDot
¶
Bases: QWidget
A filled circle in a feedback colour, or grey for no state.
Grey rather than a colour for off: every feedback colour is saturated, and a coloured dot reads as a state, not its absence.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
int
|
The circle's size in pixels. |
8
|
Signals
clicked: A left-button release landed on the dot.
Examples:
Methods:
| Name | Description |
|---|---|
color |
Return the colour the dot paints in now. |
mouseReleaseEvent |
Emit |
paintEvent |
Fill one antialiased circle, inset half a pixel so no edge is cut. |
set_feedback |
Show feedback |
FXStatusItem
¶
FXStatusItem(
text: str = "",
icon: Optional[str] = None,
parent: Optional[QWidget] = None,
clickable: bool = True,
)
Bases: QToolButton
An icon and a word on a status bar, flat, lit when it is clickable.
Painted against the bar as the bar is painted at that moment, a message's tint included, so its ink always reads. Hidden while it has no text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
The word shown. Defaults to |
''
|
|
Optional[str]
|
An fxicons icon name. Defaults to |
None
|
|
Optional[QWidget]
|
Parent widget. Defaults to |
None
|
|
bool
|
Whether a click does something; otherwise plain text
that takes no mouse. Defaults to |
True
|
Examples:
>>> item = FXStatusItem("3", "warning")
>>> window.statusBar().add_item(item)
>>> item.clicked.connect(show_log)
Methods:
| Name | Description |
|---|---|
ground |
Return the colour the item is drawn on now. |
ink |
Return the word's colour on the ground the item is drawn on now. |
minimumSizeHint |
Return |
paintEvent |
Paint the hover fill, the icon and the word against the bar. |
setText |
Show |
set_clickable |
Make a click do something, or make the item plain text. |
set_tip |
Say what the item is and what its click does. |
show_state |
Show |
sizeHint |
Return the icon, the word and the side padding. |
Methods:¶
set_clickable
¶
set_clickable(clickable: bool) -> None
Make a click do something, or make the item plain text.
set_tip
¶
Say what the item is and what its click does.
show_state
¶
Show text beside icon, muted or in a feedback tone.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
The word shown. |
required |
|
str
|
An fxicons icon name. |
required |
|
bool
|
Whether the word takes the muted ink. |
False
|
|
str
|
A feedback level ("error", "warning", ...) for the icon,
or |
''
|
FXSystemTray
¶
Bases: QSystemTrayIcon
A tray icon whose menu opens on a left click too, ending in Quit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QObject]
|
The parent object. Defaults to |
None
|
|
Optional[Union[str, QIcon]]
|
The tray icon: a path to an image, or a |
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
quit_action |
QAction
|
Quits an |
Examples:
>>> app = FXApplication()
>>> tray = FXSystemTray()
>>> menu = tray.contextMenu()
>>> menu.insertAction(tray.quit_action, QAction("Set Project", menu))
>>> tray.show()
>>> app.exec()
Methods:
| Name | Description |
|---|---|
quit |
Quit the application, unless it is a host fxgui does not own. |
FXTagChip
¶
Bases: QFrame
A single removable tag chip.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
The tag text. |
required |
|
Optional[QWidget]
|
Parent widget. |
None
|
|
bool
|
Whether the chip can be removed. |
True
|
Signals
removed: Emitted when the remove button is clicked.
Methods:
| Name | Description |
|---|---|
text |
Return the tag text. |
FXTagInput
¶
FXTagInput(
parent: Optional[QWidget] = None,
placeholder: str = "Add tag and press Enter...",
max_tags: int = 0,
allow_duplicates: bool = False,
)
Bases: QWidget
A field whose Enter turns the text into a chip; a chip's x removes it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
str
|
Placeholder text for the input field. |
'Add tag and press Enter...'
|
|
int
|
Maximum number of tags allowed (0 = unlimited). |
0
|
|
bool
|
Whether duplicate tags are allowed. |
False
|
Signals
tags_changed: Emitted when tags are added or removed. tag_added: Emitted when a single tag is added. tag_removed: Emitted when a single tag is removed.
Examples:
>>> tag_input = FXTagInput(placeholder="Add tags...")
>>> tag_input.tags_changed.connect(lambda tags: print(f"Tags: {tags}"))
>>> tag_input.add_tag("python")
>>> tag_input.add_tag("qt")
Methods:
| Name | Description |
|---|---|
add_tag |
Add |
clear_tags |
Remove all tags. |
remove_tag |
Remove the first chip reading |
set_tags |
Replace the tags, saying |
tags |
Return the current tags, in order. |
FXThreadLine
¶
FXThreadLine(thread: QWidget)
Bases: QWidget
A line over a thread, from a comment's face into each reply's face.
Laid over the thread and blind to the mouse, so it crosses the cards' borders; it follows the thread's size and the faces' moves.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
QWidget
|
The widget holding the comment and its replies. |
required |
Examples:
Methods:
| Name | Description |
|---|---|
eventFilter |
Follow the thread's size, and a face that moves or hides. |
join |
Draw the line from under |
paintEvent |
Draw the line in the theme's border colour. |
path |
Return the line: down from the head, an elbow into each face. |
FXThumbnailDelegate
¶
FXThumbnailDelegate(parent: Optional[QWidget] = None)
Bases: QStyledItemDelegate
Paint rows as a thumbnail, a title, a description and status marks.
Column 0 is laid out from both edges: the thumbnail (or the decoration
icon) at the left, then the title and the description (Markdown,
shown as plain text), and the status pill and dot anchored to the
right edge with the child count badge under them. The text stops short
of all three. A row with a Qt.BackgroundRole is drawn as a card.
Note
Item roles:
- Qt.BackgroundRole (QColor, QBrush or token name): the card
fill, rounded with a border_light edge.
- Qt.DecorationRole (QIcon): the icon of a row without a
thumbnail, or an overlay on the thumbnail.
- THUMBNAIL_VISIBLE_ROLE (bool), THUMBNAIL_PATH_ROLE (str).
- DESCRIPTION_ROLE (str, Markdown).
- STATUS_DOT_COLOR_ROLE, STATUS_LABEL_COLOR_ROLE (QColor or
token name), STATUS_LABEL_TEXT_ROLE (str).
- STATUS_DOT_VISIBLE_ROLE, STATUS_LABEL_VISIBLE_ROLE,
CHILD_COUNT_VISIBLE_ROLE (bool).
- PICKER_TEXT_ROLE (str), PICKER_CHOICES_ROLE
(Sequence[str]), PICKER_UNAVAILABLE_ROLE (Mapping[str, str],
a listed choice that cannot be picked, to its reason).
A view that stamps roles of its own on the same items derives them
from FIRST_FREE_ROLE.
Note
An element shows when its delegate flag (show_thumbnail,
show_status_dot, show_status_label) is True and its per-item
visible role is not False.
Note
The right-anchored marks walk left as column 0 narrows.
apply_minimum_thumbnail_width(view) stops the column before they
reach the thumbnail; sizeHint reports the same floor.
Examples:
>>> tree = QTreeWidget()
>>> tree.setItemDelegate(fxwidgets.FXThumbnailDelegate())
>>> item = QTreeWidgetItem(tree, ["My Item"])
>>> item.setData(0, FXThumbnailDelegate.THUMBNAIL_PATH_ROLE, path)
>>> item.setData(0, FXThumbnailDelegate.DESCRIPTION_ROLE, "**Bold**")
>>> item.setData(0, FXThumbnailDelegate.STATUS_DOT_COLOR_ROLE, "feedback_success_foreground")
>>> item.setData(0, Qt.BackgroundRole, "surface")
Methods:
| Name | Description |
|---|---|
apply_minimum_thumbnail_width |
Keep one column from being dragged below what its rows need. |
apply_transparent_selection |
Hand a view's row fill, selection and hover to the delegate. |
editorEvent |
Open a row's picker on a click inside its pill. |
has_focus_ring |
Whether the focus ring is drawn on this cell. |
paint |
Paint the cell: its fill or card, hover or selection, content, ring. |
sizeHint |
Return the row's size, measured with the item's own font. |
Attributes:
| Name | Type | Description |
|---|---|---|
focus_ring |
str
|
Whether the ring outlines the current |
Attributes¶
focus_ring
property
writable
¶
focus_ring: str
Whether the ring outlines the current "row" or "cell".
Methods:¶
apply_minimum_thumbnail_width
classmethod
¶
Keep one column from being dragged below what its rows need.
The floor is the thumbnail's span plus the widest status marks the
laid-out rows show. setMinimumSectionSize cannot serve: it applies
to every section. A second call on the same column replaces the
first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
QWidget
|
The tree view whose header is guarded. |
required |
|
int
|
The column to guard. |
0
|
|
int
|
A width the column never goes below, even when empty. |
0
|
Examples:
apply_transparent_selection
staticmethod
¶
apply_transparent_selection(view: QWidget) -> None
Hand a view's row fill, selection and hover to the delegate.
Marks the view for the registered rule that clears Qt's own highlight, and installs a style that skips the native row panel and focus rect, which Windows 11 draws under the delegate's ring.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
QWidget
|
A view painted by |
required |
editorEvent
¶
editorEvent(event, model, option, index) -> bool
Open a row's picker on a click inside its pill.
Everything else goes to the base class, which toggles the painted check box.
paint
¶
Paint the cell: its fill or card, hover or selection, content, ring.
sizeHint
¶
Return the row's size, measured with the item's own font.
FXTimelineSlider
¶
FXTimelineSlider(
parent: Optional[QWidget] = None,
start_frame: int = 1,
end_frame: int = 100,
current_frame: Optional[int] = None,
fps: float = 24,
show_controls: bool = True,
show_spinbox: bool = True,
show_loop_controls: bool = False,
show_keyframe_controls: bool = False,
controls_position: str = "left",
show_range: bool = True,
show_fps: bool = True,
own_clock: bool = True,
)
Bases: QWidget
A timeline/scrubber widget for DCC applications.
- Keyframe markers and a current frame indicator, with optional playback controls.
- Keys while the timeline has focus: Home, Left, Space, Right and End; I and O with the in/out controls.
- Track zoom: the mouse wheel zooms around the cursor, a middle-mouse
drag pans,
reset_view()restores the full range. - Named marker layers (lines or a top strip) and named regions, mapped through the zoomed window. The widget assigns no meaning to a layer.
- Optional in/out controls (
show_loop_controls) that request marking the current frame; the consumer typically callsset_loop_region. - Optional keyframe navigation (
show_keyframe_controls). - A hover line with the hovered frame number.
- Narrow, the "below" layout drops the go-to-start and go-to-end buttons, then the frame field, so the transport keeps one row.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
int
|
Start frame of the timeline. |
1
|
|
int
|
End frame of the timeline. |
100
|
|
Optional[int]
|
Initial current frame. |
None
|
|
float
|
Frames per second for playback; fractional rates such as 23.976 play at that rate. |
24
|
|
bool
|
Whether to show playback controls. |
True
|
|
bool
|
Whether to show the frame spinbox. |
True
|
|
bool
|
Whether to show the mark-in/mark-out buttons. |
False
|
|
bool
|
Whether to show the previous/next-keyframe navigation buttons. |
False
|
|
str
|
"left" (one row) or "below" (full-width track on top, the transport centred below, fps far left, consumer extras from add_control_widget() far right). |
'left'
|
|
bool
|
Whether to show the start and end frame fields, and the view fields of the "below" layout; a player's range is fixed. |
True
|
|
bool
|
Whether to show the frame rate field. |
True
|
|
bool
|
Whether playback advances the frame. False for a
consumer that keeps time itself, such as a movie: play and stop
only switch the button and emit, the consumer moves the
playhead with |
True
|
Raises:
| Type | Description |
|---|---|
ValueError
|
|
Signals
frame_changed: Emitted when the current frame changes. playback_started: Emitted when playback starts. playback_stopped: Emitted when playback stops. view_changed: Emitted with (first, last) when the visible frame window changes (zoom, pan, or reset). in_point_requested: Mark-in pressed; carries the current frame. out_point_requested: Mark-out pressed; carries the current frame. loop_toggled: Emitted with the new loop playback state.
Examples:
>>> timeline = FXTimelineSlider(start_frame=1, end_frame=100)
>>> timeline.frame_changed.connect(lambda f: print(f"Frame: {f}"))
>>> timeline.add_keyframe(10)
>>> timeline.set_marker_frames(
... "cached", {2, 3, 4}, "feedback_success_foreground", "strip")
>>> timeline.set_marker_frames("errors", {40, 41}, "#ef4444")
>>> timeline.set_loop_region(20, 60)
Methods:
| Name | Description |
|---|---|
add_control_widget |
Append a consumer widget to the right of the controls. |
add_keyframe |
Mark |
clear_keyframes |
Remove all keyframe markers. |
clear_region |
Remove a named region (no-op if absent). |
current_frame |
Return the current frame. |
fps |
Return the playback frame rate. |
frame_range |
Return the frame range as (start, end). |
go_to_end |
Go to the end frame. |
go_to_next_keyframe |
Jump to the nearest keyframe after the current frame, if any. |
go_to_previous_keyframe |
Jump to the nearest keyframe before the current frame, if any. |
go_to_start |
Go to the start frame. |
is_view_zoomed |
Return whether the track shows a sub-window of the full range. |
keyPressEvent |
Run the transport key the buttons' tips name. |
loop_playback |
Return whether playback wraps to the start at the end. |
next_frame |
Advance to the next frame. |
play |
Start playback. |
previous_frame |
Go to the previous frame. |
remove_keyframe |
Unmark |
remove_markers |
Remove a named marker layer (no-op if absent). |
reset_view |
Restore the track to the full frame range. |
resizeEvent |
Drop or restore the optional controls for the new width. |
set_fps |
Set the rate, held to 1-120; fractional rates such as 23.976 hold. |
set_frame |
Set the frame, clamped; |
set_loop_playback |
Set whether playback wraps to the start at the end. |
set_loop_region |
Show the loop in/out range as the bracketed "loop" region. |
set_marker_frames |
Set (or replace) a named marker layer painted on the track. |
set_range |
Set the range from |
set_region |
Set (or replace) a named frame region painted on the track. |
set_view_range |
Zoom the track to the [first, last] frame window. |
stop |
Stop playback. |
toggle_playback |
Toggle playback state. |
track_rect |
Return where the track draws its frames, in this widget's pixels. |
view_range |
Return the visible window as (first, last); the range unzoomed. |
zoom_view |
Zoom in |
Methods:¶
add_control_widget
¶
Append a consumer widget to the right of the controls.
go_to_next_keyframe
¶
Jump to the nearest keyframe after the current frame, if any.
go_to_previous_keyframe
¶
Jump to the nearest keyframe before the current frame, if any.
is_view_zoomed
¶
is_view_zoomed() -> bool
Return whether the track shows a sub-window of the full range.
keyPressEvent
¶
Run the transport key the buttons' tips name.
set_fps
¶
set_fps(fps: float) -> None
Set the rate, held to 1-120; fractional rates such as 23.976 hold.
set_frame
¶
Set the frame, clamped; emit says frame_changed.
set_loop_playback
¶
set_loop_playback(enabled: bool) -> None
Set whether playback wraps to the start at the end.
set_loop_region
¶
Show the loop in/out range as the bracketed "loop" region.
None for either end clears it.
set_marker_frames
¶
set_marker_frames(
name: str,
frames: Iterable[int],
color: Optional[str] = None,
style: str = "line",
) -> None
Set (or replace) a named marker layer painted on the track.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Layer identifier; setting the same name replaces it. |
required |
|
Iterable[int]
|
Iterable of frame numbers. Empty removes the layer. |
required |
|
Optional[str]
|
A theme token such as "feedback_success_foreground", or any QColor value. Read when painted, so a token follows a theme switch; None is the accent. |
None
|
|
str
|
"line" for 1px vertical lines at each frame, or "strip" for a translucent band along the top edge with a 1px solid top line over contiguous frame runs. |
'line'
|
Raises:
| Type | Description |
|---|---|
ValueError
|
|
set_range
¶
Set the range from start to end, clamping the frame and view.
set_region
¶
set_region(
name: str,
start: int,
end: int,
color: Optional[str] = None,
bracket_edges: bool = False,
) -> None
Set (or replace) a named frame region painted on the track.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Region identifier; setting the same name replaces it. |
required |
|
int
|
First frame of the region. |
required |
|
int
|
Last frame of the region. |
required |
|
Optional[str]
|
A theme token or any QColor value, read when painted; None is the accent. |
None
|
|
bool
|
Draw the edges as [ ] brackets, so a zero-width region still reads as a marker. |
False
|
set_view_range
¶
Zoom the track to the [first, last] frame window.
The window is clamped inside the full range; a window covering the full range (or more) resets the view.
track_rect
¶
Return where the track draws its frames, in this widget's pixels.
The left edge is the first frame of view_range(), the right edge
the last, so another widget can line its own frames up with them.
view_range
¶
Return the visible window as (first, last); the range unzoomed.
FXToggleSwitch
¶
FXToggleSwitch(
parent: Optional[QWidget] = None,
on_color: Optional[str] = None,
off_color: Optional[str] = None,
thumb_color: Optional[str] = None,
)
Bases: QAbstractButton
An on/off switch that slides, as tall as a push button.
Its edge and thumb read at fxstyle.CONTROL_CONTRAST on every theme;
hover, focus and disabled wear the push button's tokens.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
Parent widget. |
None
|
|
Optional[str]
|
A theme token or a colour, when on. Defaults to the accent. |
None
|
|
Optional[str]
|
A token or a colour, when off. Defaults to the sunken surface. |
None
|
|
Optional[str]
|
A token or a colour for the thumb. Defaults to the muted text off and the on-accent text on. |
None
|
Signals
toggled: Emitted when the switch state changes.
Examples:
>>> switch = FXToggleSwitch()
>>> switch.toggled.connect(lambda checked: print(f"Switch: {checked}"))
>>> switch.setChecked(True)
Methods:
| Name | Description |
|---|---|
enterEvent |
Repaint to show the hover state. |
hitButton |
Return True if pos is inside the clickable area. |
leaveEvent |
Repaint to hide the hover state. |
minimumSizeHint |
Return the minimum size of the switch. |
paintEvent |
Paint the track, its edge and the thumb. |
position |
Set the animation position and trigger repaint. |
sizeHint |
Return the preferred size of the switch. |
track_rect |
Return the track: the indicator size tall, centred in the widget. |
FXValidatedLineEdit
¶
FXValidatedLineEdit(
parent: Optional[QWidget] = None,
shake_amplitude: int = 4,
shake_duration: int = 300,
flash_duration: int = 400,
)
Bases: QLineEdit
A line edit that provides visual feedback when input is rejected.
When a validator rejects input (e.g., typing an invalid character), this widget shakes briefly and flashes a border in the theme's error colour. The flash is painted over the field, so the caller's own stylesheet and text margins are left as they were.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Optional[QWidget]
|
The parent widget. |
None
|
|
int
|
Maximum horizontal displacement in pixels. |
4
|
|
int
|
Total duration of shake animation in milliseconds. |
300
|
|
int
|
Duration of red border flash in milliseconds. |
400
|
Examples:
>>> from qtpy.QtWidgets import QLineEdit
>>> from fxgui.fxwidgets import FXValidatedLineEdit, FXCamelCaseValidator
>>> line_edit = FXValidatedLineEdit()
>>> line_edit.setValidator(FXCamelCaseValidator())
>>> line_edit.setPlaceholderText("camelCase only")
Methods:
| Name | Description |
|---|---|
keyPressEvent |
Shake when a typed character changed nothing: it was rejected. |
paintEvent |
Paint the field, then the rejection flash over its border. |
Functions:¶
align_labels
¶
Give the labels of every form in forms one right-aligned column.
Qt shares no label column across form layouts.
apply_tip
¶
Set a rich tooltip on target, plus a markup-free status tip.
The tooltip is rebuilt each time it shows, in the theme in force.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
A widget, an action, or an item already in its list, tree or table widget; a tree item gets the tip on every column. |
required | |
|
str
|
What the control is, in a couple of words. |
required |
|
str
|
What the control does. Defaults to |
''
|
|
str
|
A Qt key sequence, such as |
''
|
Raises:
| Type | Description |
|---|---|
ValueError
|
|
Examples:
Note
The status tip carries the same words without markup. Qt shows it in the window's status bar on hover, which is where a person looks for "what is this" before a tooltip has had time to appear. The title and body also become the accessible name and description; a later call replaces them, but never a name set by hand.
code_color
¶
Return the colour code highlighting gives token in the current theme.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
A Pygments token name, such as "String", "Number" or "Name.Function"; one the style leaves uncoloured takes its parent's colour, else the theme's text colour. |
required |
Examples:
fix_wrapped_heights
¶
Give every word-wrapped label under widget the height its width needs.
Qt loses a label's height-for-width a few layouts deep and clips its
last lines. Call after the labels have their width, and again from the
holder's resizeEvent.
grab_screen_region
¶
Let the user drag out a region of window's screen; None on Escape.
window is hidden for the grab and shown again afterwards, whatever
happens. Closing the last window is kept from quitting the
application meanwhile: with window hidden, the overlay is the last.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
QWidget
|
The window to take out of the picture. |
required |
Returns:
| Type | Description |
|---|---|
Optional[QPixmap]
|
The region as a pixmap, or None when cancelled or no screen exists. |
keycap
¶
Render a keyboard shortcut as rich text, one keycap per key.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
A Qt key sequence, such as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
HTML for the keycaps, or an empty string when |
Examples:
Note
The HTML holds the current theme's colours; a keycap on a window is
an FXKeycap.
tip
¶
Build the HTML for a rich tooltip.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
What the control is, in a couple of words. Sentence case, no trailing period, it is a label and not a sentence. |
required |
|
str
|
What the control does, or why it is unavailable; a newline
breaks the line. Defaults to |
''
|
|
str
|
A Qt key sequence, such as |
''
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
HTML to hand to |
Examples:
>>> tip("", "", "")
''
>>> button.setToolTip(
... tip("Save", "Write the scene to disk", "Ctrl+S")
... )
Note
The HTML holds the current theme's colours: call it when the tip
shows, as a model's data(ToolTipRole) does, or use apply_tip.
Every caller string is HTML-escaped, so a path or a name holding
& or < reaches the user as text instead of corrupting the markup.
Qt ignores max-width and applies a table width as a fixed width,
so there is no width cap: the tooltip wraps itself, up to 440 px.