Skip to content

Widgets

Subclass the FXMainWindow

You can subclass any widgets in the fxwidgets module. Here's a practical example with FXMainWindow:

# Third-party
from qtpy.QtWidgets import QWidget, QVBoxLayout, QPushButton

# Internal
from fxgui import fxwidgets, fxicons


class MyWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.add_layout()
        self.add_buttons()

    def add_layout(self):
        """Adds a vertical layout to the main layout of the widget."""

        self.main_layout = QVBoxLayout()
        self.setLayout(self.main_layout)

    def add_buttons(self):
        """Adds buttons to the main layout of the widget."""

        # Use fxicons for theme-aware icons
        home_button = QPushButton("Home")
        fxicons.set_icon(home_button, "home")

        settings_button = QPushButton("Settings")
        fxicons.set_icon(settings_button, "settings")

        self.main_layout.addWidget(home_button)
        self.main_layout.addWidget(settings_button)
        self.main_layout.addStretch()


class MyWindow(fxwidgets.FXMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setCentralWidget(MyWidget(parent=self))
        self.adjustSize()


application = fxwidgets.FXApplication()
window = MyWindow()
window.setWindowTitle("Subclassed FXMainWindow")
window.show()
application.exec()
python -m fxgui.examples

A window opens with every public widget, a page per kind: buttons, inputs, display, containers, lists and trees, the timeline, windows and dialogs, and docking. Each box is titled with the class names it shows. Window > Theme switches the theme, so you can see a widget in each. The Docking page needs PySide6-QtAds (see Installation).

Available Widgets

The fxwidgets module holds these classes:

Class What it is
FXAccordion Collapsible sections stacked; one open at a time unless exclusive=False
FXApplication The QApplication that themes every window it owns
FXAvatar Round avatar: a photo, or initials on a disc coloured by the name
FXBreadcrumb Clickable breadcrumb trail; double-click it to type a path
FXCamelCaseValidator Accepts camelCase letters only
FXCapitalizedLetterValidator Accepts a name starting with a capital letter
FXCheckableComboBox Combo box whose popup stays open while several rows are ticked
FXCodeBlock Read-only code with syntax highlighting
FXCollapsibleWidget A titled section that opens and shuts its content
FXCommand One row of an FXCommandPalette: a label, a callable or a list of choices, keys, a section
FXCommandPalette Popup search over a window's commands, or over rows to go to; the commands run lately come first
FXCommandRow A toolbar fixed in place, whose margins survive style changes
FXConfirmDeleteDialog Asks for a name typed exactly before an act with no undo; Enter never deletes
FXDropZone Drop target for files or folders, with a browse button and a file list
FXElidedLabel Label that cuts its text with "..." when it does not fit
FXEmojiButton Round icon button that opens an FXEmojiPicker and can insert into an editor
FXEmojiPicker Popup grid of emoji, keyboard navigable
FXFilePathWidget File or folder path field with a browse button
FXFilteredTree An FXKeyboardTree under a filter bar, with expand-all and collapse-all; actions= puts a row of buttons under the tree
FXFloatingDialog Dialog that opens at the pointer
FXFlowLayout Layout that wraps its widgets onto new lines, like words
FXIconButton Round icon button; checkable, filled with the accent when checked
FXIconLabel Label that draws an icon in the theme's colours at paint time
FXIconLineEdit Line edit with an icon on the left or right
FXJoinedGroup Widgets side by side in one pill outline, such as a status and a Post button
FXKeyboardTree Tree whose row menus, Enter and typing work from the keyboard
FXKeycap A shortcut drawn as keys, one cap per key, round at the button radius; follows every theme switch
FXLettersUnderscoreValidator Accepts letters and underscores, numbers optional
FXLoadingOverlay Spinner over a widget, dimming it and blocking its input
FXLoadingSpinner Animated loading indicator: spinner, dots or pulse
FXLowerCaseValidator Accepts lowercase letters, numbers and underscores optional
FXMainWindow Main window with menus, toolbar, status bar and a theme menu
FXMentionEdit Text box that offers people by name after an @ and lists who it names
FXNotificationBanner Card with a message that slides in from a window's right edge
FXOutputLogHandler Logging handler that writes records into an FXOutputLogWidget
FXOutputLogWidget Read-only log display with search
FXPasswordLineEdit Password field with a show/hide eye icon
FXPrimaryButton The main action of a form, on the theme's accent
FXProgressCard Card showing a task's progress and status
FXPygmentsHighlighter Pygments syntax highlighter for any QTextDocument
FXRangeSlider Slider with two handles for a low and a high value
FXRatingWidget Star rating input, halves optional
FXResizedScrollArea Scroll area whose height follows its content, between a floor and a cap
FXSearchBar Search field with a clear button and a debounced search signal
FXSeating Seats a tray panel in the screen corner nearest its icon and slides it in
FXSingleInstance Lock on a local socket name; a second start wakes the first
FXSingleton Metaclass for Qt classes that have one instance
FXSortedTreeWidgetItem Tree row that sorts numbers in text naturally (v2 before v10)
FXSplashScreen Splash screen with a title, a text and a progress bar
FXSplitButton Split button whose click and dropdown both have keys
FXStatusBar Status bar with an accent line, messages, items and a busy line
FXStatusDot Small clickable circle in a feedback colour, grey for no state
FXStatusItem Icon and word on a status bar, lit when clickable
FXSystemTray System tray icon with a menu
FXTagChip One tag, removable or not
FXTagInput Field that turns what you type into FXTagChips
FXThreadLine Line over a comment thread, from the comment's face into each reply's
FXThumbnailDelegate Item delegate with thumbnails, status dots, labels and stars
FXTimelineSlider Timeline with playback, keyframes, markers and a loop region
FXToggleSwitch On/off switch that slides
FXValidatedLineEdit Line edit that shakes and flashes when its validator refuses a key

fxdocking.FXDockArea docks named panes around a body; it needs PySide6-QtAds (see Installation).

And these functions and constants:

Name What it does
align_labels Gives the labels of several forms one right-aligned column
apply_tip Sets a rich tooltip and a plain status tip on a widget, an action or a view's item (see Tooltips)
fix_wrapped_heights Gives every word-wrapped label under a widget the height its width needs
grab_screen_region Lets the user drag out a screen region and returns it, or None on Escape
keycap Renders a shortcut as keys in a tooltip's HTML; on a window, use FXKeycap
tip Returns the HTML apply_tip shows, in the theme in force
DEFAULT_EMOJIS The emoji an FXEmojiPicker offers by default
CRITICAL, ERROR, WARNING, SUCCESS, INFO, DEBUG Severities for messages, banners and progress cards

Tip

Every widget follows a theme switch with no call of its own.

from fxgui.fxwidgets import FXBreadcrumb

crumb = FXBreadcrumb(home_icon="", tab_stops=False)
crumb.set_path(["pilot", "sq010", "sh0040", "comp"])
crumb.set_edit_placeholder("Type a shot")
  • Every segment but the last is a button: it tints under the pointer and shows a pointing hand. The last one is where the path already is, so it is bold and does nothing.
  • The strip behind the segments is a filled field, brighter while the pointer is over it. Double-click it to type a path; a press anywhere outside closes the editor, and so does exit_edit_mode().
  • The colours are worked out each time the strip paints, from the theme and from what the breadcrumb sits on: the frame colour on a framed window's toolbar or a band marked with mark_as_frame, the surface anywhere else. The text reads at 4.5:1 on both fills and the edge shows at 1.3:1 against the ground and both fills, in every bundled theme. A theme switch needs no call.
  • tab_stops=False takes the segments and the back and forward buttons out of the Tab order. The path editor keeps its stop.

The starting colours are class attributes, so a subclass names its own tokens:

from fxgui.fxwidgets import FXBreadcrumb


class HouseCrumb(FXBreadcrumb):
    STRIP_RESTING_TOKEN = "surface_alt"
    SEGMENT_HOVER_TOKEN = "text_muted"
    SEGMENT_HOVER_ALPHA = 48

Do not point STRIP_RESTING_TOKEN at surface: in every bundled theme that is the window's own colour, so on a plain window the strip disappears.

Your Own Item-Data Roles

FXThumbnailDelegate reads item-data roles of its own off the items it paints, from Qt.UserRole + 1 up to FIRST_FREE_ROLE, and FXSortedTreeWidgetItem.SORT_ROLE sits in the same range. A view that puts roles of its own on the same items derives them from FIRST_FREE_ROLE:

from fxgui.fxwidgets import FXThumbnailDelegate

ROW_KIND_ROLE = FXThumbnailDelegate.FIRST_FREE_ROLE
ROW_COLOR_ROLE = FXThumbnailDelegate.FIRST_FREE_ROLE + 1

Warning

Do not guess a number instead. Every number below FIRST_FREE_ROLE is one the delegate reads: a view storing its own value on CHILD_COUNT_VISIBLE_ROLE's number gets a child count drawn on rows with no children.

A role added to the delegate moves FIRST_FREE_ROLE up, and every role derived from it moves too.

Tooltips

apply_tip is fxgui's tooltip. It hands Qt's own setToolTip a small HTML string, and sets a markup-free status tip for the window's status bar:

from qtpy.QtWidgets import QPushButton
from fxgui.fxwidgets import apply_tip

save_button = QPushButton("Save")
apply_tip(
    save_button,
    "Save",
    "Write the current scene to disk, overwriting the last version",
    "Ctrl+S",
)

The title is in the theme's primary text, the body dimmed, and the shortcut sits on the right as keycaps, one per key: Ctrl S. The keys of one chord sit close; a second chord (Ctrl+K, Ctrl+S) sits further away. Key names come from QKeySequence, so a Mac shows its own glyphs rather than the word "Ctrl".

Target What happens
A widget The tip is rebuilt each time it is about to show
A QAction The tip is rebuilt when the action is hovered, before its tool button or menu shows it
An item of a QListWidget, QTreeWidget or QTableWidget The view builds the tip when it shows; a tree item gets it on every column. Add the item to its view first, or apply_tip raises ValueError

The HTML holds the colours of the theme in force, so rebuilding at show time is what makes a tip set in one theme show in the next. Every string is HTML-escaped, so a path holding & or < reaches the user as text, and a newline in the body breaks the line. Qt's rich text draws no rounded background, so a keycap in a tooltip is square.

Two lower-level helpers:

  • tip() returns the HTML. Call it when the tip shows: a model returns tip(...) from data() for Qt.ToolTipRole, which Qt asks for on hover.
  • keycap() returns a shortcut's keycaps as HTML. A label reads its text once, so a keycap on a window is an FXKeycap instead: a widget, one cap per key, round at the button radius, that follows every theme switch.