pyqt_reactive.theming

Theming and styling system.

Color schemes, palette management, and stylesheet generation for consistent application-wide theming.

class pyqt_reactive.theming.ColorScheme(window_bg: Tuple[int, int, int] = (43, 43, 43), panel_bg: Tuple[int, int, int] = (30, 30, 30), frame_bg: Tuple[int, int, int] = (43, 43, 43), border_color: Tuple[int, int, int] = (85, 85, 85), border_light: Tuple[int, int, int] = (102, 102, 102), separator_color: Tuple[int, int, int] = (51, 51, 51), text_primary: Tuple[int, int, int] = (255, 255, 255), text_secondary: Tuple[int, int, int] = (204, 204, 204), text_accent: Tuple[int, int, int] = (0, 170, 255), text_disabled: Tuple[int, int, int] = (102, 102, 102), button_normal_bg: Tuple[int, int, int] = (64, 64, 64), button_hover_bg: Tuple[int, int, int] = (80, 80, 80), button_pressed_bg: Tuple[int, int, int] = (48, 48, 48), button_disabled_bg: Tuple[int, int, int] = (42, 42, 42), button_text: Tuple[int, int, int] = (255, 255, 255), button_disabled_text: Tuple[int, int, int] = (102, 102, 102), input_bg: Tuple[int, int, int] = (64, 64, 64), input_border: Tuple[int, int, int] = (102, 102, 102), input_text: Tuple[int, int, int] = (255, 255, 255), input_focus_border: Tuple[int, int, int] = (0, 170, 255), selection_bg: Tuple[int, int, int] = (0, 120, 212), selection_text: Tuple[int, int, int] = (255, 255, 255), hover_bg: Tuple[int, int, int] = (51, 51, 51), focus_outline: Tuple[int, int, int] = (0, 170, 255), search_highlight_bg: Tuple[int, int, int, int] = (255, 255, 0, 100), search_highlight_text: Tuple[int, int, int] = (0, 0, 0), status_success: Tuple[int, int, int] = (0, 255, 0), status_warning: Tuple[int, int, int] = (255, 170, 0), status_error: Tuple[int, int, int] = (255, 0, 0), status_info: Tuple[int, int, int] = (0, 170, 255), progress_bg: Tuple[int, int, int] = (30, 30, 30), progress_fill: Tuple[int, int, int] = (0, 120, 212), activity_indicator: Tuple[int, int, int] = (0, 170, 255), log_critical_fg: Tuple[int, int, int] = (255, 255, 255), log_critical_bg: Tuple[int, int, int] = (139, 0, 0), log_error_color: Tuple[int, int, int] = (255, 85, 85), log_warning_color: Tuple[int, int, int] = (255, 140, 0), log_info_color: Tuple[int, int, int] = (100, 160, 210), log_debug_color: Tuple[int, int, int] = (160, 160, 160), timestamp_color: Tuple[int, int, int] = (105, 105, 105), logger_name_color: Tuple[int, int, int] = (147, 112, 219), memory_address_color: Tuple[int, int, int] = (255, 182, 193), file_path_color: Tuple[int, int, int] = (34, 139, 34), python_keyword_color: Tuple[int, int, int] = (86, 156, 214), python_string_color: Tuple[int, int, int] = (206, 145, 120), python_number_color: Tuple[int, int, int] = (181, 206, 168), python_operator_color: Tuple[int, int, int] = (212, 212, 212), python_name_color: Tuple[int, int, int] = (156, 220, 254), python_function_color: Tuple[int, int, int] = (220, 220, 170), python_class_color: Tuple[int, int, int] = (78, 201, 176), python_builtin_color: Tuple[int, int, int] = (86, 156, 214), python_comment_color: Tuple[int, int, int] = (106, 153, 85), exception_color: Tuple[int, int, int] = (255, 69, 0), function_call_color: Tuple[int, int, int] = (255, 215, 0), boolean_color: Tuple[int, int, int] = (86, 156, 214), tuple_parentheses_color: Tuple[int, int, int] = (255, 215, 0), set_braces_color: Tuple[int, int, int] = (255, 140, 0), class_representation_color: Tuple[int, int, int] = (78, 201, 176), function_representation_color: Tuple[int, int, int] = (220, 220, 170), module_path_color: Tuple[int, int, int] = (147, 112, 219), hex_number_color: Tuple[int, int, int] = (181, 206, 168), scientific_notation_color: Tuple[int, int, int] = (181, 206, 168), binary_number_color: Tuple[int, int, int] = (181, 206, 168), octal_number_color: Tuple[int, int, int] = (181, 206, 168), python_special_color: Tuple[int, int, int] = (255, 20, 147), single_quoted_string_color: Tuple[int, int, int] = (206, 145, 120), list_comprehension_color: Tuple[int, int, int] = (156, 220, 254), generator_expression_color: Tuple[int, int, int] = (156, 220, 254))[source]

