Skip to content

fxstyle

fxstyle

Styling, theming, and color management for fxgui.

This module provides comprehensive styling functionality including
  • Multiple theme support with dynamic theme switching
  • Theme persistence across application restarts (via fxconfig)
  • QSS stylesheet loading with dynamic color replacement
  • Custom QProxyStyle for standard icon overrides
  • Theme toggling with icon cache invalidation
  • Color loading from YAML configuration files with inheritance support

Theme Color Reference

Each theme in style.yaml defines these semantic color roles:

Accent Colors (interactive highlights): - accent_primary: Hover borders, selections, progress gradients (end) - accent_secondary: Gradient starts, item hover backgrounds

Surface Colors (backgrounds): - surface: Main widget/window backgrounds, buttons, selected tabs - surface_alt: Alternate row backgrounds in lists/tables - surface_sunken: Recessed areas - inputs, lists, menus, status bar - tooltip: Tooltip backgrounds

Border Colors: - border: Standard borders on inputs, containers, menus - border_light: Subtle borders - tooltips, buttons, tabs - border_strong: Emphasized borders - frames, separators

Text Colors: - text: Primary text for all widgets - text_muted: De-emphasized text - inactive tabs, placeholders - text_disabled: Disabled widget text - text_on_accent_primary: Text on accent_primary backgrounds (optional, auto-computed) - text_on_accent_secondary: Text on accent_secondary backgrounds (optional, auto-computed)

Interactive States: - state_hover: Hover state backgrounds - state_pressed: Pressed/checked/active backgrounds

Scrollbar: - scrollbar_track: Track/gutter background - scrollbar_thumb: Draggable thumb - scrollbar_thumb_hover: Thumb hover state

Layout: - grid: Table gridlines, header borders - separator: Separator/splitter hover backgrounds

Slider: - slider_thumb: Slider handle color - slider_thumb_hover: Slider handle hover/pressed

Icon: - icon: Monochrome icon tint color

Classes:

Name Description
FXProxyStyle

Custom style providing Material Design icons for Qt standard icons.

FXThemeManager

Singleton that emits signals when theme changes.

FXThemeAware

Mixin for widgets that auto-update on theme changes.

Functions:

Name Description
load_stylesheet

Load and customize QSS stylesheets.

get_colors

Get the cached color configuration.

set_color_file

Set a custom color configuration file.

apply_theme

Apply a theme to a widget (stylesheet + icons).

get_available_themes

Get list of available theme names.

get_theme

Get the current theme name.

get_theme_colors

Get the color palette for the current theme.

get_accent_colors

Get primary/secondary accent colors.

get_icon_color

Get the icon tint color for current theme.

is_light_theme

Check if the current theme is light or dark.

save_theme

Save the current theme to persistent storage.

load_saved_theme

Load the previously saved theme.

Constants

STYLE_FILE: Path to the default QSS stylesheet. DEFAULT_COLOR_FILE: Path to the default color configuration.

Examples:

Loading a stylesheet with a theme:

>>> from fxgui import fxstyle
>>> stylesheet = fxstyle.load_stylesheet(theme="dracula")
>>> widget.setStyleSheet(stylesheet)

Applying a theme to a window:

>>> fxstyle.apply_theme(window, "one_dark_pro")

Getting colors for custom widgets:

>>> colors = fxstyle.get_theme_colors()
>>> surface = colors["surface"]  # Main background
>>> sunken = colors["surface_sunken"]  # Input/list backgrounds
>>> text = colors["text"]  # Primary text color

Theme persistence (automatic): Themes are automatically saved when using apply_theme(). On next application startup, the saved theme is automatically loaded.

Classes

FXProxyStyle

FXProxyStyle(*args, **kwargs)

Bases: QProxyStyle


              flowchart TD
              fxgui.fxstyle.FXProxyStyle[FXProxyStyle]

              

              click fxgui.fxstyle.FXProxyStyle href "" "fxgui.fxstyle.FXProxyStyle"
            

A custom style class that extends QProxyStyle to provide custom icons.

