ThemePlugin¶
Theme plugins define application color schemes.
Purpose¶
Use ThemePlugin when you want to:
Add a custom color theme
Create beamline-branded appearance
Provide dark/light mode variants
Base Class¶
from lightfall.plugins.theme_plugin import ThemePlugin, ThemeDefinition
Class Attributes¶
Attribute |
Value |
Description |
|---|---|---|
|
|
Plugin type identifier |
|
|
One instance per plugin |
Required Methods¶
name (property)¶
Unique identifier for this theme.
@property
def name(self) -> str:
return "my_theme"
display_name (property)¶
Human-readable name shown in the theme selector.
@property
def display_name(self) -> str:
return "My Theme"
is_dark (property)¶
Whether this is a dark theme.
@property
def is_dark(self) -> bool:
return True # or False for light themes
get_theme_definition()¶
Return the theme’s color definitions.
def get_theme_definition(self) -> ThemeDefinition:
return ThemeDefinition(
primary="#3b82f6",
background="#1a1a1a",
# ... other colors
)
ThemeDefinition¶
The ThemeDefinition dataclass defines all theme colors:
@dataclass
class ThemeDefinition:
# Accent colors
primary: str = "#2563eb" # Primary brand/accent
secondary: str = "#7c3aed" # Secondary accent
success: str = "#16a34a" # Success/positive state
warning: str = "#d97706" # Warning state
error: str = "#dc2626" # Error/danger state
info: str = "#0891b2" # Informational state
# Surface colors
background: str = "#ffffff" # Main background
surface: str = "#f3f4f6" # Elevated surface
text: str = "#1f2937" # Primary text
text_secondary: str = "#6b7280" # Secondary text
border: str = "#e5e7eb" # Borders/dividers
# State colors (default to success/error)
connected: str = "" # Connected state
disconnected: str = "" # Disconnected state
# Optional CSS
css_overrides: str = "" # Additional CSS rules
Lifecycle¶
Theme plugins are loaded with
preload=Trueget_theme_definition()provides color valuesTheme is registered with
ThemeRegistryUsers select themes in Appearance settings
ThemeManagerapplies the selected theme
Complete Example¶
Dark Theme¶
"""Custom dark theme plugin."""
from lightfall.plugins.theme_plugin import ThemePlugin, ThemeDefinition
class BeamlineDarkTheme(ThemePlugin):
"""Dark theme with beamline branding."""
@property
def name(self) -> str:
return "beamline_dark"
@property
def display_name(self) -> str:
return "Beamline Dark"
@property
def is_dark(self) -> bool:
return True
def get_theme_definition(self) -> ThemeDefinition:
return ThemeDefinition(
# Brand colors
primary="#00a0e4", # Beamline blue
secondary="#7c3aed", # Purple accent
# Status colors
success="#22c55e", # Green
warning="#f59e0b", # Amber
error="#ef4444", # Red
info="#06b6d4", # Cyan
# Dark surface colors
background="#0f172a", # Very dark blue
surface="#1e293b", # Dark slate
text="#f1f5f9", # Light text
text_secondary="#94a3b8", # Muted text
border="#334155", # Subtle border
# State colors
connected="#22c55e",
disconnected="#ef4444",
)
Light Theme¶
"""Custom light theme plugin."""
from lightfall.plugins.theme_plugin import ThemePlugin, ThemeDefinition
class BeamlineLightTheme(ThemePlugin):
"""Light theme with beamline branding."""
@property
def name(self) -> str:
return "beamline_light"
@property
def display_name(self) -> str:
return "Beamline Light"
@property
def is_dark(self) -> bool:
return False
def get_theme_definition(self) -> ThemeDefinition:
return ThemeDefinition(
# Brand colors
primary="#0077b6", # Beamline blue
secondary="#6366f1", # Indigo accent
# Status colors
success="#16a34a",
warning="#d97706",
error="#dc2626",
info="#0891b2",
# Light surface colors
background="#ffffff",
surface="#f8fafc",
text="#1e293b",
text_secondary="#64748b",
border="#e2e8f0",
)
Theme with CSS Overrides¶
"""Theme with custom CSS overrides."""
from lightfall.plugins.theme_plugin import ThemePlugin, ThemeDefinition
class CustomStyledTheme(ThemePlugin):
"""Theme with additional CSS customizations."""
@property
def name(self) -> str:
return "custom_styled"
@property
def display_name(self) -> str:
return "Custom Styled"
@property
def is_dark(self) -> bool:
return True
def get_theme_definition(self) -> ThemeDefinition:
return ThemeDefinition(
primary="#8b5cf6",
background="#18181b",
surface="#27272a",
text="#fafafa",
text_secondary="#a1a1aa",
border="#3f3f46",
css_overrides="""
/* Custom button styling */
QPushButton {
border-radius: 8px;
padding: 8px 16px;
}
QPushButton:hover {
background-color: #8b5cf6;
}
/* Custom scrollbar */
QScrollBar:vertical {
width: 8px;
background: transparent;
}
QScrollBar::handle:vertical {
background: #52525b;
border-radius: 4px;
}
"""
)
Registration¶
Built-in Manifest¶
Themes must be preloaded to apply before the main window:
PluginEntry(
type_name="theme",
name="beamline_dark",
import_path="my_package.themes:BeamlineDarkTheme",
preload=True, # Required for themes
),
Built-in Themes¶
Lightfall includes these themes by default:
Theme |
Type |
Description |
|---|---|---|
|
Light |
Clean light theme |
|
Dark |
Modern slate gray |
|
Dark |
Deep blue tones |
|
Dark |
High contrast dark |
System Theme Support¶
When is_dark is properly set, themes support system theme detection. Users can select “System” to automatically use a light or dark theme based on OS settings.
Color Guidelines¶
Accessibility¶
Ensure sufficient contrast between text and background
Use distinct colors for different states
Test with color blindness simulators
Consistency¶
Use semantic colors consistently (success = green, error = red)
Maintain visual hierarchy with surface colors
Keep accent colors visible but not overwhelming
Example Color Contrast¶
For dark themes:
Background: #1a1a1a (very dark)
Surface: #2a2a2a (slightly lighter)
Text: #e0e0e0 (high contrast)
Text secondary: #a0a0a0 (lower contrast)
For light themes:
Background: #ffffff (white)
Surface: #f5f5f5 (slightly darker)
Text: #1a1a1a (high contrast)
Text secondary: #666666 (lower contrast)