Comprehensive color scheme for OpenHCS PyQt6 GUI with semantic color names.

Extends the LogColorScheme pattern to cover all GUI components including windows, dialogs, widgets, and interactive elements. Supports light/dark theme variants and ensures WCAG accessibility compliance.

All colors meet minimum 4.5:1 contrast ratio for normal text readability.

window_bg: Tuple[int, int, int] = (43, 43, 43)
panel_bg: Tuple[int, int, int] = (30, 30, 30)
frame_bg: Tuple[int, int, int] = (43, 43, 43)
border_color: Tuple[int, int, int] = (85, 85, 85)
border_light: Tuple[int, int, int] = (102, 102, 102)
separator_color: Tuple[int, int, int] = (51, 51, 51)
text_primary: Tuple[int, int, int] = (255, 255, 255)
text_secondary: Tuple[int, int, int] = (204, 204, 204)
text_accent: Tuple[int, int, int] = (0, 170, 255)
text_disabled: Tuple[int, int, int] = (102, 102, 102)
button_normal_bg: Tuple[int, int, int] = (64, 64, 64)
button_hover_bg: Tuple[int, int, int] = (80, 80, 80)
button_pressed_bg: Tuple[int, int, int] = (48, 48, 48)
button_disabled_bg: Tuple[int, int, int] = (42, 42, 42)
button_text: Tuple[int, int, int] = (255, 255, 255)
button_disabled_text: Tuple[int, int, int] = (102, 102, 102)
input_bg: Tuple[int, int, int] = (64, 64, 64)
input_border: Tuple[int, int, int] = (102, 102, 102)
input_text: Tuple[int, int, int] = (255, 255, 255)
input_focus_border: Tuple[int, int, int] = (0, 170, 255)
selection_bg: Tuple[int, int, int] = (0, 120, 212)
selection_text: Tuple[int, int, int] = (255, 255, 255)
hover_bg: Tuple[int, int, int] = (51, 51, 51)
focus_outline: Tuple[int, int, int] = (0, 170, 255)
search_highlight_bg: Tuple[int, int, int, int] = (255, 255, 0, 100)
search_highlight_text: Tuple[int, int, int] = (0, 0, 0)
status_success: Tuple[int, int, int] = (0, 255, 0)
status_warning: Tuple[int, int, int] = (255, 170, 0)
status_error: Tuple[int, int, int] = (255, 0, 0)
status_info: Tuple[int, int, int] = (0, 170, 255)
progress_bg: Tuple[int, int, int] = (30, 30, 30)
progress_fill: Tuple[int, int, int] = (0, 120, 212)
activity_indicator: Tuple[int, int, int] = (0, 170, 255)
log_critical_fg: Tuple[int, int, int] = (255, 255, 255)
log_critical_bg: Tuple[int, int, int] = (139, 0, 0)
log_error_color: Tuple[int, int, int] = (255, 85, 85)
log_warning_color: Tuple[int, int, int] = (255, 140, 0)
log_info_color: Tuple[int, int, int] = (100, 160, 210)
log_debug_color: Tuple[int, int, int] = (160, 160, 160)
timestamp_color: Tuple[int, int, int] = (105, 105, 105)
logger_name_color: Tuple[int, int, int] = (147, 112, 219)
memory_address_color: Tuple[int, int, int] = (255, 182, 193)
file_path_color: Tuple[int, int, int] = (34, 139, 34)
python_keyword_color: Tuple[int, int, int] = (86, 156, 214)
python_string_color: Tuple[int, int, int] = (206, 145, 120)
python_number_color: Tuple[int, int, int] = (181, 206, 168)
python_operator_color: Tuple[int, int, int] = (212, 212, 212)
python_name_color: Tuple[int, int, int] = (156, 220, 254)
python_function_color: Tuple[int, int, int] = (220, 220, 170)
python_class_color: Tuple[int, int, int] = (78, 201, 176)
python_builtin_color: Tuple[int, int, int] = (86, 156, 214)
python_comment_color: Tuple[int, int, int] = (106, 153, 85)
exception_color: Tuple[int, int, int] = (255, 69, 0)
function_call_color: Tuple[int, int, int] = (255, 215, 0)
boolean_color: Tuple[int, int, int] = (86, 156, 214)
tuple_parentheses_color: Tuple[int, int, int] = (255, 215, 0)
set_braces_color: Tuple[int, int, int] = (255, 140, 0)
class_representation_color: Tuple[int, int, int] = (78, 201, 176)
function_representation_color: Tuple[int, int, int] = (220, 220, 170)
module_path_color: Tuple[int, int, int] = (147, 112, 219)
hex_number_color: Tuple[int, int, int] = (181, 206, 168)
scientific_notation_color: Tuple[int, int, int] = (181, 206, 168)
binary_number_color: Tuple[int, int, int] = (181, 206, 168)
octal_number_color: Tuple[int, int, int] = (181, 206, 168)
python_special_color: Tuple[int, int, int] = (255, 20, 147)
single_quoted_string_color: Tuple[int, int, int] = (206, 145, 120)
list_comprehension_color: Tuple[int, int, int] = (156, 220, 254)
generator_expression_color: Tuple[int, int, int] = (156, 220, 254)
to_qcolor(color_tuple: Tuple[int, int, int]) QColor[source]