This style provides theme-aware standard icons (file dialogs, message boxes, etc.) using Material Design icons from the fxicons library.

Note

Qt stylesheets bypass QProxyStyle's drawControl() method, which means icon colorization for item views (lists, trees) and menus cannot be handled here when stylesheets are applied. Use FXIconColorDelegate from fxwidgets for icon colorization in item views instead.

Examples:

>>> from fxgui import fxstyle
>>> # Apply to application
>>> fxstyle.set_style(app, "Fusion")

Methods:

Name Description
set_icon_color

Set the color of the icons.

standardIcon

Return an icon for the given standardIcon.

Functions
set_icon_color
set_icon_color(color: str)

Set the color of the icons.

Parameters:

Name Type Description Default
color str

The color to set the icons to.

required
standardIcon
standardIcon(
    standardIcon: StandardPixmap,
    option: Optional[QStyleOption] = None,
    widget: Optional[QWidget] = None,
) -> QIcon

Return an icon for the given standardIcon.

Parameters:

Name Type Description Default
standardIcon StandardPixmap

The standard pixmap for which an icon should be returned.

required
option Optional[QStyleOption]

An option that can be used to fine-tune the look of the icon. Defaults to None.

None
widget Optional[QWidget]

The widget for which the icon is being requested. Defaults to None.

None

Returns:

Type Description
QIcon

The icon for the standardIcon. If no custom icon is found,

QIcon

the default icon is returned.

FXThemeAware

FXThemeAware(*args, **kwargs)

Mixin that makes widgets automatically respond to theme changes.

This mixin provides automatic theme updates for custom widgets. When the theme changes, connected widgets are notified and can update their appearance.

Usage
  1. Inherit from FXThemeAware FIRST: class MyWidget(FXThemeAware, QWidget)
  2. Override _on_theme_changed() to apply custom colors (optional)
  3. Use self.theme property to access current theme colors
  4. Optionally declare a theme_style class attribute for automatic QSS

Examples:

New API (recommended):

>>> from fxgui import fxstyle
>>> class FXMyWidget(FXThemeAware, QWidget):
...     # Option 1: Declarative QSS with color tokens
...     theme_style = '''
...         FXMyWidget {
...             background: @surface;
...             border: 1px solid @border;
...         }
...     '''
...
...     # Option 2: Programmatic colors in paintEvent
...     def paintEvent(self, event):
...         painter = QPainter(self)
...         painter.fillRect(self.rect(), QColor(self.theme.surface))

Legacy API (deprecated, still works):

>>> class FXMyWidget(FXThemeAware, QWidget):
...     def _apply_theme_styles(self):
...         colors = fxstyle.get_theme_colors()
...         self.setStyleSheet(f"background: {colors['surface']};")

Attributes:

Name Type Description
theme FXThemeColors

Property returning current theme colors as a FXThemeColors object.

theme_style str

Optional class attribute with QSS containing @color tokens.

Attributes
theme property

Get current theme colors as a namespace object.

Returns:

Type Description
FXThemeColors

FXThemeColors object with color attributes (e.g., theme.surface,

FXThemeColors

theme.accent_primary, theme.text).

Examples:

>>> def paintEvent(self, event):
...     painter = QPainter(self)
...     painter.fillRect(self.rect(), QColor(self.theme.surface))
...     painter.setPen(QColor(self.theme.text))
Functions
__apply_theme_style_attribute
__apply_theme_style_attribute() -> None

Process the theme_style class attribute and apply it.

__handle_theme_change
__handle_theme_change(_theme_name: str = None) -> None

Internal handler for theme changes.

FXThemeColors

FXThemeColors(colors_dict: dict)

Namespace for accessing theme colors with dot notation.

This class provides a convenient way to access theme colors using attribute access instead of dictionary lookup.

Examples:

>>> colors = FXThemeColors(fxstyle.get_theme_colors())
>>> colors.surface  # "#302f2f"
>>> colors.accent_primary  # "#2196F3"

Initialize with a colors dictionary.

Parameters:

