Skip to content

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.

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.

FXProxyStyle

Bases: QProxyStyle

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

Methods:

Name Description
set_icon_color

Set the color of the icons.

standardIcon

Return an icon for the given standardIcon.

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

Mixin that makes widgets automatically respond to theme changes.

Usage
  1. Inherit from FXThemeAware FIRST: class MyWidget(FXThemeAware, QWidget)
  2. Override _apply_theme_styles() to apply your colors
Example

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

That's it! Colors update automatically when theme changes.

Methods:

Name Description
changeEvent

Handle Qt palette change events.

changeEvent

changeEvent(event) -> None

Handle Qt palette change events.

FXThemeManager

Bases: QObject

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.

current_theme property

current_theme: str

Return the current theme name.

notify_theme_changed

notify_theme_changed(theme_name: str) -> None

Called by apply_theme() when theme changes.

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_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_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:

  • icon: Tint color for monochrome icons

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.

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.