Convert RGB tuple to QColor object.

Parameters:

color_tuple – RGB color tuple (r, g, b)

Returns:

Qt color object

Return type:

QColor

to_qcolor_rgba(color_tuple: Tuple[int, int, int, int]) QColor[source]

Convert RGBA tuple to QColor object.

Parameters:

color_tuple – RGBA color tuple (r, g, b, a)

Returns:

Qt color object with alpha

Return type:

QColor

to_hex(color_tuple: Tuple[int, int, int]) str[source]

Convert RGB tuple to hex color string.

Parameters:

color_tuple – RGB color tuple (r, g, b)

Returns:

Hex color string (e.g., “#ff0000”)

Return type:

str

classmethod create_dark_theme() PyQt6ColorScheme[source]

Create a dark theme variant with adjusted colors for dark backgrounds.

This is the default theme, so most colors remain the same with minor adjustments for better contrast on dark backgrounds.

Returns:

Dark theme color scheme with enhanced contrast

Return type:

PyQt6ColorScheme

classmethod create_light_theme() PyQt6ColorScheme[source]

Create a light theme variant with adjusted colors for light backgrounds.

All colors are adjusted to maintain WCAG 4.5:1 contrast ratio on light backgrounds while preserving the semantic meaning and visual hierarchy.

Returns:

Light theme color scheme with appropriate contrast

Return type:

PyQt6ColorScheme

classmethod load_color_scheme_from_config(config_path: str = None) PyQt6ColorScheme[source]

Load color scheme from external configuration file.

Parameters:

config_path – Path to JSON config file (optional)

Returns:

Loaded color scheme or default if file not found

Return type:

PyQt6ColorScheme

validate_wcag_contrast(foreground: Tuple[int, int, int], background: Tuple[int, int, int], min_ratio: float = 4.5) bool[source]

Validate WCAG contrast ratio between foreground and background colors.

Parameters:
  • foreground – Foreground color RGB tuple

  • background – Background color RGB tuple

  • min_ratio – Minimum contrast ratio (default: 4.5 for normal text)

Returns:

True if contrast ratio meets minimum requirement

Return type:

bool

get_color_dict() Dict[str, Tuple[int, int, int]][source]

Get all colors as a dictionary for serialization or inspection.

Returns:

Dictionary of color name to RGB tuple

Return type:

Dict[str, Tuple[int, int, int]]

save_to_json(config_path: str) bool[source]

Save color scheme to JSON configuration file.

Parameters:

config_path – Path to save JSON config file

Returns:

True if save successful, False otherwise

Return type:

bool

__init__(window_bg: Tuple[int, int, int] = (43, 43, 43), panel_bg: Tuple[int, int, int] = (30, 30, 30), frame_bg: Tuple[int, int, int] = (43, 43, 43), border_color: Tuple[int, int, int] = (85, 85, 85), border_light: Tuple[int, int, int] = (102, 102, 102), separator_color: Tuple[int, int, int] = (51, 51, 51), text_primary: Tuple[int, int, int] = (255, 255, 255), text_secondary: Tuple[int, int, int] = (204, 204, 204), text_accent: Tuple[int, int, int] = (0, 170, 255), text_disabled: Tuple[int, int, int] = (102, 102, 102), button_normal_bg: Tuple[int, int, int] = (64, 64, 64), button_hover_bg: Tuple[int, int, int] = (80, 80, 80), button_pressed_bg: Tuple[int, int, int] = (48, 48, 48), button_disabled_bg: Tuple[int, int, int] = (42, 42, 42), button_text: Tuple[int, int, int] = (255, 255, 255), button_disabled_text: Tuple[int, int, int] = (102, 102, 102), input_bg: Tuple[int, int, int] = (64, 64, 64), input_border: Tuple[int, int, int] = (102, 102, 102), input_text: Tuple[int, int, int] = (255, 255, 255), input_focus_border: Tuple[int, int, int] = (0, 170, 255), selection_bg: Tuple[int, int, int] = (0, 120, 212), selection_text: Tuple[int, int, int] = (255, 255, 255), hover_bg: Tuple[int, int, int] = (51, 51, 51), focus_outline: Tuple[int, int, int] = (0, 170, 255), search_highlight_bg: Tuple[int, int, int, int] = (255, 255, 0, 100), search_highlight_text: Tuple[int, int, int] = (0, 0, 0), status_success: Tuple[int, int, int] = (0, 255, 0), status_warning: Tuple[int, int, int] = (255, 170, 0), status_error: Tuple[int, int, int] = (255, 0, 0), status_info: Tuple[int, int, int] = (0, 170, 255), progress_bg: Tuple[int, int, int] = (30, 30, 30), progress_fill: Tuple[int, int, int] = (0, 120, 212), activity_indicator: Tuple[int, int, int] = (0, 170, 255), log_critical_fg: Tuple[int, int, int] = (255, 255, 255), log_critical_bg: Tuple[int, int, int] = (139, 0, 0), log_error_color: Tuple[int, int, int] = (255, 85, 85), log_warning_color: Tuple[int, int, int] = (255, 140, 0), log_info_color: Tuple[int, int, int] = (100, 160, 210), log_debug_color: Tuple[int, int, int] = (160, 160, 160), timestamp_color: Tuple[int, int, int] = (105, 105, 105), logger_name_color: Tuple[int, int, int] = (147, 112, 219), memory_address_color: Tuple[int, int, int] = (255, 182, 193), file_path_color: Tuple[int, int, int] = (34, 139, 34), python_keyword_color: Tuple[int, int, int] = (86, 156, 214), python_string_color: Tuple[int, int, int] = (206, 145, 120), python_number_color: Tuple[int, int, int] = (181, 206, 168), python_operator_color: Tuple[int, int, int] = (212, 212, 212), python_name_color: Tuple[int, int, int] = (156, 220, 254), python_function_color: Tuple[int, int, int] = (220, 220, 170), python_class_color: Tuple[int, int, int] = (78, 201, 176), python_builtin_color: Tuple[int, int, int] = (86, 156, 214), python_comment_color: Tuple[int, int, int] = (106, 153, 85), exception_color: Tuple[int, int, int] = (255, 69, 0), function_call_color: Tuple[int, int, int] = (255, 215, 0), boolean_color: Tuple[int, int, int] = (86, 156, 214), tuple_parentheses_color: Tuple[int, int, int] = (255, 215, 0), set_braces_color: Tuple[int, int, int] = (255, 140, 0), class_representation_color: Tuple[int, int, int] = (78, 201, 176), function_representation_color: Tuple[int, int, int] = (220, 220, 170), module_path_color: Tuple[int, int, int] = (147, 112, 219), hex_number_color: Tuple[int, int, int] = (181, 206, 168), scientific_notation_color: Tuple[int, int, int] = (181, 206, 168), binary_number_color: Tuple[int, int, int] = (181, 206, 168), octal_number_color: Tuple[int, int, int] = (181, 206, 168), python_special_color: Tuple[int, int, int] = (255, 20, 147), single_quoted_string_color: Tuple[int, int, int] = (206, 145, 120), list_comprehension_color: Tuple[int, int, int] = (156, 220, 254), generator_expression_color: Tuple[int, int, int] = (156, 220, 254)) None
class pyqt_reactive.theming.PaletteManager(color_scheme: ColorScheme)[source]

Manages QPalette integration with ColorScheme.

Provides methods to apply color schemes to Qt’s palette system, enabling system-wide theming and consistent color application.

__init__(color_scheme: ColorScheme)[source]

Initialize the palette manager with a color scheme.

Parameters:

color_scheme – ColorScheme instance to use for palette generation

update_color_scheme(color_scheme: ColorScheme)[source]

Update the color scheme used for palette generation.

Parameters:

color_scheme – New ColorScheme instance

create_palette() QPalette[source]

Create a QPalette from the current color scheme.

Returns:

Configured palette with color scheme colors

Return type:

QPalette

apply_palette_to_application(app: QApplication | None = None)[source]

Apply the color scheme palette to the entire application.

Parameters:

app – QApplication instance (uses QApplication.instance() if None)

restore_original_palette(app: QApplication | None = None)[source]

Restore the original application palette.

Parameters:

app – QApplication instance (uses QApplication.instance() if None)

get_palette_info() dict[source]

Get information about the current palette configuration.

Returns:

Dictionary with palette color information

Return type:

dict

class pyqt_reactive.theming.ThemeManager(initial_color_scheme: ColorScheme | None = None)[source]

High-level theme management for the entire application.

Coordinates color scheme, style sheet generation, and palette management to provide seamless theme switching capabilities.

__init__(initial_color_scheme: ColorScheme | None = None)[source]

Initialize the theme manager.

Parameters:

initial_color_scheme – Initial color scheme (defaults to dark theme)

switch_to_dark_theme()[source]

Switch to dark theme variant.

switch_to_light_theme()[source]

Switch to light theme variant.

apply_color_scheme(color_scheme: ColorScheme)[source]

Apply a new color scheme to the entire application.

Parameters:

color_scheme – New ColorScheme to apply

register_theme_change_callback(callback)[source]

Register a callback to be called when theme changes.

Parameters:

callback – Function to call with new color scheme

unregister_theme_change_callback(callback)[source]

Unregister a theme change callback.

Parameters:

callback – Function to remove from callbacks

get_current_style_sheet() str[source]

Get the current complete application style sheet.

Returns:

Complete QStyleSheet for current theme

Return type:

str

load_theme_from_config(config_path: str) bool[source]

Load and apply theme from configuration file.

Parameters:

config_path – Path to JSON configuration file

Returns:

True if successful, False otherwise

Return type:

bool

save_current_theme(config_path: str) bool[source]

Save current theme to configuration file.

Parameters:

config_path – Path to save JSON configuration file

Returns:

True if successful, False otherwise

Return type:

bool

class pyqt_reactive.theming.StyleSheetGenerator(color_scheme: ColorScheme)[source]

Generates QStyleSheet strings from ColorScheme objects.

Provides methods to generate complete stylesheets for different widget types, replacing hardcoded colors with centralized color scheme references.

__init__(color_scheme: ColorScheme)[source]

Initialize the style generator with a color scheme.

Parameters:

color_scheme – ColorScheme instance to use for styling

update_color_scheme(color_scheme: ColorScheme)[source]

Update the color scheme used for style generation.

Parameters:

color_scheme – New ColorScheme instance

generate_dialog_style() str[source]

Generate QStyleSheet for dialog windows.

Returns:

Complete QStyleSheet for dialog styling

Return type:

str

generate_tree_widget_style() str[source]

Generate QStyleSheet for tree widgets and list widgets.

Returns:

Complete QStyleSheet for tree/list widget styling

Return type:

str

generate_list_widget_style() str[source]

Alias for generate_tree_widget_style (includes QListWidget styling).

generate_table_widget_style() str[source]

Generate QStyleSheet for table widgets.

Returns:

Complete QStyleSheet for table widget styling

Return type:

str

generate_button_style() str[source]

Generate QStyleSheet for buttons with all states.

Returns:

Complete QStyleSheet for button styling

Return type:

str

generate_combobox_style() str[source]

Generate QStyleSheet for combo boxes with dropdown styling.

Returns:

Complete QStyleSheet for combo box styling

Return type:

str

generate_progress_bar_style() str[source]

Generate QStyleSheet for progress bars.

Returns:

Complete QStyleSheet for progress bar styling

Return type:

str

generate_frame_style() str[source]

Generate QStyleSheet for frames and panels.

Returns:

Complete QStyleSheet for frame styling

Return type:

str

generate_tab_widget_style() str[source]

Generate QStyleSheet for tab widgets.

Returns:

Complete QStyleSheet for tab widget styling

Return type:

str

generate_system_monitor_style() str[source]

Generate QStyleSheet for system monitor widget.

Returns:

Complete QStyleSheet for system monitor styling

Return type:

str

generate_complete_application_style() str[source]

Generate complete application-wide QStyleSheet.

Returns:

Complete QStyleSheet for entire application

Return type:

str

generate_config_window_style() str[source]

Generate QStyleSheet for configuration windows with button panel.

Returns:

Complete QStyleSheet for config window styling

Return type:

str

generate_config_button_styles() dict[source]

Generate individual button styles for config window buttons.

Returns:

Dictionary with button styles for generic, reset, cancel, save

Return type:

dict

generate_plate_manager_style() str[source]

Generate QStyleSheet for plate manager widget with all components.

Returns:

Complete QStyleSheet for plate manager styling

Return type:

str

get_status_color_hex(status_type: str) str[source]

Get hex color string for status type.

Parameters:

status_type – Status type (success, warning, error, info)

Returns:

Hex color string for the status type

Return type:

str

Modules

color_scheme

PyQt6 Color Scheme for OpenHCS GUI

palette_manager

QPalette Manager for OpenHCS PyQt6 GUI

style_generator

QStyleSheet Generator for OpenHCS PyQt6 GUI