Name Type Description Default
colors_dict
dict

Dictionary of color name to hex value mappings.

required
Functions

FXThemeManager

FXThemeManager()

Bases: QObject


              flowchart TD
              fxgui.fxstyle.FXThemeManager[FXThemeManager]

              

              click fxgui.fxstyle.FXThemeManager href "" "fxgui.fxstyle.FXThemeManager"
            

Singleton that emits theme_changed(str) when the theme changes.

Methods:

Name Description
notify_theme_changed

Called by apply_theme() when theme changes.

Attributes:

Name Type Description
current_theme str

Return the current theme name.

Attributes
current_theme property
current_theme: str

Return the current theme name.

Functions
notify_theme_changed
notify_theme_changed(theme_name: str) -> None

Called by apply_theme() when theme changes.

Functions

apply_theme

apply_theme(widget: QWidget, theme: str) -> str

Apply a theme to the widget with full style updates.

This function handles all necessary state updates including: - Switching the stylesheet - Updating icon colors - Invalidating icon caches

Parameters:

Name Type Description Default
widget
QWidget

The QWidget subclass to apply the theme to.

required
theme
str

The theme name to apply (e.g., "dark", "light", or custom).

required

Returns:

Type Description
str

The theme that was applied.

Examples:

Apply a specific theme:

>>> fxstyle.apply_theme(window, "dark")
>>> fxstyle.apply_theme(window, "light")
>>> fxstyle.apply_theme(window, "dracula")

get_accent_colors

get_accent_colors() -> dict

Get the accent colors for the current theme.

Accent colors are used for interactive elements:

  • primary: Hover borders on input widgets (QLineEdit, QComboBox, etc.), selection backgrounds, progress bar/slider gradients (end color), menu bar selections, pressed/selected items in item views.

  • secondary: Progress bar/slider gradients (start color), widget item hover backgrounds, menu pressed backgrounds, list/tree item hover highlights.

Returns:

Type Description
dict

Dictionary containing 'primary' and 'secondary' accent colors

dict

from the current theme.

Examples:

>>> colors = get_accent_colors()
>>> primary = colors["primary"]  # "#2196F3" for dark theme
>>> secondary = colors["secondary"]  # "#1976D2" for dark theme

get_available_themes

get_available_themes() -> list

Get a list of all available theme names from the color configuration.

Returns:

Type Description
list

List of theme names (e.g., ["dark", "light", "dracula", "one_dark_pro"]).

Examples:

>>> themes = fxstyle.get_available_themes()
>>> print(themes)  # ['dark', 'light', 'dracula', 'one_dark_pro']

get_colors

get_colors() -> dict

Get the cached color configuration dictionary.

This is the preferred way to access colors throughout the application. Colors are loaded once from the YAML file and cached for subsequent calls.

Returns:

Type Description
dict

The complete color configuration containing 'feedback', 'dcc', and

dict

'themes' sections.

Examples:

>>> colors = fxstyle.get_colors()
>>> error_color = colors["feedback"]["error"]["foreground"]
>>> dark_surface = colors["themes"]["dark"]["surface"]

get_contrast_text_color

get_contrast_text_color(background_hex: str) -> str

Determine whether to use white or black text on a given background.

Uses WCAG luminance calculation to ensure readable contrast.

Parameters:

Name Type Description Default
background_hex
str

The background color as a hex string.

required

Returns:

Type Description
str

"#FFFFFF" for dark backgrounds, "#000000" for light backgrounds.

get_feedback_colors

get_feedback_colors() -> dict

Get the feedback/status colors for notifications and logging.

These colors are used by FXNotificationBanner, FXLogWidget, and other status/feedback widgets.

Each level provides both a foreground (text/icon) and background color designed to work together with appropriate contrast.

The function first checks for theme-specific feedback colors (defined within the current theme), then falls back to the global feedback colors for backward compatibility.

Returns:

Type Description
dict

Dictionary with keys: 'debug', 'info', 'success', 'warning', 'error'.

dict

Each value is a dict with 'foreground' and 'background' keys.

Examples:

>>> colors = fxstyle.get_feedback_colors()
>>> colors["error"]["foreground"]  # "#ff4444"
>>> colors["error"]["background"]  # "#7b2323"
>>> colors["success"]["foreground"]  # "#8ac549"

get_icon_color

get_icon_color() -> str

Get the icon color for the current theme.

This color is used to tint monochrome SVG icons so they match the theme. It's applied by fxicons.get_icon() and FXProxyStyle for standard Qt icons.

Returns:

Type Description
str

The icon color as a hex string from the current theme's configuration.

Examples:

>>> color = fxstyle.get_icon_color()
>>> print(color)  # "#b4b4b4" for dark, "#424242" for light

get_icon_on_accent_primary

get_icon_on_accent_primary() -> str

Get the icon color for accent_primary backgrounds.

This color should be used for icons displayed on selected items or other elements that use the accent_primary color as their background.

If not explicitly defined in the theme, falls back to text_on_accent_primary, which is auto-computed based on the accent_primary color's luminance.

Returns:

Type Description
str

The icon color as a hex string for use on accent_primary backgrounds.

Examples:

>>> color = fxstyle.get_icon_on_accent_primary()
>>> print(color)  # "#ffffff" for dark theme with blue accent

get_icon_on_accent_secondary

get_icon_on_accent_secondary() -> str

Get the icon color for accent_secondary backgrounds.

This color should be used for icons displayed on hovered items or other elements that use the accent_secondary color as their background.

If not explicitly defined in the theme, falls back to text_on_accent_secondary, which is auto-computed based on the accent_secondary color's luminance.

Returns:

Type Description
str

The icon color as a hex string for use on accent_secondary backgrounds.

Examples:

>>> color = fxstyle.get_icon_on_accent_secondary()
>>> print(color)  # "#ffffff" for dark theme with blue accent

get_luminance

get_luminance(hex_color: str) -> float

Calculate the relative luminance of a color.

Uses the WCAG 2.0 formula for relative luminance.

Parameters:

Name Type Description Default
hex_color
str

A hex color string (e.g., "#007ACC" or "007ACC").

required

Returns:

Type Description
float

The relative luminance value between 0 (black) and 1 (white).

get_theme

get_theme() -> str

Get the current theme name.

On first access, the theme is loaded from persistent storage. If no theme was previously saved, defaults to "dark".

Returns:

Type Description
str

The current theme name (e.g., "dark", "light").

get_theme_colors

get_theme_colors() -> dict

Get the color palette for the current theme.

Returns a dictionary with all semantic color roles:

Surface Colors (Backgrounds):

  • surface: Main widget/window backgrounds, buttons, selected tabs
  • surface_alt: Alternate row backgrounds in lists/tables
  • surface_sunken: Recessed areas - input fields, lists, menus
  • tooltip: Tooltip backgrounds

Border Colors:

  • border: Standard borders on inputs, containers, menus
  • border_light: Subtle borders - tooltips, buttons, tabs
  • border_strong: Emphasized borders - frames, separators

Text Colors:

  • text: Primary text for all widgets
  • text_muted: De-emphasized text - inactive tabs, placeholders
  • text_disabled: Disabled widget text
  • text_on_accent_primary: Text on accent_primary backgrounds (optional)
  • text_on_accent_secondary: Text on accent_secondary backgrounds (optional)

Interactive States:

  • state_hover: Hover state backgrounds
  • state_pressed: Pressed/checked/active backgrounds

Scrollbar Colors:

  • scrollbar_track: Track/gutter background
  • scrollbar_thumb: Draggable thumb
  • scrollbar_thumb_hover: Thumb hover state

Layout Colors:

  • grid: Table gridlines, header borders
  • separator: Separator/splitter hover backgrounds

Slider Colors:

  • slider_thumb: Slider handle color
  • slider_thumb_hover: Slider handle hover/pressed

Icon Colors:

  • icon: Tint color for monochrome icons
  • icon_on_accent_primary: Icon color on accent_primary backgrounds (optional)
  • icon_on_accent_secondary: Icon color on accent_secondary backgrounds (optional)

Returns:

Type Description
dict

Dictionary containing theme-specific colors.

Examples:

>>> colors = get_theme_colors()
>>> bg = colors["surface"]  # "#302f2f" for dark
>>> sunken = colors["surface_sunken"]  # Input/list backgrounds
>>> text = colors["text"]  # Primary text color

invalidate_standard_icon_map

invalidate_standard_icon_map() -> None

Invalidate the cached standard icon map.

This should be called when changing themes so icons are regenerated with the new color scheme on next access.

is_light_theme

is_light_theme() -> bool

Check if the current theme is a light theme.

Determines theme brightness by analyzing the surface color's lightness. This is more reliable than checking the theme name since it works with any custom theme.

Returns:

Type Description
bool

True if the current theme is light, False if dark.

Examples:

>>> if fxstyle.is_light_theme():
...     use_dark_icons()
... else:
...     use_light_icons()

load_saved_theme

load_saved_theme() -> str

Load the saved theme from persistent storage.

If no theme has been saved, returns the default theme ("dark").

Returns:

Type Description
str

The saved theme name, or "dark" if none is saved.

Examples:

>>> theme = fxstyle.load_saved_theme()
>>> print(theme)  # "dracula" if previously saved

load_stylesheet

load_stylesheet(
    style_file: str = STYLE_FILE, extra: Optional[str] = None, theme: str = None
) -> str

Load the stylesheet and replace placeholders with actual values.

Parameters:

Name Type Description Default
style_file
str

The path to the QSS file. Defaults to STYLE_FILE.

STYLE_FILE
extra
Optional[str]

Extra stylesheet content to append. Defaults to None.

None
theme
str

The theme to use (e.g., "dark", "light", "dracula"). If None, uses the saved theme from persistent storage.

None

Returns:

Type Description
str

The stylesheet with all placeholders replaced.

replace_colors

replace_colors(
    stylesheet: str, colors_dict: dict = None, prefix: str = ""
) -> str

Replace color placeholders in a stylesheet with actual color values.

This function searches for placeholders in the format @{prefix}{key} and replaces them with the corresponding color values from the dictionary.

Parameters:

Name Type Description Default
stylesheet
str

The stylesheet string containing color placeholders.

required
colors_dict
dict

Dictionary containing color definitions. Only top-level non-dict values are used. Defaults to colors from get_colors().

None
prefix
str

Prefix for placeholder names. Defaults to empty string.

''

Returns:

Type Description
str

The stylesheet with all matching placeholders replaced.

Examples:

>>> colors = {"primary": "#FF5722", "secondary": "#E64A19"}
>>> qss = "color: @primary; background: @secondary;"
>>> result = replace_colors(qss, colors)
>>> print(result)
'color: #FF5722; background: #E64A19;'

save_theme

save_theme(theme: str) -> None

Save the current theme to persistent storage.

Parameters:

Name Type Description Default
theme
str

The theme name to save.

required

Examples:

>>> fxstyle.save_theme("dracula")

set_color_file

set_color_file(color_file: str) -> None

Set a custom color configuration file.

This clears the color cache and sets the new file as the active color source. The next call to get_colors() will load from this file.

Supports both YAML (.yaml, .yml) files with inheritance via anchors.

Parameters:

Name Type Description Default
color_file
str

Path to the custom YAML color configuration file.

required

Examples:

>>> fxstyle.set_color_file("path/to/custom_theme.yaml")
>>> colors = fxstyle.get_colors()  # Loads from custom file

set_style

set_style(widget: QWidget, style: str = None) -> FXProxyStyle

Set the style.

Parameters:

Name Type Description Default
widget
QWidget

The QWidget subclass to set the style to.

required
style
str

The style to set. Defaults to None.

None

Returns:

Type Description
FXProxyStyle

The custom style.

Note

You can retrieve the styles available on your system with QStyleFactory.keys(). Only those string values are accepted in the style argument.