API Reference

Welcome to the Qt Framework API reference documentation.

Core Modules

The Qt Framework is organized into several key modules:

Core (qtframework.core)

Core application components for building Qt applications.

Application core module.

class qtframework.core.application.Application(argv=None, *, app_name='QtFrameworkApp', org_name='QtFramework', org_domain='qtframework.local', resource_manager=None, excluded_builtin_themes=None, excluded_themes=None, included_themes=None, include_auto_theme=True)[source]

Bases: QApplication

Enhanced QApplication with built-in theme and context management.

property context: Context

Get application context.

context_changed
classmethod create_and_run(window_class, *, argv=None, app_name='QtFrameworkApp', org_name='QtFramework', org_domain='qtframework.local', excluded_builtin_themes=None, excluded_themes=None, included_themes=None, include_auto_theme=True, **window_kwargs)[source]

Create and run application with main window.

Parameters:
  • window_class (type[BaseWindow]) – Main window class

  • argv (list[str] | None) – Command line arguments

  • app_name (str) – Application name

  • org_name (str) – Organization name

  • org_domain (str) – Organization domain

  • excluded_builtin_themes (list[str] | None) – List of built-in theme names to exclude from loading

  • excluded_themes (list[str] | None) – List of custom theme names to exclude from loading

  • included_themes (list[str] | None) – If specified, ONLY load these built-in framework themes (custom themes always load)

  • include_auto_theme (bool) – Whether to include ‘auto’ theme in theme list (default: True)

  • **window_kwargs (Any) – Keyword arguments for window

Returns:

Application exit code

Return type:

int

static exec()[source]

Execute the application.

register_window(window)[source]

Register a window with the application.

Parameters:

window (BaseWindow) – Window to register

property resource_manager: ResourceManager

Get resource manager.

property settings: QSettings

Get settings object.

staticMetaObject = PySide6.QtCore.QMetaObject("Application" inherits "QApplication": Methods:   #33 type=Signal, signature=theme_changed(QString), parameters=QString   #34 type=Signal, signature=context_changed() )
theme_changed
property theme_manager: ThemeManager

Get theme manager.

unregister_window(window)[source]

Unregister a window from the application.

Parameters:

window (BaseWindow) – Window to unregister

Base window implementation.

class qtframework.core.window.BaseWindow(application=None, *, parent=None, title='Qt Framework Window')[source]

Bases: QMainWindow

Base window class with framework integration.

property application: Application | None

Get parent application.

closeEvent(event)[source]

Handle window close event.

Parameters:

event (Any) – Close event

staticMetaObject = PySide6.QtCore.QMetaObject("BaseWindow" inherits "QMainWindow": Methods:   #39 type=Signal, signature=window_closed() )
window_closed

Application context management.

class qtframework.core.context.Context[source]

Bases: QObject

Application-wide context for sharing state.

clear()[source]

Clear all context values.

get(key, default=None)[source]

Get a context value.

Parameters:
  • key (str) – Context key

  • default (Any) – Default value if key not found

Returns:

Context value or default

Return type:

Any

items()[source]

Get all context items.

Returns:

List of (key, value) tuples

Return type:

list[tuple[str, Any]]

keys()[source]

Get all context keys.

Returns:

List of context keys

Return type:

list[str]

remove(key)[source]

Remove a context value.

Parameters:

key (str) – Context key to remove

set(key, value)[source]

Set a context value.

Parameters:
  • key (str) – Context key

  • value (Any) – Value to set

staticMetaObject = PySide6.QtCore.QMetaObject("Context" inherits "QObject": Methods:   #4 type=Signal, signature=value_changed(QString,PyObject), parameters=QString, PyObject )
update(data)[source]

Update multiple context values.

Parameters:

data (dict[str, Any]) – Dictionary of values to update

value_changed

Theming (qtframework.themes)

Modern token-based theming system with light, dark, and high contrast themes.

  • See Theming Guide for comprehensive theming guide

  • Design tokens provide semantic color system

  • Hot-reload support for rapid development

  • Custom theme creation via Python or YAML

Modern theme class using design tokens.

This module defines the Theme class which represents a complete visual theme for the application using a design token system.

Example

Create and use a theme from YAML:

from qtframework.themes.theme import Theme
from pathlib import Path

# Define theme in YAML file (my_theme.yaml):
# name: "custom"
# display_name: "Custom Theme"
# description: "A custom application theme"
# author: "Your Name"
# version: "1.0.0"
# tokens:
#   semantic:
#     bg_primary: "#FFFFFF"
#     fg_primary: "#000000"
#     action_primary: "#007AFF"
#     action_secondary: "#5856D6"
#   spacing:
#     xs: 4
#     sm: 8
#     md: 16
#     lg: 24
#   typography:
#     font_family: "Segoe UI"
#     font_size_base: 14

# Load theme from YAML
theme = Theme.from_yaml("my_theme.yaml")

# Generate stylesheet
stylesheet = theme.generate_stylesheet()
app.setStyleSheet(stylesheet)

# Access individual tokens
primary_bg = theme.get_token("semantic.bg_primary")
base_spacing = theme.get_token("spacing.md")

# Export theme
theme.save_yaml("exported_theme.yaml")

See also

ThemeManager: Manager for handling multiple themes qtframework.themes.tokens: Design token definitions StylesheetGenerator: Generates Qt stylesheets from tokens

class qtframework.themes.theme.Theme(name, display_name, description='', author='', version='1.0.0', *, tokens=None, custom_styles=None, resource_manager=None)[source]

Bases: object

Modern theme class using design tokens.

Represents a complete application theme with design tokens for colors, spacing, typography, and other visual properties. Themes can be loaded from YAML files or created programmatically.

name

Internal theme identifier

display_name

Human-readable theme name

description

Theme description

author

Theme author

version

Theme version string

tokens

Design tokens defining the theme’s visual properties

custom_styles

Additional custom CSS-like rules

classmethod from_dict(data)[source]

Create theme from dictionary.

Parameters:

data (dict[str, Any]) – Theme configuration dictionary

Returns:

Theme instance

Return type:

Theme

classmethod from_yaml(yaml_path)[source]

Load theme from YAML file.

Parameters:

yaml_path (Path | str) – Path to YAML theme file

Returns:

Theme instance

Raises:
  • FileNotFoundError – If YAML file does not exist

  • yaml.YAMLError – If YAML parsing fails

  • KeyError – If required theme fields are missing

  • ValueError – If theme data is invalid

Return type:

Theme

generate_stylesheet()[source]

Generate Qt stylesheet from theme tokens.

Returns:

Complete Qt stylesheet string

Return type:

str

get_token(token_path)[source]

Get a token value by its path.

Parameters:

token_path (str) – Dot-separated path to token

Returns:

Token value or None

Return type:

str | None

save_yaml(yaml_path)[source]

Save theme to YAML file.

Parameters:

yaml_path (Path | str) – Path to save YAML file

to_dict()[source]

Export theme as dictionary.

Returns:

Theme configuration dictionary

Return type:

dict[str, Any]

Modern theme manager with JSON/YAML support.

This module provides a comprehensive theme management system that supports built-in themes, custom theme loading from YAML files, and programmatic theme creation.

Example

Create and register a custom theme:

from qtframework.themes.theme_manager import ThemeManager
from qtframework.themes.theme import Theme
from qtframework.themes.tokens import DesignTokens, SemanticColors
from pathlib import Path

# Initialize theme manager
theme_manager = ThemeManager(themes_dir=Path("my_themes"))

# Use built-in themes
theme_manager.set_theme("light")
theme_manager.set_theme("dark")

# Create a custom theme programmatically
custom_theme = theme_manager.create_theme_from_colors(
    name="ocean",
    primary_color="#0077BE",
    background_color="#F0F8FF",
    is_dark=False,
    display_name="Ocean Theme",
    description="A calming blue ocean theme",
)

# Register the custom theme
theme_manager.register_theme(custom_theme)
theme_manager.set_theme("ocean")

# Apply theme to application
app = QApplication.instance()
stylesheet = theme_manager.get_stylesheet()
app.setStyleSheet(stylesheet)

# Listen for theme changes
theme_manager.theme_changed.connect(
    lambda name: print(f"Theme changed to: {name}")
)

# Export theme for sharing
theme_manager.export_theme("ocean", "ocean_theme.yaml")

See also

Theme: Theme class with design tokens qtframework.themes.tokens: Design token system qtframework.core.application: Application class that integrates themes

class qtframework.themes.theme_manager.ThemeManager(themes_dir=None, font_scale=100, resource_manager=None, excluded_builtin_themes=None, excluded_themes=None, included_themes=None, include_auto_theme=True)[source]

Bases: QObject

Modern theme manager for handling application themes.

create_theme_from_colors(name, primary_color, background_color, is_dark=False, **kwargs)[source]

Create a simple theme from basic color values.

Parameters:
  • name (str) – Theme name

  • primary_color (str) – Primary accent color

  • background_color (str) – Background color

  • is_dark (bool) – Whether this is a dark theme

  • **kwargs – Additional theme properties

Returns:

New theme instance

Return type:

Theme

detect_system_theme()[source]

Detect the system’s light/dark mode preference.

Returns:

‘dark’ if system is in dark mode, ‘light’ otherwise

Return type:

str

export_theme(theme_name, export_path, format='json')[source]

Export a theme to a file.

Parameters:
  • theme_name (str) – Name of the theme to export

  • export_path (str | Path) – Path to export the theme to

  • format (str) – Export format (‘yaml’ or ‘yml’ only)

Returns:

True if exported successfully

Return type:

bool

get_current_theme()[source]

Get the current active theme.

Returns:

Current theme instance

Return type:

Theme

get_stylesheet(theme_name=None)[source]

Get the stylesheet for a theme.

Parameters:

theme_name (str | None) – Theme name, or None for current theme

Returns:

Generated Qt stylesheet string

Return type:

str

get_theme(theme_name=None)[source]

Get a theme by name.

Parameters:

theme_name (str | None) – Theme name, or None for current theme

Returns:

Theme instance or None if not found

Return type:

Theme | None

get_theme_info(theme_name)[source]

Get information about a theme.

Parameters:

theme_name (str) – Name of the theme

Returns:

Theme information dictionary or None

Return type:

dict[str, str] | None

list_themes()[source]

List all available theme names.

Returns:

List of theme names with ‘auto’ first if enabled

Return type:

list[str]

register_theme(theme, override=True)[source]

Register a theme programmatically.

Parameters:
  • theme (Theme) – Theme to register

  • override (bool) – If True, override existing theme with same name (default: True)

Returns:

True if registered successfully

Return type:

bool

reload_themes()[source]

Reload all custom themes from disk.

set_font_scale(scale_percent)[source]

Set the font scale percentage.

Parameters:

scale_percent (int) – Font scale percentage (50-200)

set_theme(theme_name)[source]

Set the current theme.

Parameters:

theme_name (str) – Name of the theme to activate (use ‘auto’ for system theme detection)

Returns:

True if theme was set successfully

Return type:

bool

staticMetaObject = PySide6.QtCore.QMetaObject("ThemeManager" inherits "QObject": Methods:   #4 type=Signal, signature=theme_changed(QString), parameters=QString )
theme_changed
unregister_theme(theme_name)[source]

Unregister a theme.

Parameters:

theme_name (str) – Name of the theme to unregister

Returns:

True if unregistered successfully

Return type:

bool

Design token system for theming.

class qtframework.themes.tokens.BorderRadius(*, radius_none=0, radius_sm=2, radius_md=4, radius_lg=6, radius_xl=8, radius_2xl=12, radius_3xl=16, radius_full=9999)[source]

Bases: BaseModel

Border radius tokens.

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

radius_2xl: int
radius_3xl: int
radius_full: int
radius_lg: int
radius_md: int
radius_none: int
radius_sm: int
radius_xl: int
class qtframework.themes.tokens.ComponentColors(*, button_primary_bg='', button_primary_fg='', button_primary_border='', button_secondary_bg='', button_secondary_fg='', button_secondary_border='', button_image='', button_hover_image='', button_pressed_image='', button_disabled_image='', button_border_slice='', input_bg='', input_fg='', input_border='', input_placeholder='', combobox_bg='', combobox_fg='', combobox_border='', combobox_arrow_image='', combobox_arrow_hover_image='', combobox_arrow_pressed_image='', combobox_arrow_disabled_image='', combobox_arrow_width=20, combobox_arrow_height=20, table_header_bg='', table_header_fg='', table_row_bg='', table_row_bg_alt='', table_row_hover='', table_row_selected='', table_border='', tree_branch_closed_image='', tree_branch_open_image='', tree_branch_closed_hover_image='', tree_branch_open_hover_image='', tree_branch_closed_pressed_image='', tree_branch_open_pressed_image='', menu_bg='', menu_fg='', menu_hover_bg='', menu_hover_fg='', menu_selected_bg='', menu_selected_fg='', scrollbar_bg='', scrollbar_thumb='', scrollbar_thumb_hover='', scrollbar_thumb_pressed='', scrollbar_thumb_border='', scrollbar_width=None, scrollbar_height=None, scrollbar_bg_image='', scrollbar_thumb_image='', scrollbar_thumb_hover_image='', scrollbar_thumb_pressed_image='', scrollbar_thumb_border_slice='', scrollbar_thumb_hover_border_slice='', scrollbar_thumb_pressed_border_slice='', scrollbar_bg_border_slice='', scrollbar_arrow_bg='', scrollbar_arrow_bg_hover='', scrollbar_arrow_bg_pressed='', scrollbar_up_arrow_image='', scrollbar_down_arrow_image='', scrollbar_left_arrow_image='', scrollbar_right_arrow_image='', scrollbar_arrow_size=None, scrollbar_arrow_width=None, scrollbar_arrow_height=None, scrollbar_arrow_width_horizontal=None, scrollbar_arrow_height_horizontal=None, tab_bg='', tab_fg='', tab_active_bg='', tab_active_fg='', tab_hover_bg='', tab_hover_fg='', chart_1='', chart_2='', chart_3='', chart_4='', chart_5='', chart_6='', chart_grid='', chart_axis='', badge_default_bg='', badge_default_fg='', badge_default_border='', badge_primary_bg='', badge_primary_fg='', badge_primary_border='', badge_secondary_bg='', badge_secondary_fg='', badge_secondary_border='', badge_success_bg='', badge_success_fg='', badge_success_border='', badge_warning_bg='', badge_warning_fg='', badge_warning_border='', badge_danger_bg='', badge_danger_fg='', badge_danger_border='', badge_info_bg='', badge_info_fg='', badge_info_border='', badge_light_bg='', badge_light_fg='', badge_light_border='', badge_dark_bg='', badge_dark_fg='', badge_dark_border='')[source]

Bases: BaseModel

Component-specific color tokens.

badge_danger_bg: str
badge_danger_border: str
badge_danger_fg: str
badge_dark_bg: str
badge_dark_border: str
badge_dark_fg: str
badge_default_bg: str
badge_default_border: str
badge_default_fg: str
badge_info_bg: str
badge_info_border: str
badge_info_fg: str
badge_light_bg: str
badge_light_border: str
badge_light_fg: str
badge_primary_bg: str
badge_primary_border: str
badge_primary_fg: str
badge_secondary_bg: str
badge_secondary_border: str
badge_secondary_fg: str
badge_success_bg: str
badge_success_border: str
badge_success_fg: str
badge_warning_bg: str
badge_warning_border: str
badge_warning_fg: str
button_border_slice: str
button_disabled_image: str
button_hover_image: str
button_image: str
button_pressed_image: str
button_primary_bg: str
button_primary_border: str
button_primary_fg: str
button_secondary_bg: str
button_secondary_border: str
button_secondary_fg: str
chart_1: str
chart_2: str
chart_3: str
chart_4: str
chart_5: str
chart_6: str
chart_axis: str
chart_grid: str
combobox_arrow_disabled_image: str
combobox_arrow_height: int
combobox_arrow_hover_image: str
combobox_arrow_image: str
combobox_arrow_pressed_image: str
combobox_arrow_width: int
combobox_bg: str
combobox_border: str
combobox_fg: str
input_bg: str
input_border: str
input_fg: str
input_placeholder: str
menu_bg: str
menu_fg: str
menu_hover_bg: str
menu_hover_fg: str
menu_selected_bg: str
menu_selected_fg: str
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

scrollbar_arrow_bg: str
scrollbar_arrow_bg_hover: str
scrollbar_arrow_bg_pressed: str
scrollbar_arrow_height: int | None
scrollbar_arrow_height_horizontal: int | None
scrollbar_arrow_size: int | None
scrollbar_arrow_width: int | None
scrollbar_arrow_width_horizontal: int | None
scrollbar_bg: str
scrollbar_bg_border_slice: str
scrollbar_bg_image: str
scrollbar_down_arrow_image: str
scrollbar_height: int | None
scrollbar_left_arrow_image: str
scrollbar_right_arrow_image: str
scrollbar_thumb: str
scrollbar_thumb_border: str
scrollbar_thumb_border_slice: str
scrollbar_thumb_hover: str
scrollbar_thumb_hover_border_slice: str
scrollbar_thumb_hover_image: str
scrollbar_thumb_image: str
scrollbar_thumb_pressed: str
scrollbar_thumb_pressed_border_slice: str
scrollbar_thumb_pressed_image: str
scrollbar_up_arrow_image: str
scrollbar_width: int | None
tab_active_bg: str
tab_active_fg: str
tab_bg: str
tab_fg: str
tab_hover_bg: str
tab_hover_fg: str
table_border: str
table_header_bg: str
table_header_fg: str
table_row_bg: str
table_row_bg_alt: str
table_row_hover: str
table_row_selected: str
tree_branch_closed_hover_image: str
tree_branch_closed_image: str
tree_branch_closed_pressed_image: str
tree_branch_open_hover_image: str
tree_branch_open_image: str
tree_branch_open_pressed_image: str
class qtframework.themes.tokens.DesignTokens(primitive=<factory>, semantic=<factory>, components=<factory>, typography=<factory>, spacing=<factory>, borders=<factory>, shadows=<factory>, transitions=<factory>, syntax=<factory>, custom=<factory>)[source]

Bases: object

Complete design token system.

Supports extension with custom token categories for app-specific needs. Custom tokens can be added via the ‘custom’ field or by adding new top-level categories in YAML that aren’t part of the standard token set.

Example

Add custom ping colors in your theme YAML:

tokens:
ping:

excellent: “#00FF00” good: “#FFFF00” poor: “#FF0000”

Access via: theme.tokens.get_custom(“ping.excellent”)

apply_font_scale(scale_percent=100)[source]

Apply font scaling to all typography tokens.

Parameters:

scale_percent (int) – Percentage to scale fonts (e.g., 100 = normal, 125 = 125%, 150 = 150%)

borders: BorderRadius
components: ComponentColors
custom: dict[str, Any]
classmethod from_dict(data)[source]

Create DesignTokens from dictionary.

Automatically preserves any custom token categories not in the standard set.

get_custom(token_path, default=None)[source]

Get a custom token value by path.

Convenience method for accessing custom tokens.

Parameters:
  • token_path (str) – Dot-separated path within custom tokens (e.g., “ping.excellent”)

  • default (Any) – Default value if token not found

Returns:

Token value or default

Return type:

Any

Example

>>> tokens.get_custom("ping.excellent", "#00FF00")
"#00FF00"
primitive: PrimitiveColors
resolve_semantic_colors()[source]

Resolve semantic color references to actual values.

resolve_token(token_path)[source]

Resolve a token path to its value.

Supports both standard and custom token paths.

Parameters:

token_path (str) – Dot-separated path to token (e.g., “primitive.primary_500” or “ping.excellent”)

Returns:

Token value or None if not found

Return type:

str | None

Example

>>> tokens.resolve_token("primitive.primary_500")
"#2196F3"
>>> tokens.resolve_token("ping.excellent")  # custom token
"#00FF00"
semantic: SemanticColors
shadows: Shadows
spacing: Spacing
syntax: SyntaxColors
to_dict()[source]

Convert tokens to dictionary format.

Includes both standard and custom token categories.

transitions: Transitions
typography: Typography
class qtframework.themes.tokens.PrimitiveColors(*, gray_50='#FAFAFA', gray_100='#F5F5F5', gray_200='#EEEEEE', gray_300='#E0E0E0', gray_400='#BDBDBD', gray_500='#9E9E9E', gray_600='#757575', gray_700='#616161', gray_800='#424242', gray_900='#212121', gray_950='#121212', primary_50='#E3F2FD', primary_100='#BBDEFB', primary_200='#90CAF9', primary_300='#64B5F6', primary_400='#42A5F5', primary_500='#2196F3', primary_600='#1E88E5', primary_700='#1976D2', primary_800='#1565C0', primary_900='#0D47A1', primary_950='#0A3A7F', secondary_50='#FFF8E1', secondary_100='#FFECB3', secondary_200='#FFE082', secondary_300='#FFD54F', secondary_400='#FFCA28', secondary_500='#FFC107', secondary_600='#FFB300', secondary_700='#FFA000', secondary_800='#FF8F00', secondary_900='#FF6F00', secondary_950='#E65100', success_50='#E8F5E9', success_100='#C8E6C9', success_200='#A5D6A7', success_300='#81C784', success_400='#66BB6A', success_500='#4CAF50', success_600='#43A047', success_700='#388E3C', success_800='#2E7D32', success_900='#1B5E20', success_950='#0D4018', warning_50='#FFF3E0', warning_100='#FFE0B2', warning_200='#FFCC80', warning_300='#FFB74D', warning_400='#FFA726', warning_500='#FF9800', warning_600='#FB8C00', warning_700='#F57C00', warning_800='#EF6C00', warning_900='#E65100', warning_950='#BF360C', error_50='#FFEBEE', error_100='#FFCDD2', error_200='#EF9A9A', error_300='#E57373', error_400='#EF5350', error_500='#F44336', error_600='#E53935', error_700='#D32F2F', error_800='#C62828', error_900='#B71C1C', error_950='#7F0000', info_50='#E0F7FA', info_100='#B2EBF2', info_200='#80DEEA', info_300='#4DD0E1', info_400='#26C6DA', info_500='#00BCD4', info_600='#00ACC1', info_700='#0097A7', info_800='#00838F', info_900='#006064', info_950='#004D50', white='#FFFFFF', black='#000000', transparent='transparent')[source]

Bases: BaseModel

Primitive color tokens - raw color values.

black: str
error_100: str
error_200: str
error_300: str
error_400: str
error_50: str
error_500: str
error_600: str
error_700: str
error_800: str
error_900: str
error_950: str
gray_100: str
gray_200: str
gray_300: str
gray_400: str
gray_50: str
gray_500: str
gray_600: str
gray_700: str
gray_800: str
gray_900: str
gray_950: str
info_100: str
info_200: str
info_300: str
info_400: str
info_50: str
info_500: str
info_600: str
info_700: str
info_800: str
info_900: str
info_950: str
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

primary_100: str
primary_200: str
primary_300: str
primary_400: str
primary_50: str
primary_500: str
primary_600: str
primary_700: str
primary_800: str
primary_900: str
primary_950: str
secondary_100: str
secondary_200: str
secondary_300: str
secondary_400: str
secondary_50: str
secondary_500: str
secondary_600: str
secondary_700: str
secondary_800: str
secondary_900: str
secondary_950: str
success_100: str
success_200: str
success_300: str
success_400: str
success_50: str
success_500: str
success_600: str
success_700: str
success_800: str
success_900: str
success_950: str
transparent: str
warning_100: str
warning_200: str
warning_300: str
warning_400: str
warning_50: str
warning_500: str
warning_600: str
warning_700: str
warning_800: str
warning_900: str
warning_950: str
white: str
class qtframework.themes.tokens.SemanticColors(*, bg_primary='', bg_secondary='', bg_tertiary='', bg_elevated='', bg_overlay='', fg_primary='', fg_secondary='', fg_tertiary='', fg_on_accent='', fg_on_dark='', fg_on_light='', action_primary='', action_primary_hover='', action_primary_active='', action_secondary='', action_secondary_hover='', action_secondary_active='', feedback_success='', feedback_warning='', feedback_error='', feedback_info='', border_default='', border_subtle='', border_strong='', border_focus='', state_hover='', state_selected='', state_disabled='', state_focus='')[source]

Bases: BaseModel

Semantic color tokens - meaning-based references.

action_primary: str
action_primary_active: str
action_primary_hover: str
action_secondary: str
action_secondary_active: str
action_secondary_hover: str
bg_elevated: str
bg_overlay: str
bg_primary: str
bg_secondary: str
bg_tertiary: str
border_default: str
border_focus: str
border_strong: str
border_subtle: str
feedback_error: str
feedback_info: str
feedback_success: str
feedback_warning: str
fg_on_accent: str
fg_on_dark: str
fg_on_light: str
fg_primary: str
fg_secondary: str
fg_tertiary: str
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

state_disabled: str
state_focus: str
state_hover: str
state_selected: str
class qtframework.themes.tokens.Shadows(*, shadow_none='none', shadow_sm='0 1px 2px 0 rgba(0, 0, 0, 0.05)', shadow_md='0 4px 6px -1px rgba(0, 0, 0, 0.1)', shadow_lg='0 10px 15px -3px rgba(0, 0, 0, 0.1)', shadow_xl='0 20px 25px -5px rgba(0, 0, 0, 0.1)', shadow_2xl='0 25px 50px -12px rgba(0, 0, 0, 0.25)', shadow_inner='inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)')[source]

Bases: BaseModel

Shadow tokens.

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

shadow_2xl: str
shadow_inner: str
shadow_lg: str
shadow_md: str
shadow_none: str
shadow_sm: str
shadow_xl: str
class qtframework.themes.tokens.Spacing(*, space_0=0, space_1=2, space_2=4, space_3=6, space_4=8, space_5=10, space_6=12, space_8=16, space_10=20, space_12=24, space_16=32, space_20=40, space_24=48, space_32=64)[source]

Bases: BaseModel

Spacing tokens.

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

space_0: int
space_1: int
space_10: int
space_12: int
space_16: int
space_2: int
space_20: int
space_24: int
space_3: int
space_32: int
space_4: int
space_5: int
space_6: int
space_8: int
class qtframework.themes.tokens.SyntaxColors(*, keyword='#0000FF', class_name='#267F99', function='#795E26', string='#A31515', comment='#008000', number='#098658', operator='#000000', decorator='#AA0000', constant='#0000FF', variable='#001080', parameter='#001080', type='#267F99', namespace='#267F99', error='#FF0000', warning='#FFA500', info='#0000FF')[source]

Bases: BaseModel

Syntax highlighting color tokens.

class_name: str
comment: str
constant: str
decorator: str
error: str
function: str
info: str
keyword: str
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

namespace: str
number: str
operator: str
parameter: str
string: str
type: str
variable: str
warning: str
class qtframework.themes.tokens.Transitions(*, transition_fast='150ms ease-in-out', transition_normal='250ms ease-in-out', transition_slow='350ms ease-in-out')[source]

Bases: BaseModel

Transition/animation tokens.

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

transition_fast: str
transition_normal: str
transition_slow: str
class qtframework.themes.tokens.Typography(*, font_family_default="'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica', sans-serif", font_family_mono="'Cascadia Code', 'Consolas', 'Monaco', 'Courier New', monospace", font_family_code='Consolas', font_size_xs=11, font_size_sm=12, font_size_md=14, font_size_lg=16, font_size_xl=18, font_size_2xl=20, font_size_3xl=24, font_size_4xl=28, font_size_5xl=32, font_weight_thin=100, font_weight_light=300, font_weight_normal=400, font_weight_medium=500, font_weight_semibold=600, font_weight_bold=700, font_weight_black=900, line_height_tight=1.2, line_height_normal=1.5, line_height_relaxed=1.75, line_height_loose=2.0)[source]

Bases: BaseModel

Typography tokens.

font_family_code: str
font_family_default: str
font_family_mono: str
font_size_2xl: int
font_size_3xl: int
font_size_4xl: int
font_size_5xl: int
font_size_lg: int
font_size_md: int
font_size_sm: int
font_size_xl: int
font_size_xs: int
font_weight_black: int
font_weight_bold: int
font_weight_light: int
font_weight_medium: int
font_weight_normal: int
font_weight_semibold: int
font_weight_thin: int
line_height_loose: float
line_height_normal: float
line_height_relaxed: float
line_height_tight: float
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

Built-in themes using the modern token system.

qtframework.themes.builtin_themes.create_dark_theme()[source]

Create the built-in dark theme.

qtframework.themes.builtin_themes.create_high_contrast_theme()[source]

Create a high contrast theme for accessibility.

qtframework.themes.builtin_themes.create_light_theme()[source]

Create the built-in light theme.

State Management (qtframework.state)

Redux-inspired state management for predictable application state.

  • See State Management Guide for detailed guide

  • Single source of truth for application state

  • Pure reducers for state transformations

  • Middleware for async operations

Redux-like state store implementation.

This module provides a centralized state management system based on Redux patterns, featuring unidirectional data flow, pure reducers, and middleware support.

Example

Basic store usage with reducer:

from qtframework.state import Store, Action, create_reducer

# Define initial state
initial_state = {"count": 0, "user": None}


# Create reducer
def counter_reducer(state, action):
    if action.type == "INCREMENT":
        return {**state, "count": state["count"] + 1}
    elif action.type == "DECREMENT":
        return {**state, "count": state["count"] - 1}
    elif action.type == "SET_USER":
        return {**state, "user": action.payload}
    return state


# Create store
store = Store(reducer=counter_reducer, initial_state=initial_state)


# Subscribe to changes
def on_change(state):
    print(f"Count: {state['count']}")


unsubscribe = store.subscribe(on_change)

# Dispatch actions
store.dispatch(Action(type="INCREMENT"))  # Output: Count: 1
store.dispatch(Action(type="INCREMENT"))  # Output: Count: 2

# Unsubscribe when done
unsubscribe()

With middleware:

from qtframework.state import logger_middleware, thunk_middleware

store = Store(
    reducer=counter_reducer,
    initial_state=initial_state,
    middleware=[logger_middleware(), thunk_middleware()],
)

# Middleware processes actions before they reach the reducer
store.dispatch(Action(type="INCREMENT"))
# Logger middleware will log the action and state changes

Combining reducers:

from qtframework.state import combine_reducers


def user_reducer(state=None, action=None):
    if action.type == "SET_USER":
        return action.payload
    elif action.type == "LOGOUT":
        return None
    return state


def items_reducer(state=None, action=None):
    if state is None:
        state = []
    if action.type == "ADD_ITEM":
        return [*state, action.payload]
    elif action.type == "REMOVE_ITEM":
        return [item for item in state if item["id"] != action.payload]
    return state


root_reducer = combine_reducers({
    "user": user_reducer,
    "items": items_reducer,
    "count": counter_reducer,
})

store = Store(
    reducer=root_reducer, initial_state={"user": None, "items": [], "count": 0}
)

See also

class qtframework.state.store.Store(reducer, initial_state=None, middleware=None)[source]

Bases: QObject

Centralized state store with Redux-like pattern.

The Store holds the application state and provides methods to: - Dispatch actions to modify state - Subscribe to state changes - Access current state (read-only) - Navigate state history (time-travel debugging)

Signals:

state_changed(dict): Emitted when state changes action_dispatched(dict): Emitted when action is dispatched

Example

Creating and using a store:

store = Store(reducer=my_reducer, initial_state={"count": 0})

# Subscribe to changes
store.state_changed.connect(lambda state: print(state))

# Dispatch actions
store.dispatch(Action(type="INCREMENT"))
action_dispatched
add_middleware(middleware)[source]

Add middleware to the store.

Parameters:

middleware (Middleware) – Middleware to add

dispatch(action)[source]

Dispatch an action to update state.

Actions are processed through middleware (if any) before reaching the reducer. The reducer creates a new state, which triggers subscriber notifications.

Parameters:

action (Action | dict[str, Any]) – Action to dispatch (Action object or dict with type/payload)

Returns:

Dispatched action (converted to Action if dict was provided)

Raises:
  • RuntimeError – If dispatch is called while already dispatching (prevents nested dispatches which can cause race conditions)

  • TypeError – If action cannot be converted to Action

Return type:

Action

Example:

# Dispatch with Action object
store.dispatch(Action(type="INCREMENT"))

# Dispatch with dict
store.dispatch({"type": "SET_USER", "payload": {"id": 1}})
get_history()[source]

Get state history for time-travel debugging.

Returns:

Deep copy of all historical states (up to 100 states)

Return type:

list[dict[str, Any]]

Note

Returns a deep copy of history to prevent external modifications. For large state objects, this may be memory-intensive. History is automatically limited to the last 100 states (configurable via _max_history).

Example:

# Get and display history
history = store.get_history()
for i, state in enumerate(history):
    print(f"State {i}: {state}")
get_state()[source]

Get current state.

Returns:

Copy of current state

Return type:

dict[str, Any]

redo()[source]

Redo previously undone state change.

Returns:

True if redo successful

Return type:

bool

remove_middleware(middleware)[source]

Remove middleware from the store.

Parameters:

middleware (Middleware) – Middleware to remove

Returns:

True if middleware was found and removed, False otherwise

Return type:

bool

replace_reducer(reducer)[source]

Replace the root reducer.

Parameters:

reducer (Reducer) – New reducer

reset(state=None)[source]

Reset store to initial or provided state.

Parameters:

state (dict[str, Any] | None) – State to reset to

select(selector)[source]

Select a value from state.

Parameters:

selector (Callable[[dict[str, Any]], Any]) – Selector function

Returns:

Selected value

Return type:

Any

select_path(path)[source]

Select value by path (e.g., ‘user.profile.name’).

Parameters:

path (str) – Dot-separated path

Returns:

Value at path or None

Return type:

Any

property state: dict[str, Any]

Get current state (read-only copy).

state_changed
staticMetaObject = PySide6.QtCore.QMetaObject("Store" inherits "QObject": Methods:   #4 type=Signal, signature=state_changed(QVariantMap), parameters=QVariantMap   #5 type=Signal, signature=action_dispatched(QVariantMap), parameters=QVariantMap )
subscribe(callback)[source]

Subscribe to state changes.

Parameters:

callback (Callable[[dict[str, Any]], None]) – Callback function

Returns:

Unsubscribe function

Return type:

Callable[[], None]

undo()[source]

Undo last state change.

Returns:

True if undo successful

Return type:

bool

Action definitions for state management.

class qtframework.state.actions.Action(type, payload=None, meta=<factory>, error=False)[source]

Bases: object

Redux-style action.

error: bool = False
classmethod from_dict(data)[source]

Create action from dictionary.

Parameters:

data (dict[str, Any]) – Action dictionary

Returns:

Action instance

Return type:

Action

meta: dict[str, Any]
payload: Any = None
to_dict()[source]

Convert action to dictionary.

Returns:

Action as dictionary

Return type:

dict[str, Any]

type: str | ActionType
class qtframework.state.actions.ActionCreator(namespace='')[source]

Bases: object

Factory for creating typed actions.

batch(actions)[source]

Create batch action.

Parameters:

actions (list[Action]) – List of actions to batch

Returns:

Batch action

Return type:

Action

create(action_type, payload=None, **meta)[source]

Create an action with namespace.

Parameters:
  • action_type (str) – Action type

  • payload (Any) – Action payload

  • **meta (Any) – Additional metadata

Returns:

Action instance

Return type:

Action

delete(path)[source]

Create delete action.

Parameters:

path (str) – Path to delete

Returns:

Delete action

Return type:

Action

set(data)[source]

Create set action.

Parameters:

data (dict[str, Any]) – Data to set

Returns:

Set action

Return type:

Action

update(path, value)[source]

Create update action.

Parameters:
  • path (str) – State path

  • value (Any) – New value

Returns:

Update action

Return type:

Action

class qtframework.state.actions.ActionType(*values)[source]

Bases: Enum

Common action types.

BATCH = 'BATCH'
CLEAR = 'CLEAR'
DELETE = 'DELETE'
INIT = '@@INIT'
REPLACE = '@@REPLACE'
RESET = '@@RESET'
SET = 'SET'
UPDATE = 'UPDATE'
class qtframework.state.actions.AsyncAction(type, payload=None, meta=None, promise=None)[source]

Bases: Action

Async action with promise support.

qtframework.state.actions.create_action(action_type, payload=None, **meta)[source]

Helper to create an action.

Parameters:
  • action_type (str | ActionType) – Action type

  • payload (Any) – Action payload

  • **meta (Any) – Additional metadata

Returns:

Action instance

Return type:

Action

qtframework.state.actions.create_async_action(action_type, promise, payload=None, **meta)[source]

Helper to create an async action.

Parameters:
  • action_type (str | ActionType) – Action type

  • promise (Any) – Promise or future

  • payload (Any) – Action payload

  • **meta (Any) – Additional metadata

Returns:

AsyncAction instance

Return type:

AsyncAction

Reducer functions for state management.

class qtframework.state.reducers.ReducerBuilder(initial_state=None)[source]

Bases: object

Builder for creating reducers.

build()[source]

Build the reducer.

Returns:

Reducer function

Return type:

Callable[[State, Action], State]

handle(action_type)[source]

Add handler for action type.

Parameters:

action_type (str) – Action type to handle

Returns:

Decorator function

Return type:

Callable[[Callable[[State, Action], State]], ReducerBuilder]

qtframework.state.reducers.combine_reducers(reducers)[source]

Combine multiple reducers into one.

Parameters:

reducers (dict[str, Callable[[State, Action], State]]) – Dictionary of reducers

Returns:

Combined reducer function

Return type:

Callable[[State, Action], State]

qtframework.state.reducers.create_reducer(initial_state, handlers)[source]

Create a reducer with handlers.

Parameters:
  • initial_state (State) – Initial state

  • handlers (dict[str, Callable[[State, Action], State]]) – Dictionary of action handlers

Returns:

Reducer function

Return type:

Callable[[State, Action], State]

qtframework.state.reducers.create_slice_reducer(slice_name, initial_state, reducers)[source]

Create a slice reducer with action creators.

Parameters:
  • slice_name (str) – Name of the slice

  • initial_state (Any) – Initial state for slice

  • reducers (dict[str, Callable[[Any, Any], Any]]) – Reducer functions

Returns:

Tuple of (reducer, action_creators)

Return type:

tuple[Callable[[State, Action], State], dict[str, Callable[[…], Action]]]

qtframework.state.reducers.immutable_delete(state, path)[source]

Immutably delete from nested state.

Parameters:
  • state (dict[str, Any]) – Current state

  • path (str) – Dot-separated path to the key to delete

Returns:

A deep copy of the state with the key removed. Original state is unchanged. Returns unmodified copy if path doesn’t exist.

Return type:

dict[str, Any]

qtframework.state.reducers.immutable_update(state, path, value)[source]

Immutably update nested state.

Parameters:
  • state (dict[str, Any]) – Current state

  • path (str) – Dot-separated path (e.g., “user.profile.name”)

  • value (Any) – New value to set at the path

Returns:

A deep copy of the state with the update applied. Original state is unchanged.

Return type:

dict[str, Any]

Middleware for state store.

qtframework.state.middleware.crash_reporter_middleware()[source]

Middleware that reports crashes and dispatches error actions.

Catches exceptions during action processing, logs them, and dispatches an ERROR_OCCURRED action before re-raising the exception.

qtframework.state.middleware.devtools_middleware()[source]

Middleware for Redux DevTools integration.

Note: DevTools connection not yet implemented. Currently captures state snapshots but doesn’t transmit to external devtools.

qtframework.state.middleware.logger_middleware()[source]

Middleware that logs all actions.

qtframework.state.middleware.promise_middleware()[source]

Middleware for handling promise-based async actions.

Automatically dispatches PENDING, SUCCESS, and ERROR actions for AsyncAction instances with promises, following the Redux async action pattern.

qtframework.state.middleware.thunk_middleware()[source]

Middleware for handling thunk actions (functions).

Allows dispatching functions that receive dispatch and getState as arguments, enabling async action creators and complex logic before dispatching actions.

qtframework.state.middleware.timing_middleware()[source]

Middleware that measures action processing time.

Logs the execution time of each action dispatch in milliseconds, useful for performance monitoring and optimization.

qtframework.state.middleware.validation_middleware(validators)[source]

Middleware that validates actions before dispatching.

Parameters:

validators (dict[str, Callable[[Action], bool]]) – Dictionary mapping action types to validation functions

Returns:

Middleware function

Return type:

Middleware

Internationalization (qtframework.i18n)

Comprehensive i18n support powered by Babel.

  • See Internationalization (i18n) Guide for i18n guide

  • Translation extraction and compilation

  • Runtime language switching

  • Plural forms and context support

  • Locale-aware number and date formatting

Modern i18n manager using Babel with full gettext support.

class qtframework.i18n.babel_manager.BabelI18nManager(locale_dir=None, domain='qtframework', default_locale='en_US', fallback_locales=None, cache_size=128, auto_compile=True)[source]

Bases: QObject

Modern internationalization manager using Babel.

Features: - Full CLDR plural support - Translation contexts (pgettext) - Lazy translations - Multiple domains - Locale fallback chains - Translation caching

domain(domain)[source]

Context manager for temporary domain switch.

Usage:
with i18n.domain(‘emails’):

subject = i18n.t(‘welcome_subject’)

property domain_name: str

Return the active gettext domain.

format_currency(number, currency, **kwargs)[source]

Format currency according to locale.

format_date(date, format='medium')[source]

Format date according to locale.

format_datetime(datetime, format='medium')[source]

Format datetime according to locale.

format_decimal(number, **kwargs)[source]

Format decimal according to locale.

format_number(number, **kwargs)[source]

Format number according to locale.

format_percent(number, **kwargs)[source]

Format percentage according to locale.

format_scientific(number, **kwargs)[source]

Format number in scientific notation.

format_time(time, format='medium')[source]

Format time according to locale.

get_available_locales()[source]

Get list of available locales.

get_current_locale()[source]

Get the current locale code.

get_current_locale_object()[source]

Get the current Babel Locale object.

get_locale_info()[source]

Get detailed information about available locales.

get_plural_categories()[source]

Get plural categories for current locale (zero, one, two, few, many, other).

get_plural_rule()[source]

Get the plural rule for current locale.

gettext(msgid)[source]

Alias for t().

lazy_gettext(msgid)[source]

Get lazy translation that evaluates when accessed.

Parameters:

msgid (str) – Message ID

Returns:

LazyProxy that translates when converted to string

Return type:

LazyProxy

lazy_pgettext(context, msgid)[source]

Lazy translation with context.

locale_changed
ngettext(singular, plural_form, n)[source]

Alias for plural().

npgettext(context, singular, plural_form, n, **kwargs)[source]

Translate plural with context.

Parameters:
  • context (str) – Translation context

  • singular (str) – Singular form

  • plural_form (str) – Plural form

  • n (int) – Number for plural selection

  • **kwargs – Variables for formatting

Returns:

Contextualized plural translation

Return type:

str

pgettext(context, msgid, **kwargs)[source]

Translate with context.

Parameters:
  • context (str) – Translation context

  • msgid (str) – Message ID

  • **kwargs – Variables for formatting

Returns:

Translated string with context consideration

Return type:

str

plural(singular, plural_form, n, **kwargs)[source]

Translate plural message with CLDR rules.

Parameters:
  • singular (str) – Singular form

  • plural_form (str) – Plural form

  • n (int) – Number for plural selection

  • **kwargs – Variables for formatting

Returns:

Correctly pluralized translation

Return type:

str

set_locale(locale)[source]

Set the current locale.

Parameters:

locale (str) – Locale code (e.g., ‘en_US’, ‘es_ES’)

Returns:

True if locale was set successfully

Return type:

bool

staticMetaObject = PySide6.QtCore.QMetaObject("BabelI18nManager" inherits "QObject": Methods:   #4 type=Signal, signature=locale_changed(QString), parameters=QString   #5 type=Signal, signature=translations_reloaded() )
t(msgid, **kwargs)[source]

Translate a message.

Parameters:
  • msgid (str) – Message ID to translate

  • **kwargs – Variables for string formatting

Returns:

Translated and formatted string

Return type:

str

translations_reloaded
qtframework.i18n.babel_manager.get_i18n_manager()[source]

Get the global i18n manager instance.

qtframework.i18n.babel_manager.lazy_gettext(msgid)[source]

Lazy translation using global manager.

qtframework.i18n.babel_manager.pgettext(context, msgid, **kwargs)[source]

Translate with context using global manager.

qtframework.i18n.babel_manager.plural(singular, plural_form, n, **kwargs)[source]

Translate plural using global manager.

qtframework.i18n.babel_manager.set_i18n_manager(manager)[source]

Set the global i18n manager instance.

qtframework.i18n.babel_manager.t(msgid, **kwargs)[source]

Translate using global manager.

Translation context helpers and lazy evaluation support.

This module provides advanced i18n features including: - Translation contexts for disambiguation - Lazy translation evaluation - Message formatting with ICU-style patterns

class qtframework.i18n.contexts.LazyPlural(singular, plural, context=None)[source]

Bases: object

Lazy plural string that delays translation until evaluation.

Example:

# At module level
ITEMS_COUNT = LazyPlural("{count} item", "{count} items")

# Later
print(ITEMS_COUNT.format(count=5))  # "5 items"
format(n, **kwargs)[source]

Format with count and additional parameters.

Parameters:
  • n (int) – Count for pluralization

  • **kwargs – Additional format parameters

Returns:

Translated and formatted string

Return type:

str

class qtframework.i18n.contexts.LazyString(msgid, context=None, **kwargs)[source]

Bases: object

Lazy string that delays translation until str() is called.

This is useful for module-level constants that need translation but are defined before the locale is set.

Usage:

# At module level ERROR_MESSAGE = LazyString(“An error occurred”)

# Later, when locale is set print(str(ERROR_MESSAGE)) # Translates to current locale

format(**kwargs)[source]

Create new LazyString with additional format parameters.

class qtframework.i18n.contexts.MessageFormatter[source]

Bases: object

Advanced message formatter supporting ICU-style patterns.

This provides more complex formatting than simple string.format(), including gender, select cases, and nested patterns.

Usage:

formatter = MessageFormatter()

# Gender-aware messages pattern = “{name} {gender, select, male {his} female {her} other {their}} profile” result = formatter.format(pattern, name=”Alex”, gender=”female”) # “Alex her profile”

# Plural with select pattern = “{count, plural, =0 {no items} one {# item} other {# items}}” result = formatter.format(pattern, count=5) # “5 items”

format(pattern, **kwargs)[source]

Format a pattern with parameters.

Parameters:
  • pattern (str) – ICU-style message pattern

  • **kwargs – Parameters for formatting

Returns:

Formatted string

Return type:

str

class qtframework.i18n.contexts.TranslationContext(context)[source]

Bases: object

Context for disambiguating translations.

Usage:

# Same word, different meanings may_month = pgettext(“month”, “May”) may_permission = pgettext(“permission”, “May”)

# Widget-specific context save_button = pgettext(“button”, “Save”) save_menu = pgettext(“menu”, “Save”)

lazy(msgid)[source]

Create lazy translation with this context.

plural(singular, plural_form, n, **kwargs)[source]

Translate plural with this context.

t(msgid, **kwargs)[source]

Translate with this context.

class qtframework.i18n.contexts.UIContext[source]

Bases: object

Standard UI element contexts.

button = <qtframework.i18n.contexts.TranslationContext object>
dialog = <qtframework.i18n.contexts.TranslationContext object>
error = <qtframework.i18n.contexts.TranslationContext object>
footer = <qtframework.i18n.contexts.TranslationContext object>
header = <qtframework.i18n.contexts.TranslationContext object>
info = <qtframework.i18n.contexts.TranslationContext object>
label = <qtframework.i18n.contexts.TranslationContext object>
menu = <qtframework.i18n.contexts.TranslationContext object>
placeholder = <qtframework.i18n.contexts.TranslationContext object>
success = <qtframework.i18n.contexts.TranslationContext object>
tab = <qtframework.i18n.contexts.TranslationContext object>
title = <qtframework.i18n.contexts.TranslationContext object>
tooltip = <qtframework.i18n.contexts.TranslationContext object>
warning = <qtframework.i18n.contexts.TranslationContext object>
qtframework.i18n.contexts.lazy(msgid, context=None, **kwargs)[source]

Create a lazy translatable string.

qtframework.i18n.contexts.lazy_plural(singular, plural, context=None)[source]

Create a lazy plural string.

qtframework.i18n.contexts.translatable_property(context=None)[source]

Decorator for creating translatable class properties.

Example:

class MyWidget:
    @translatable_property("tooltip")
    def help_text(self):
        return "Click here for help"

The property will automatically translate when accessed.

Qt widget integration for i18n.

class qtframework.i18n.widgets.LanguageSelector(parent=None)[source]

Bases: QComboBox

Combo box for selecting application language.

language_changed
staticMetaObject = PySide6.QtCore.QMetaObject("LanguageSelector" inherits "QComboBox": Methods:   #46 type=Signal, signature=language_changed(QString), parameters=QString )
class qtframework.i18n.widgets.TranslatableAction(translation_key=None, parent=None, **kwargs)[source]

Bases: QAction, TranslatableWidget

QAction with automatic translation support.

staticMetaObject = PySide6.QtCore.QMetaObject("TranslatableAction" inherits "QAction": )
class qtframework.i18n.widgets.TranslatableButton(translation_key=None, parent=None, **kwargs)[source]

Bases: QPushButton, TranslatableWidget

QPushButton with automatic translation support.

staticMetaObject = PySide6.QtCore.QMetaObject("TranslatableButton" inherits "QPushButton": )
class qtframework.i18n.widgets.TranslatableLabel(translation_key=None, parent=None, **kwargs)[source]

Bases: QLabel, TranslatableWidget

QLabel with automatic translation support.

staticMetaObject = PySide6.QtCore.QMetaObject("TranslatableLabel" inherits "QLabel": )
class qtframework.i18n.widgets.TranslatableMenu(translation_key=None, parent=None, **kwargs)[source]

Bases: QMenu, TranslatableWidget

QMenu with automatic translation support.

staticMetaObject = PySide6.QtCore.QMetaObject("TranslatableMenu" inherits "QMenu": )
class qtframework.i18n.widgets.TranslatableWidget[source]

Bases: object

Mixin for widgets that support automatic translation updates.

set_plural_translation(singular, plural, count, **kwargs)[source]

Set plural translation for this widget.

Parameters:
  • singular (str) – Singular form (msgid)

  • plural (str) – Plural form (msgid_plural)

  • count (int) – Count for pluralization

  • **kwargs – Additional variables

set_translation_key(key, **kwargs)[source]

Set the translation key for this widget.

Parameters:
  • key (str) – Translation key

  • **kwargs – Variables for string interpolation

class qtframework.i18n.widgets.TranslationHelper(widget)[source]

Bases: object

Helper class for managing translations in complex widgets.

clear()[source]

Clear all registered translations.

register(element, key, setter='setText', **kwargs)[source]

Register an element for automatic translation.

Parameters:
  • element (Any) – UI element to translate

  • key (str) – Translation key

  • setter (str) – Method name to set text (default: “setText”)

  • **kwargs – Translation arguments

register_plural(element, key, count, setter='setText', **kwargs)[source]

Register an element for plural translation.

Parameters:
  • element (Any) – UI element to translate

  • key (str) – Translation key

  • count (int) – Count for pluralization

  • setter (str) – Method name to set text

  • **kwargs – Additional arguments

update_count(element, count)[source]

Update the count for a plural translation.

Parameters:
  • element (Any) – UI element

  • count (int) – New count

qtframework.i18n.widgets.setup_widget_translations(widget)[source]

Setup translation helper for a widget.

Parameters:

widget (QWidget) – Widget to setup translations for

Returns:

TranslationHelper instance

Return type:

TranslationHelper

qtframework.i18n.widgets.translatable(translation_key=None, **default_args)[source]

Decorator to make a method automatically translatable.

Parameters:
  • translation_key (str | None) – Translation key to use

  • **default_args – Default translation arguments

Returns:

Decorated method

Plugins (qtframework.plugins)

Extensible plugin system for modular applications.

  • See Plugins Guide for plugin development guide

  • Dynamic loading and unloading

  • Dependency resolution

  • Plugin lifecycle management

  • Hot reload support

Base plugin classes and interfaces.

This module defines the base plugin system for extending Qt Framework applications. Plugins can add new features, modify behavior, and integrate with the application lifecycle.

Example

Complete plugin implementation:

from qtframework.plugins.base import Plugin, PluginMetadata, PluginState
from PySide6.QtWidgets import QAction, QMessageBox

# Define plugin metadata
metadata = PluginMetadata(
    id="com.example.hello",
    name="Hello Plugin",
    version="1.0.0",
    description="A simple hello world plugin",
    author="Your Name",
    category="utility",
    dependencies=[],
)


# Create plugin class
class HelloPlugin(Plugin):
    def __init__(self):
        super().__init__(metadata)
        self.action = None

    def initialize(self) -> bool:
        '''Called once when plugin is loaded'''
        self.log("Plugin initializing...", "info")
        # Load resources, initialize state
        return True

    def activate(self) -> bool:
        '''Called when plugin is activated'''
        self.log("Plugin activated", "info")

        # Add menu action to application
        if self.application:
            self.action = QAction("Say Hello", self.application.window)
            self.action.triggered.connect(self.show_hello)

            # Add to Tools menu
            tools_menu = self.application.window.menuBar().addMenu("Tools")
            tools_menu.addAction(self.action)

        return True

    def deactivate(self) -> bool:
        '''Called when plugin is deactivated'''
        self.log("Plugin deactivated", "info")

        # Remove UI elements
        if self.action:
            self.action.deleteLater()
            self.action = None

        return True

    def cleanup(self) -> None:
        '''Called when plugin is unloaded'''
        self.log("Plugin cleaning up", "info")
        # Release resources

    def show_hello(self):
        '''Show hello message'''
        QMessageBox.information(
            self.application.window,
            "Hello Plugin",
            "Hello from the plugin system!",
        )

    def on_settings_changed(self, settings: dict):
        '''Handle settings changes'''
        greeting = settings.get("greeting", "Hello")
        self.log(f"Greeting changed to: {greeting}", "info")


# Use in application
from qtframework.plugins.manager import PluginManager

plugin_manager = PluginManager()
hello_plugin = HelloPlugin()

# Load and activate plugin
plugin_manager.register_plugin(hello_plugin)
plugin_manager.load_plugin("com.example.hello")
plugin_manager.activate_plugin("com.example.hello")

See also

PluginManager: Manages plugin loading and lifecycle PluginMetadata: Plugin metadata and configuration PluginState: Plugin state enumeration

class qtframework.plugins.base.Plugin(metadata)[source]

Bases: QObject

Abstract base class for plugins.

activate()[source]

Activate the plugin.

Called when the plugin is enabled. Use for connecting signals, starting services, or adding UI elements.

Returns:

True if activation successful, False if plugin failed to activate

Return type:

bool

property application: Application | None

Get application instance.

cleanup()[source]

Clean up plugin resources.

deactivate()[source]

Deactivate the plugin.

Called when the plugin is disabled. Use for disconnecting signals, stopping services, or removing UI elements. Plugin remains loaded.

Returns:

True if deactivation successful, False if plugin failed to deactivate

Return type:

bool

error_occurred
get_settings()[source]

Get plugin settings.

Returns:

Plugin settings dictionary

Return type:

dict[str, Any]

property id: str

Get plugin ID.

initialize()[source]

Initialize the plugin.

Called once when the plugin is first loaded. Use for one-time setup like loading resources or registering services.

Returns:

True if initialization successful, False if plugin should not be loaded

Return type:

bool

log(message, level='info')[source]

Log a message.

Parameters:
  • message (str) – Log message

  • level (str) – Log level (debug, info, warning, error)

message
property metadata: PluginMetadata

Get plugin metadata.

property name: str

Get plugin name.

on_settings_changed(settings)[source]

Handle settings change.

Parameters:

settings (dict[str, Any]) – New settings

register_hook(hook_name, callback)[source]

Register a hook callback.

Parameters:
  • hook_name (str) – Hook name

  • callback (Callable) – Callback function

set_application(app)[source]

Set application instance.

Parameters:

app (Application) – Application instance

set_settings(settings)[source]

Set plugin settings.

Parameters:

settings (dict[str, Any]) – Settings dictionary

set_state(state)[source]

Set plugin state.

Parameters:

state (PluginState) – New plugin state

property state: PluginState

Get plugin state.

state_changed
staticMetaObject = PySide6.QtCore.QMetaObject("Plugin" inherits "QObject": Methods:   #4 type=Signal, signature=state_changed(QString), parameters=QString   #5 type=Signal, signature=error_occurred(QString), parameters=QString   #6 type=Signal, signature=message(QString,QString), parameters=QString, QString )
trigger_hook(hook_name, *args, **kwargs)[source]

Trigger a hook.

Parameters:
  • hook_name (str) – Hook name

  • *args (Any) – Positional arguments

  • **kwargs (Any) – Keyword arguments

Returns:

List of hook results

Return type:

list[Any]

unregister_hook(hook_name, callback)[source]

Unregister a hook callback.

Parameters:
  • hook_name (str) – Hook name

  • callback (Callable) – Callback function

class qtframework.plugins.base.PluginMetadata(id, name, version, description='', author='', website='', dependencies=None, category='general', icon='', min_framework_version='0.1.0', max_framework_version=None, settings_schema=None)[source]

Bases: object

Plugin metadata information.

author: str = ''
category: str = 'general'
dependencies: list[str] | None = None
description: str = ''
icon: str = ''
id: str
max_framework_version: str | None = None
min_framework_version: str = '0.1.0'
name: str
settings_schema: dict[str, Any] | None = None
version: str
website: str = ''
class qtframework.plugins.base.PluginState(*values)[source]

Bases: Enum

Plugin state enumeration.

ACTIVE = 'active'
DISABLED = 'disabled'
ERROR = 'error'
LOADED = 'loaded'
LOADING = 'loading'
UNLOADED = 'unloaded'

Plugin manager for handling plugin lifecycle.

class qtframework.plugins.manager.PluginManager(application=None)[source]

Bases: QObject

Manager for handling plugins.

activate_plugin(plugin_id)[source]

Activate a plugin.

Parameters:

plugin_id (str) – Plugin ID

Returns:

True if plugin activated successfully

Raises:
  • PluginError – If plugin is not loaded or activation fails

  • RuntimeError – If plugin dependencies are not met

Return type:

bool

add_plugin_path(path)[source]

Add a plugin search path.

Parameters:

path (Path | str) – Path to search for plugins

deactivate_plugin(plugin_id)[source]

Deactivate a plugin.

Parameters:

plugin_id (str) – Plugin ID

Returns:

True if plugin deactivated successfully

Return type:

bool

discover_plugins()[source]

Discover available plugins.

Returns:

List of discovered plugin metadata

Return type:

list[PluginMetadata]

get_active_plugins()[source]

Get all active plugins.

Returns:

List of active plugins

Return type:

list[Plugin]

get_all_plugins()[source]

Get all loaded plugins.

Returns:

Dictionary of plugins

Return type:

dict[str, Plugin]

get_plugin(plugin_id)[source]

Get a plugin by ID.

Parameters:

plugin_id (str) – Plugin ID

Returns:

Plugin instance or None

Return type:

Plugin | None

load_plugin(plugin_id, plugin_path=None)[source]

Load a plugin with security validation.

Parameters:
  • plugin_id (str) – Plugin ID

  • plugin_path (Path | None) – Optional specific plugin path

Returns:

True if plugin loaded successfully

Raises:
Return type:

bool

plugin_activated
plugin_deactivated
plugin_error
plugin_loaded
register_global_hook(hook_name, plugin_id, callback)[source]

Register a global hook.

Parameters:
  • hook_name (str) – Hook name

  • plugin_id (str) – Plugin ID

  • callback (Callable) – Callback function

staticMetaObject = PySide6.QtCore.QMetaObject("PluginManager" inherits "QObject": Methods:   #4 type=Signal, signature=plugin_loaded(QString), parameters=QString   #5 type=Signal, signature=plugin_activated(QString), parameters=QString   #6 type=Signal, signature=plugin_deactivated(QString), parameters=QString   #7 type=Signal, signature=plugin_error(QString,QString), parameters=QString, QString )
trigger_global_hook(hook_name, *args, **kwargs)[source]

Trigger a global hook.

Parameters:
  • hook_name (str) – Hook name

  • *args (Any) – Positional arguments

  • **kwargs (Any) – Keyword arguments

Returns:

List of hook results

Return type:

list[Any]

unload_plugin(plugin_id)[source]

Unload a plugin.

Parameters:

plugin_id (str) – Plugin ID

Returns:

True if plugin unloaded successfully

Return type:

bool

Configuration (qtframework.config)

Application configuration management with multiple providers.

Configuration storage and access.

class qtframework.config.config.Config(data=None)[source]

Bases: QObject

Configuration container with dot notation access.

clear()[source]

Clear all configuration.

config_reloaded
delete(key)[source]

Delete configuration value.

Parameters:

key (str) – Dot-separated key path

Returns:

True if deleted

Return type:

bool

from_dict(data)[source]

Load configuration from dictionary.

Parameters:

data (dict[str, Any]) – Configuration dictionary

get(key, default=None)[source]

Get configuration value.

Parameters:
  • key (str) – Dot-separated key path

  • default (Any) – Default value if not found

Returns:

Configuration value

Raises:

ValueError – If key is empty or malformed

Return type:

Any

has(key)[source]

Check if configuration key exists.

Parameters:

key (str) – Dot-separated key path

Returns:

True if exists

Return type:

bool

keys(prefix='')[source]

Get all configuration keys.

Parameters:

prefix (str) – Key prefix filter

Returns:

List of keys

Return type:

list[str]

merge(data, deep=True)[source]

Merge configuration data.

Parameters:
  • data (dict[str, Any]) – Data to merge

  • deep (bool) – Perform deep merge

set(key, value)[source]

Set configuration value.

Parameters:
  • key (str) – Dot-separated key path

  • value (Any) – Value to set

staticMetaObject = PySide6.QtCore.QMetaObject("Config" inherits "QObject": Methods:   #4 type=Signal, signature=value_changed(QString,PyObject), parameters=QString, PyObject   #5 type=Signal, signature=config_reloaded() )
to_dict()[source]

Get configuration as dictionary.

Returns:

Configuration dictionary

Return type:

dict[str, Any]

validate(schema)[source]

Validate configuration against schema.

Parameters:

schema (type[BaseModel]) – Pydantic model schema

Returns:

True if valid

Return type:

bool

value_changed
watch(key, callback)[source]

Watch configuration value changes.

Parameters:
  • key (str) – Key to watch

  • callback (Callable[[Any], None]) – Callback function

Returns:

Unwatch function

Return type:

Callable[[], None]

Configuration manager for handling multiple config sources.

class qtframework.config.manager.ConfigManager[source]

Bases: object

Manager for handling configuration from multiple sources.

Orchestrates file loading, validation, and migration through specialized components.

property config: Config

Get configuration object.

get(key, default=None)[source]

Get configuration value.

Parameters:
  • key (str) – Configuration key

  • default (Any) – Default value

Returns:

Configuration value

Return type:

Any

get_all()[source]

Get all configuration values as a dictionary.

Returns:

Dictionary containing all configuration keys and values

Return type:

dict[str, Any]

get_config(*, exclude_defaults=False)[source]

Get configuration data.

get_config_info(app_name, config_filename='config.json')[source]

Get information about config file locations for an application.

Parameters:
  • app_name (str) – Application name

  • config_filename (str) – Config file name (default: config.json)

Returns:

Dictionary with config file information

Return type:

dict[str, Any]

get_config_schema_version()[source]

Get the schema version of the loaded configuration.

Returns:

Schema version from the configuration, or current version if not set

Return type:

str

get_schema_version()[source]

Get the current schema version.

Returns:

Current schema version string

Return type:

str

get_sources()[source]

Get list of configuration sources.

get_supported_versions()[source]

Get list of supported configuration versions.

Returns:

List of version strings that can be migrated

Return type:

list[str]

load_defaults(defaults)[source]

Load default configuration values.

Parameters:

defaults (dict[str, Any]) – Default configuration dictionary

load_env(prefix='')[source]

Load configuration from environment variables.

Parameters:

prefix (str) – Environment variable prefix

load_file(path, format='auto', validate=True)[source]

Load configuration from file.

Parameters:
  • path (Path | str) – File path

  • format (str) – File format (auto, json, yaml, ini, env)

  • validate (bool) – Whether to validate configuration values

Returns:

True if loaded successfully

Raises:

ConfigurationError – If configuration loading or validation fails

Return type:

bool

load_standard_configs(app_name, config_filename='config.json', defaults=None)[source]

Load configuration from standard locations with defaults.

This method implements the standard config loading pattern: 1. Load defaults (lowest priority) 2. Load system config (if exists) 3. Load user config (if exists) 4. Load local config (highest priority) 5. Load environment variables (highest priority)

Parameters:
  • app_name (str) – Application name for directory discovery

  • config_filename (str) – Config file name (default: config.json)

  • defaults (dict[str, Any] | None) – Default configuration values

Returns:

Number of config files loaded

Return type:

int

Example

>>> config_manager = ConfigManager()
>>> defaults = {"theme": "light", "debug": False}
>>> config_manager.load_standard_configs("MyApp", "settings.json", defaults)
3  # Loaded defaults + user config + local config
property migrator: ConfigMigrator

Get the configuration migrator.

register_migration_handler(from_version, migration_func)[source]

Register a custom migration handler for a specific version.

Parameters:
  • from_version (str) – Source version to migrate from

  • migration_func – Function that takes config dict and returns migrated dict

Example

>>> def migrate_1_0_to_1_1(data):
...     data["new_field"] = "default_value"
...     return data
>>> config_manager.register_migration_handler("1.0.0", migrate_1_0_to_1_1)
reload()[source]

Reload all configuration sources.

reset_to_defaults()[source]

Reset configuration to the loaded defaults.

save(path, format='auto')[source]

Save configuration to file.

Parameters:
  • path (Path | str) – File path

  • format (str) – File format

Returns:

True if saved successfully

Return type:

bool

save_user_config(app_name, config_filename='config.json', exclude_defaults=True)[source]

Save current configuration to user config directory.

Parameters:
  • app_name (str) – Application name for directory discovery

  • config_filename (str) – Config file name (default: config.json)

  • exclude_defaults (bool) – Whether to exclude default values from saved config

Returns:

True if saved successfully

Return type:

bool

set(key, value)[source]

Set configuration value.

Parameters:
  • key (str) – Configuration key

  • value (Any) – Value to set

property validator: ConfigValidator

Get the configuration validator.

Configuration providers for different sources.

class qtframework.config.providers.ConfigProvider[source]

Bases: ABC

Abstract configuration provider.

abstractmethod load()[source]

Load configuration data.

abstractmethod save(data)[source]

Save configuration data.

class qtframework.config.providers.EnvProvider(prefix='')[source]

Bases: ConfigProvider

Environment variable configuration provider.

load()[source]

Load from environment.

save(data)[source]

Cannot save to environment.

class qtframework.config.providers.FileProvider(path)[source]

Bases: ConfigProvider

File-based configuration provider.

load()[source]

Load from file.

save(data)[source]

Save to file.

class qtframework.config.providers.JsonProvider(path)[source]

Bases: FileProvider

JSON configuration provider.

load()[source]

Load from JSON.

class qtframework.config.providers.YamlProvider(path)[source]

Bases: FileProvider

YAML configuration provider.

load()[source]

Load from YAML.

Widgets (qtframework.widgets)

Custom widget components and UI elements.

Base widget class.

class qtframework.widgets.base.Widget(parent=None, *, object_name=None, style_class=None)[source]

Bases: QWidget

Enhanced base widget with framework integration.

add_style_class(class_name)[source]

Add a style class.

Parameters:

class_name (str) – Class name to add

get_application()[source]

Get the application instance.

Returns:

Application instance or None

Return type:

Any | None

get_custom_property(name, default=None)[source]

Get a custom property.

Parameters:
  • name (str) – Property name

  • default (Any) – Default value

Returns:

Property value or default

Return type:

Any

has_style_class(class_name)[source]

Check if widget has a style class.

Parameters:

class_name (str) – Class name to check

Returns:

True if class is present

Return type:

bool

remove_style_class(class_name)[source]

Remove a style class.

Parameters:

class_name (str) – Class name to remove

set_custom_property(name, value)[source]

Set a custom property.

Parameters:
  • name (str) – Property name

  • value (Any) – Property value

staticMetaObject = PySide6.QtCore.QMetaObject("Widget" inherits "QWidget": Properties:   #61 "styleClass", QString [writeable] [designable] Methods:   #33 type=Signal, signature=style_changed() )
styleClass = <PySide6.QtCore.Property object>
style_changed
toggle_style_class(class_name)[source]

Toggle a style class.

Parameters:

class_name (str) – Class name to toggle

Button widget components.

class qtframework.widgets.buttons.Button(text='', parent=None, *, variant=ButtonVariant.PRIMARY, size=ButtonSize.MEDIUM, icon=None, object_name=None)[source]

Bases: QPushButton

Enhanced button widget.

buttonSize = <PySide6.QtCore.Property object>
size_changed
staticMetaObject = PySide6.QtCore.QMetaObject("Button" inherits "QPushButton": Properties:   #75 "variant", QString [writeable] [designable]   #76 "buttonSize", QString [writeable] [designable] Methods:   #44 type=Signal, signature=variant_changed(QString), parameters=QString   #45 type=Signal, signature=size_changed(QString), parameters=QString )
variant = <PySide6.QtCore.Property object>
variant_changed
class qtframework.widgets.buttons.ButtonSize(*values)[source]

Bases: Enum

Button size options.

COMPACT: Matches input field height, ideal for buttons next to QLineEdit/QComboBox SMALL: Small standalone button (28px height) MEDIUM: Default button size (36px height) LARGE: Large emphasis button (44px height)

COMPACT = 'compact'
LARGE = 'large'
MEDIUM = 'medium'
SMALL = 'small'
class qtframework.widgets.buttons.ButtonVariant(*values)[source]

Bases: Enum

Button variant styles.

DANGER = 'danger'
INFO = 'info'
OUTLINE = 'outline'
PRIMARY = 'primary'
SECONDARY = 'secondary'
SUCCESS = 'success'
TEXT = 'text'
WARNING = 'warning'
class qtframework.widgets.buttons.CloseButton(parent=None, *, size=20, style='default')[source]

Bases: QPushButton

Standardized close button widget.

staticMetaObject = PySide6.QtCore.QMetaObject("CloseButton" inherits "QPushButton": )
class qtframework.widgets.buttons.IconButton(icon, parent=None, *, size=None, tooltip='', object_name=None)[source]

Bases: QPushButton

Icon-only button widget.

staticMetaObject = PySide6.QtCore.QMetaObject("IconButton" inherits "QPushButton": )
class qtframework.widgets.buttons.ToggleButton(text='', parent=None, *, checked=False, on_text=None, off_text=None, object_name=None)[source]

Bases: QPushButton

Toggle button widget.

setChecked(checked)[source]

Set checked state.

Parameters:

checked (bool) – Checked state

staticMetaObject = PySide6.QtCore.QMetaObject("ToggleButton" inherits "QPushButton": Methods:   #44 type=Signal, signature=toggled_on()   #45 type=Signal, signature=toggled_off() )
toggled_off
toggled_on

Badge widget for displaying status indicators and labels.

class qtframework.widgets.badge.Badge(text='', variant=BadgeVariant.DEFAULT, parent=None)[source]

Bases: QLabel

A badge widget for displaying status indicators, counts, or labels.

Badges are small labels that can be used to show status, counts, or categorization. They are fully theme-aware and get their colors from the current theme’s badge color tokens.

refresh_style()[source]

Refresh the badge style from the current theme.

This should be called when the theme changes.

set_count(count)[source]

Set the badge to display a count.

Parameters:

count (int) – The count to display

set_rounded(rounded=True)[source]

Set whether the badge should be fully rounded (pill-shaped).

Parameters:

rounded (bool) – Whether to make the badge pill-shaped

staticMetaObject = PySide6.QtCore.QMetaObject("Badge" inherits "QLabel": )
property variant: BadgeVariant

Get the current variant.

class qtframework.widgets.badge.BadgeVariant(*values)[source]

Bases: Enum

Badge variant types.

DANGER = 'danger'
DARK = 'dark'
DEFAULT = 'default'
INFO = 'info'
LIGHT = 'light'
PRIMARY = 'primary'
SECONDARY = 'secondary'
SUCCESS = 'success'
WARNING = 'warning'

Input widget components.

class qtframework.widgets.inputs.Input(parent=None, *, placeholder='', value='', read_only=False, max_length=None, object_name=None, validators=None, validate_on_change=True)[source]

Bases: QLineEdit

Enhanced input widget with validation support.

add_validator(validator)[source]

Add a validator to the input.

Parameters:

validator (Validator) – Validator to add

clear_validation_error()[source]

Clear validation error state.

property error_message: str

Get current error message.

Returns:

Error message

property has_validation_error: bool

Get validation error state.

Returns:

Error state

set_icon(icon, position='left')[source]

Set input icon.

Parameters:
  • icon (QIcon) – Icon to display

  • position (str) – Icon position (left or right)

set_validation_error(error, message='')[source]

Set validation error state.

Parameters:
  • error (bool) – Error state

  • message (str) – Error message

set_validators(validators)[source]

Set the validator chain.

Parameters:

validators (ValidatorChain) – New validator chain

staticMetaObject = PySide6.QtCore.QMetaObject("Input" inherits "QLineEdit": Methods:   #49 type=Signal, signature=validation_changed(bool), parameters=bool   #50 type=Signal, signature=validation_error(QString), parameters=QString )
validate(field_name='')[source]

Validate input value.

Parameters:

field_name (str) – Name of the field for error reporting

Returns:

Validation result

Return type:

ValidationResult

validation_changed
validation_error
class qtframework.widgets.inputs.PasswordInput(parent=None, *, placeholder='Enter password', show_toggle=True, object_name=None)[source]

Bases: Input

Password input widget.

staticMetaObject = PySide6.QtCore.QMetaObject("PasswordInput" inherits "Input": Methods:   #51 type=Signal, signature=visibility_changed(bool), parameters=bool )
toggle_visibility()[source]

Toggle password visibility.

visibility_changed
class qtframework.widgets.inputs.SearchInput(parent=None, *, placeholder='Search...', instant_search=True, object_name=None)[source]

Bases: Widget

Search input widget.

clear()[source]

Clear search input.

cleared
search_triggered
setFocus(focus_reason=None)[source]

Set focus to the search input field.

Parameters:

focus_reason (FocusReason | None) – Optional Qt.FocusReason indicating why focus is being set (e.g., TabFocusReason, MouseFocusReason). If None, uses default focus behavior.

setText(text)[source]

Set search text.

Parameters:

text (str) – Text to set

staticMetaObject = PySide6.QtCore.QMetaObject("SearchInput" inherits "Widget": Methods:   #34 type=Signal, signature=search_triggered(QString), parameters=QString   #35 type=Signal, signature=text_changed(QString), parameters=QString   #36 type=Signal, signature=cleared() )
text()[source]

Get search text.

Returns:

Search text

Return type:

str

text_changed
class qtframework.widgets.inputs.TextArea(parent=None, *, placeholder='', value='', read_only=False, max_length=None, object_name=None)[source]

Bases: QTextEdit

Enhanced text area widget.

setPlainText(text)[source]

Set plain text.

Parameters:

text (str) – Text to set

staticMetaObject = PySide6.QtCore.QMetaObject("TextArea" inherits "QTextEdit": )

Advanced Widgets

Advanced table widgets with filtering, sorting, and search capabilities.

class qtframework.widgets.advanced.tables.DataTable(rows=0, columns=0, headers=None, parent=None)[source]

Bases: QWidget

Enhanced data table widget with filtering and sorting.

add_row(data=None)[source]

Add a row to the table.

Parameters:

data (list[Any] | None) – Row data

cell_edited
clear_selection()[source]

Clear current selection.

enable_sorting(enable=True)[source]

Enable column sorting.

Parameters:

enable (bool) – Enable sorting

get_data()[source]

Get table data.

Returns:

2D list of data

Return type:

list[list[str]]

get_selected_rows()[source]

Get list of selected row indices.

remove_selected_rows()[source]

Remove selected rows.

row_double_clicked
row_selected
select_row(row)[source]

Select a specific row.

set_column_width(column, width)[source]

Set column width.

set_data(data)[source]

Set table data.

Parameters:

data (list[list[Any]]) – 2D list of data

set_headers(headers)[source]

Set table headers.

set_row_color(row, color)[source]

Set background color for a row.

staticMetaObject = PySide6.QtCore.QMetaObject("DataTable" inherits "QWidget": Methods:   #33 type=Signal, signature=row_selected(int), parameters=int   #34 type=Signal, signature=cell_edited(int,int,QString), parameters=int, int, QString   #35 type=Signal, signature=row_double_clicked(int), parameters=int )
class qtframework.widgets.advanced.tables.PivotTable(parent=None)[source]

Bases: QWidget

Pivot table widget for data aggregation.

set_data(data)[source]

Set source data for pivot table.

staticMetaObject = PySide6.QtCore.QMetaObject("PivotTable" inherits "QWidget": )
class qtframework.widgets.advanced.tables.TreeTable(headers=None, parent=None)[source]

Bases: QWidget

Enhanced tree table widget with search and expandable rows.

add_item(parent_item, values, data=None)[source]

Add item to tree.

Parameters:
  • parent_item (QTreeWidgetItem | None) – Parent item (None for root)

  • values (list[str]) – Column values

  • data (Any) – Item data

Returns:

Created tree item

Return type:

QTreeWidgetItem

clear()[source]

Clear all items.

get_item_data(item)[source]

Get data stored in item.

get_selected_item()[source]

Get selected item.

item_double_clicked
item_expanded
item_selected
set_column_width(column, width)[source]

Set column width.

set_headers(headers)[source]

Set tree headers.

set_item_color(item, color)[source]

Set item background color.

set_item_icon(item, column, icon)[source]

Set item icon.

staticMetaObject = PySide6.QtCore.QMetaObject("TreeTable" inherits "QWidget": Methods:   #33 type=Signal, signature=item_selected(QString), parameters=QString   #34 type=Signal, signature=item_expanded(QString), parameters=QString   #35 type=Signal, signature=item_double_clicked(QString), parameters=QString )

Advanced tab widgets for the framework.

class qtframework.widgets.advanced.tabs.BaseTabPage(data=None, parent=None)[source]

Bases: Widget

Base class for tab page widgets.

get_values()[source]

Get all values from the tab controls.

staticMetaObject = PySide6.QtCore.QMetaObject("BaseTabPage" inherits "Widget": Methods:   #34 type=Signal, signature=value_changed(QString,PyObject), parameters=QString, PyObject )
update_data(data)[source]

Update data and refresh controls.

value_changed
class qtframework.widgets.advanced.tabs.TabWidget(parent=None, *, closeable_tabs=False, moveable_tabs=True)[source]

Bases: Widget

Enhanced tab widget with framework integration.

add_tab(widget, title, *, icon=None, closeable=None, data=None)[source]

Add a tab to the widget.

Parameters:
  • widget (QWidget) – The widget to add as a tab

  • title (str) – Tab title

  • icon (Any) – Optional tab icon

  • closeable (bool | None) – Whether this specific tab is closeable (overrides global setting)

  • data (dict[str, Any] | None) – Optional metadata for the tab

Returns:

Index of the added tab

Return type:

int

clear()[source]

Remove all tabs.

count()[source]

Get the number of tabs.

Returns:

Number of tabs

Return type:

int

current_index()[source]

Get the current tab index.

Returns:

Current tab index

Return type:

int

current_widget()[source]

Get the current tab widget.

Returns:

Current tab widget or None

Return type:

QWidget | None

get_tab_data(index)[source]

Get metadata for a tab.

Parameters:

index (int) – Tab index

Returns:

Tab metadata dictionary

Return type:

dict[str, Any]

get_tab_title(index)[source]

Get the title of a tab.

Parameters:

index (int) – Tab index

Returns:

Tab title

Return type:

str

insert_tab(index, widget, title, *, icon=None, data=None)[source]

Insert a tab at the specified index.

Parameters:
  • index (int) – Position to insert the tab

  • widget (QWidget) – The widget to add as a tab

  • title (str) – Tab title

  • icon (Any) – Optional tab icon

  • data (dict[str, Any] | None) – Optional metadata for the tab

Returns:

Index of the inserted tab

Return type:

int

is_tab_enabled(index)[source]

Check if a tab is enabled.

Parameters:

index (int) – Tab index

Returns:

True if tab is enabled

Return type:

bool

remove_tab(index)[source]

Remove tab at the specified index.

Parameters:

index (int) – Index of tab to remove

set_current_index(index)[source]

Set the current tab by index.

Parameters:

index (int) – Tab index to make current

set_tab_data(index, data)[source]

Set metadata for a tab.

Parameters:
  • index (int) – Tab index

  • data (dict[str, Any]) – Metadata dictionary

set_tab_enabled(index, enabled)[source]

Enable or disable a tab.

Parameters:
  • index (int) – Tab index

  • enabled (bool) – Whether the tab should be enabled

set_tab_position(position)[source]

Set the position of tab bar.

Parameters:

position (str) – One of ‘north’, ‘south’, ‘west’, ‘east’

set_tab_title(index, title)[source]

Set the title of a tab.

Parameters:
  • index (int) – Tab index

  • title (str) – New title

staticMetaObject = PySide6.QtCore.QMetaObject("TabWidget" inherits "Widget": Methods:   #34 type=Signal, signature=tab_changed(int), parameters=int   #35 type=Signal, signature=tab_close_requested(int), parameters=int )
tab_changed
tab_close_requested
widget(index)[source]

Get the widget at the specified tab index.

Parameters:

index (int) – Tab index

Returns:

Tab widget or None

Return type:

QWidget | None

Advanced dialog components with i18n support.

class qtframework.widgets.advanced.dialogs.ConfirmDialog(title=None, message=None, parent=None, translation_key_title=None, translation_key_message=None, **kwargs)[source]

Bases: QDialog

Confirmation dialog with i18n support.

staticMetaObject = PySide6.QtCore.QMetaObject("ConfirmDialog" inherits "QDialog": )
class qtframework.widgets.advanced.dialogs.FormDialog(title=None, fields=None, parent=None, translation_key_title=None, field_translation_keys=None)[source]

Bases: QDialog

Form dialog for structured input with i18n support.

get_values()[source]

Get form values.

staticMetaObject = PySide6.QtCore.QMetaObject("FormDialog" inherits "QDialog": )
class qtframework.widgets.advanced.dialogs.InputDialog(title=None, label=None, value='', parent=None, translation_key_title=None, translation_key_label=None)[source]

Bases: QDialog

Input dialog for getting user input with i18n support.

get_value()[source]

Get input value.

staticMetaObject = PySide6.QtCore.QMetaObject("InputDialog" inherits "QDialog": )
class qtframework.widgets.advanced.dialogs.ProgressDialog(title=None, label=None, maximum=100, parent=None, translation_key_title=None, translation_key_label=None)[source]

Bases: QDialog

Progress dialog with progress bar and i18n support.

canceled
set_label(text)[source]

Set label text.

set_value(value)[source]

Set progress value.

staticMetaObject = PySide6.QtCore.QMetaObject("ProgressDialog" inherits "QDialog": Methods:   #41 type=Signal, signature=canceled() )
qtframework.widgets.advanced.dialogs.show_error_dialog(parent=None, title=None, message=None, translation_key_title='dialog.error.title', translation_key_message='dialog.error.generic', **kwargs)[source]

Show an error dialog with i18n support.

Parameters:
  • parent (QWidget | None) – Parent widget

  • title (str | None) – Dialog title (overrides translation)

  • message (str | None) – Error message (overrides translation)

  • translation_key_title (str) – Translation key for title

  • translation_key_message (str) – Translation key for message

  • **kwargs – Variables for translation interpolation

qtframework.widgets.advanced.dialogs.show_info_dialog(parent=None, title=None, message=None, translation_key_title='common.info', translation_key_message=None, **kwargs)[source]

Show an information dialog with i18n support.

qtframework.widgets.advanced.dialogs.show_warning_dialog(parent=None, title=None, message=None, translation_key_title='common.warning', translation_key_message=None, **kwargs)[source]

Show a warning dialog with i18n support.

Notification system widgets.

class qtframework.widgets.advanced.notifications.Notification(title='', message='', notification_type=NotificationType.INFO, duration=5000, closable=True, parent=None)[source]

Bases: QFrame

Notification widget.

animate_in()[source]

Animate notification appearance.

animate_out()[source]

Animate notification disappearance.

clicked
close()[source]

Close notification.

closed
mousePressEvent(event)[source]

Handle mouse press.

Parameters:

event (Any) – Mouse event

show_at(position, offset=(20, 20))[source]

Show notification at specific position.

Parameters:
  • position (NotificationPosition) – Position to show at

  • offset (tuple[int, int]) – Offset from edge (x, y)

staticMetaObject = PySide6.QtCore.QMetaObject("Notification" inherits "QFrame": Methods:   #33 type=Signal, signature=closed()   #34 type=Signal, signature=clicked() )
class qtframework.widgets.advanced.notifications.NotificationManager(parent=None)[source]

Bases: QObject

Manager for handling notifications.

clear_all()[source]

Clear all notifications.

error(title, message, **kwargs)[source]

Show error notification.

info(title, message, **kwargs)[source]

Show info notification.

notify(title='', message='', notification_type=NotificationType.INFO, duration=5000, closable=True, on_click=None)[source]

Show a notification.

Parameters:
  • title (str) – Notification title

  • message (str) – Notification message

  • notification_type (NotificationType) – Type of notification

  • duration (int) – Display duration

  • closable (bool) – Show close button

  • on_click (Callable[[], None] | None) – Click callback

Returns:

Notification widget

Return type:

Notification

set_offset(x, y)[source]

Set notification offset.

Parameters:
  • x (int) – X offset

  • y (int) – Y offset

set_position(position)[source]

Set default notification position.

Parameters:

position (NotificationPosition) – Notification position

staticMetaObject = PySide6.QtCore.QMetaObject("NotificationManager" inherits "QObject": )
success(title, message, **kwargs)[source]

Show success notification.

warning(title, message, **kwargs)[source]

Show warning notification.

class qtframework.widgets.advanced.notifications.NotificationPosition(*values)[source]

Bases: Enum

Notification position.

BOTTOM_CENTER = 'bottom_center'
BOTTOM_LEFT = 'bottom_left'
BOTTOM_RIGHT = 'bottom_right'
TOP_CENTER = 'top_center'
TOP_LEFT = 'top_left'
TOP_RIGHT = 'top_right'
class qtframework.widgets.advanced.notifications.NotificationType(*values)[source]

Bases: Enum

Notification types.

ERROR = 'error'
INFO = 'info'
SUCCESS = 'success'
WARNING = 'warning'

Chart widgets for data visualization.

class qtframework.widgets.advanced.charts.BarChart(parent=None)[source]

Bases: ChartWidget

Bar chart widget with custom painting.

paintEvent(event)[source]

Paint the bar chart.

staticMetaObject = PySide6.QtCore.QMetaObject("BarChart" inherits "ChartWidget": )
class qtframework.widgets.advanced.charts.ChartType(*values)[source]

Bases: Enum

Chart types.

AREA = 'area'
BAR = 'bar'
LINE = 'line'
PIE = 'pie'
SCATTER = 'scatter'
class qtframework.widgets.advanced.charts.ChartWidget(parent=None)[source]

Bases: QWidget

Base chart widget with custom painting.

get_color(index)[source]

Get color for index based on current theme.

get_data_colors()[source]

Get data series colors from the current theme.

get_theme_colors()[source]

Get colors from the current theme.

set_colors(colors)[source]

Set custom colors.

set_data(data, labels=None)[source]

Set chart data.

set_show_grid(show)[source]

Toggle grid display.

set_show_legend(show)[source]

Toggle legend display.

set_title(title)[source]

Set chart title.

staticMetaObject = PySide6.QtCore.QMetaObject("ChartWidget" inherits "QWidget": )
class qtframework.widgets.advanced.charts.LineChart(parent=None)[source]

Bases: ChartWidget

Line chart widget with custom painting.

paintEvent(event)[source]

Paint the line chart.

staticMetaObject = PySide6.QtCore.QMetaObject("LineChart" inherits "ChartWidget": )
class qtframework.widgets.advanced.charts.PieChart(parent=None)[source]

Bases: ChartWidget

Pie chart widget with custom painting.

paintEvent(event)[source]

Paint the pie chart.

staticMetaObject = PySide6.QtCore.QMetaObject("PieChart" inherits "ChartWidget": )
class qtframework.widgets.advanced.charts.ScatterChart(parent=None)[source]

Bases: ChartWidget

Scatter chart widget with custom painting.

paintEvent(event)[source]

Paint the scatter chart.

set_points(points)[source]

Set scatter plot points.

staticMetaObject = PySide6.QtCore.QMetaObject("ScatterChart" inherits "ChartWidget": )

Layouts (qtframework.layouts)

Specialized layout managers for common UI patterns.

Base layout implementations.

class qtframework.layouts.base.Alignment(*values)[source]

Bases: Enum

Layout alignment.

CENTER = 'center'
END = 'end'
SPACE_AROUND = 'space_around'
SPACE_BETWEEN = 'space_between'
SPACE_EVENLY = 'space_evenly'
START = 'start'
STRETCH = 'stretch'
class qtframework.layouts.base.Direction(*values)[source]

Bases: Enum

Layout direction.

HORIZONTAL = 'horizontal'
VERTICAL = 'vertical'
class qtframework.layouts.base.FlexLayout(direction=Direction.HORIZONTAL, *, spacing=8, margins=8, alignment=Alignment.START, parent=None)[source]

Bases: QBoxLayout

Flexible box layout.

add_spacing(size)[source]

Add spacing to layout.

Parameters:

size (int) – Spacing size

add_stretch(stretch=0)[source]

Add stretch to layout.

Parameters:

stretch (int) – Stretch factor

add_widget(widget, stretch=0, alignment=None)[source]

Add widget to layout.

Parameters:
  • widget (QWidget) – Widget to add

  • stretch (int) – Stretch factor

  • alignment (Qt.AlignmentFlag | None) – Widget alignment

staticMetaObject = PySide6.QtCore.QMetaObject("FlexLayout" inherits "QBoxLayout": )
class qtframework.layouts.base.GridLayout(*, spacing=8, margins=8, column_stretch=None, row_stretch=None, parent=None)[source]

Bases: QGridLayout

Enhanced grid layout.

add_widget(widget, row, column, row_span=1, column_span=1, alignment=None)[source]

Add widget to grid.

Parameters:
  • widget (QWidget) – Widget to add

  • row (int) – Row position

  • column (int) – Column position

  • row_span (int) – Number of rows to span

  • column_span (int) – Number of columns to span

  • alignment (Qt.AlignmentFlag | None) – Widget alignment

set_column_minimum_width(column, width)[source]

Set column minimum width.

Parameters:
  • column (int) – Column index

  • width (int) – Minimum width

set_column_stretch(column, stretch)[source]

Set column stretch factor.

Parameters:
  • column (int) – Column index

  • stretch (int) – Stretch factor

set_row_minimum_height(row, height)[source]

Set row minimum height.

Parameters:
  • row (int) – Row index

  • height (int) – Minimum height

set_row_stretch(row, stretch)[source]

Set row stretch factor.

Parameters:
  • row (int) – Row index

  • stretch (int) – Stretch factor

staticMetaObject = PySide6.QtCore.QMetaObject("GridLayout" inherits "QGridLayout": )

Sidebar layout implementation.

This module provides a collapsible sidebar layout with support for left/right positioning, resizing, and smooth animations.

Layout Structure:

The sidebar layout creates a two-panel interface:

Left Sidebar:
┌──────────┬─────────────────────────┐
│          │                         │
│ Sidebar  │   Main Content Area     │
│  Panel   │                         │
│          │   [Toggle Button]       │
│          │                         │
└──────────┴─────────────────────────┘

Right Sidebar:
┌─────────────────────────┬──────────┐
│                         │          │
│   Main Content Area     │ Sidebar  │
│                         │  Panel   │
│   [Toggle Button]       │          │
│                         │          │
└─────────────────────────┴──────────┘

Collapsed State (Left):
┌─┬────────────────────────────────┐
│ │                                │
│ │    Main Content Area           │
│ │                                │
│ │    [Toggle Button]             │
│ │                                │
└─┴────────────────────────────────┘

Example

Create a sidebar layout with navigation:

from qtframework.layouts.sidebar import SidebarLayout, SidebarPosition
from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton

# Create sidebar layout
sidebar_layout = SidebarLayout(
    sidebar_width=250,
    position=SidebarPosition.LEFT,
    collapsible=True,
    resizable=True,
)

# Create sidebar content (navigation)
nav_panel = QWidget()
nav_layout = QVBoxLayout(nav_panel)
nav_layout.addWidget(QLabel("Navigation"))
nav_layout.addWidget(QPushButton("Home"))
nav_layout.addWidget(QPushButton("Settings"))
nav_layout.addWidget(QPushButton("Profile"))

# Create main content
content_panel = QWidget()
content_layout = QVBoxLayout(content_panel)
content_layout.addWidget(QLabel("Main Content Area"))

# Set widgets
sidebar_layout.set_sidebar_widget(nav_panel)
sidebar_layout.set_content_widget(content_panel)

# Listen for sidebar toggle
sidebar_layout.sidebar_toggled.connect(
    lambda visible: print(f"Sidebar visible: {visible}")
)

# Programmatically toggle
sidebar_layout.toggle_sidebar()  # Collapse/expand

See also

FlowLayout: Flow layout for wrapping widgets qtframework.layouts: Other layout components

class qtframework.layouts.sidebar.SidebarLayout(parent=None, *, sidebar_width=250, position=SidebarPosition.LEFT, collapsible=True, resizable=True)[source]

Bases: QWidget

Layout with collapsible sidebar.

is_collapsed()[source]

Check if sidebar is collapsed.

Returns:

True if collapsed

Return type:

bool

set_content_widget(widget)[source]

Set content widget.

Parameters:

widget (QWidget) – Widget to set in content area

set_sidebar_widget(widget)[source]

Set sidebar widget.

Parameters:

widget (QWidget) – Widget to set in sidebar

set_sidebar_width(width)[source]

Set sidebar width.

Parameters:

width (int) – Width in pixels

sidebar_toggled
staticMetaObject = PySide6.QtCore.QMetaObject("SidebarLayout" inherits "QWidget": Methods:   #33 type=Signal, signature=sidebar_toggled(bool), parameters=bool )
toggle_sidebar()[source]

Toggle sidebar visibility.

class qtframework.layouts.sidebar.SidebarPosition(*values)[source]

Bases: Enum

Sidebar position.

LEFT = 'left'
RIGHT = 'right'

Card layout components.

class qtframework.layouts.card.Card(parent=None, *, title='', elevated=True, padding=16, object_name=None)[source]

Bases: QFrame

Card container widget.

add_stretch(stretch=1)[source]

Add stretch to card.

Parameters:

stretch (int) – Stretch factor

add_widget(widget, stretch=0)[source]

Add widget to card.

Parameters:
  • widget (QWidget) – Widget to add

  • stretch (int) – Stretch factor

set_content_margins(left, top, right, bottom)[source]

Set content margins.

Parameters:
  • left (int) – Left margin

  • top (int) – Top margin

  • right (int) – Right margin

  • bottom (int) – Bottom margin

set_spacing(spacing)[source]

Set content spacing.

Parameters:

spacing (int) – Spacing between widgets

set_title(title)[source]

Set card title.

Parameters:

title (str) – Title text

staticMetaObject = PySide6.QtCore.QMetaObject("Card" inherits "QFrame": )
class qtframework.layouts.card.CardLayout(parent=None, *, columns=3, spacing=16, responsive=True)[source]

Bases: QWidget

Layout for arranging cards.

add_card(card=None, *, title='', content=None)[source]

Add a card to the layout.

Parameters:
  • card (Card | None) – Existing card or None to create new

  • title (str) – Card title (if creating new)

  • content (QWidget | None) – Card content (if creating new)

Returns:

Added card

Return type:

Card

clear_cards()[source]

Remove all cards.

remove_card(card)[source]

Remove a card from the layout.

Parameters:

card (Card) – Card to remove

resizeEvent(event)[source]

Handle resize event.

Parameters:

event (Any) – Resize event

staticMetaObject = PySide6.QtCore.QMetaObject("CardLayout" inherits "QWidget": )

Flow layout that automatically wraps widgets based on available width.

This module provides a flow layout that arranges widgets in a flowing manner, similar to how text wraps in a word processor. Widgets automatically wrap to the next line when they exceed the available width.

Layout Structure:

Widgets flow left to right and wrap when necessary:

Available Width
┌─────────────────────────────────┐
│ ┌────┐ ┌────┐ ┌────┐ ┌────┐    │
│ │ W1 │ │ W2 │ │ W3 │ │ W4 │    │
│ └────┘ └────┘ └────┘ └────┘    │
│ ┌────┐ ┌────┐ ┌────┐           │
│ │ W5 │ │ W6 │ │ W7 │           │
│ └────┘ └────┘ └────┘           │
│ ┌────┐                          │
│ │ W8 │                          │
│ └────┘                          │
└─────────────────────────────────┘

When Width Decreases:
┌───────────────┐
│ ┌────┐ ┌────┐│
│ │ W1 │ │ W2 ││
│ └────┘ └────┘│
│ ┌────┐ ┌────┐│
│ │ W3 │ │ W4 ││
│ └────┘ └────┘│
│ ┌────┐ ┌────┐│
│ │ W5 │ │ W6 ││
│ └────┘ └────┘│
└───────────────┘

Example

Create a flow layout with tags or chips:

from qtframework.layouts.flow import FlowLayout
from qtframework.widgets import Badge
from PySide6.QtWidgets import QWidget

# Create container with flow layout
container = QWidget()
flow_layout = FlowLayout(parent=container, margin=10, h_spacing=8, v_spacing=8)

# Add tags/chips that will wrap automatically
tags = [
    "Python",
    "JavaScript",
    "React",
    "Qt",
    "Django",
    "FastAPI",
    "PostgreSQL",
    "Redis",
    "Docker",
]

for tag in tags:
    badge = Badge(text=tag, variant="primary")
    flow_layout.addWidget(badge)

# Layout automatically reflows on window resize

Use with button groups:

from qtframework.widgets import Button

# Create action buttons that wrap on small screens
actions = ["Save", "Cancel", "Delete", "Export", "Print"]

for action in actions:
    button = Button(text=action)
    flow_layout.addWidget(button)

Custom spacing based on widget properties:

# Create layout with tight spacing
tight_flow = FlowLayout(h_spacing=4, v_spacing=4)

# Create layout with generous spacing
loose_flow = FlowLayout(h_spacing=16, v_spacing=16)
Key Features:
  • Automatic Wrapping: Widgets wrap to next line when width exceeded

  • Dynamic Reflow: Automatically adjusts on window resize

  • Custom Spacing: Configure horizontal and vertical spacing

  • Height for Width: Properly calculates height based on width

  • Smart Spacing: Uses platform-appropriate spacing when not specified

See also

SidebarLayout: Sidebar layout with collapsible panel qtframework.widgets.Badge: Badge widget often used with flow layout

class qtframework.layouts.flow.FlowLayout(parent=None, margin=-1, h_spacing=-1, v_spacing=-1)[source]

Bases: QLayout

A layout that arranges widgets in a flowing manner, wrapping to new lines as needed.

addItem(item)[source]

Add an item to the layout.

count()[source]

Return the number of items in the layout.

expandingDirections()[source]

Return the expanding directions.

hasHeightForWidth()[source]

Return whether the layout has height for width.

heightForWidth(width)[source]

Calculate the height needed for a given width.

horizontalSpacing()[source]

Get horizontal spacing between widgets.

invalidate()[source]

Invalidate the layout to force recalculation.

Triggers immediate re-layout if geometry is already valid to ensure proper widget positioning after invalidation.

itemAt(index)[source]

Return the item at the given index.

minimumSize()[source]

Calculate the minimum size of the layout.

setGeometry(rect)[source]

Set the geometry of the layout.

sizeHint()[source]

Return the preferred size of the layout.

staticMetaObject = PySide6.QtCore.QMetaObject("FlowLayout" inherits "QLayout": )
takeAt(index)[source]

Remove and return the item at the given index.

verticalSpacing()[source]

Get vertical spacing between widgets.

Utilities (qtframework.utils)

Helper functions and utility classes.

Logging utilities with color support and enhanced configuration.

class qtframework.utils.logger.LogFormatter(fmt=None, use_color=True)[source]

Bases: Formatter

Custom formatter with color support for console output.

COLORS: ClassVar[dict[str, str]] = {'CRITICAL': '\x1b[35m', 'DEBUG': '\x1b[36m', 'ERROR': '\x1b[31m', 'INFO': '\x1b[32m', 'RESET': '\x1b[0m', 'WARNING': '\x1b[33m'}
format(record)[source]

Format log record with optional color.

Parameters:

record (LogRecord) – Log record to format

Returns:

Formatted log string

Return type:

str

qtframework.utils.logger.get_logger(name)[source]

Get a logger instance.

Parameters:

name (str) – Logger name (typically __name__)

Returns:

Logger instance

Return type:

Logger

qtframework.utils.logger.setup_logging(log_file=None, console_level=20, file_level=10, log_format=None)[source]

Setup logging configuration.

Parameters:
  • log_file (Path | str | None) – Optional path to log file. If None, only console logging is enabled

  • console_level (int) – Logging level for console output (default: INFO)

  • file_level (int) – Logging level for file output (default: DEBUG)

  • log_format (str | None) – Custom log format string

Input validation framework for Qt Framework.

This module provides a comprehensive validation system with built-in validators for common use cases (email, numbers, paths, etc.) and support for custom validators and multi-field form validation.

Example

Basic validation with built-in validators:

from qtframework.utils.validation import (
    RequiredValidator,
    EmailValidator,
    LengthValidator,
    NumberValidator,
    ValidationError,
)

# Simple field validation
email_validator = EmailValidator()
try:
    email_validator.validate("user@example.com", "email")
    print("Valid email!")
except ValidationError as e:
    print(f"Error: {e.message}")

# Chained validators
from qtframework.utils.validation import ValidatorChain

username_validators = ValidatorChain([
    RequiredValidator("Username is required"),
    LengthValidator(min_length=3, max_length=20),
])

result = username_validators.validate("ab", "username")
if not result.is_valid:
    print(result.get_error_messages())

Complete form validation example:

from qtframework.utils.validation import (
    FormValidator,
    required_string,
    email_field,
    number_field,
)

# Create form validator
form = FormValidator()
form.add_field("username", required_string(min_length=3, max_length=20))
form.add_field("email", email_field())
form.add_field("age", number_field(min_value=18, max_value=120))

# Validate form data
data = {"username": "john_doe", "email": "john@example.com", "age": 25}

result = form.validate(data)
if result.is_valid:
    print("Form is valid!")
else:
    for error in result.errors:
        print(f"{error.field_name}: {error.message}")

Integration with Input widgets:

from qtframework.widgets.inputs import Input
from qtframework.utils.validation import email_field

# Create input with validation
email_input = Input(
    label="Email Address",
    placeholder="Enter your email",
    validators=email_field().validators,
)


# Validate on change
def on_email_change(text):
    result = email_field().validate(text, "email")
    if not result.is_valid:
        email_input.set_error(result.get_error_messages()[0])
    else:
        email_input.clear_error()


email_input.textChanged.connect(on_email_change)

See also

Validator: Base validator class for custom validators FormValidator: Multi-field form validation qtframework.utils.exceptions.ValidationError: Validation error exception qtframework.widgets.inputs: Input widgets with validation support

class qtframework.utils.validation.ChoiceValidator(choices, message=None)[source]

Bases: Validator

Validates that value is one of allowed choices.

validate(value, field_name='')[source]

Validate that value is in choices.

class qtframework.utils.validation.CustomValidator(func, message=None)[source]

Bases: Validator

Validates using a custom function.

validate(value, field_name='')[source]

Validate using custom function.

class qtframework.utils.validation.EmailValidator(message=None)[source]

Bases: RegexValidator

Validates email addresses.

EMAIL_PATTERN = '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'
class qtframework.utils.validation.FormValidator[source]

Bases: object

Validates multiple fields with different validators.

Manages validation for entire forms with multiple fields, each having their own validation rules.

Example

Multi-field form validation:

from qtframework.utils.validation import (
    FormValidator,
    ValidatorChain,
    RequiredValidator,
    EmailValidator,
    LengthValidator,
    NumberValidator,
    CustomValidator,
)

# Create form validator
form = FormValidator()

# Add username validation
form.add_field(
    "username",
    [RequiredValidator(), LengthValidator(min_length=3, max_length=20)],
)

# Add email validation
form.add_field("email", [RequiredValidator(), EmailValidator()])


# Add age validation with custom rule
def check_age(value):
    age = int(value)
    return 18 <= age <= 120


form.add_field(
    "age",
    [
        RequiredValidator(),
        NumberValidator(min_value=18, max_value=120, allow_float=False),
        CustomValidator(check_age, "Age must be between 18 and 120"),
    ],
)

# Add password confirmation validation
form.add_field("password", [RequiredValidator(), LengthValidator(min_length=8)])

# Validate entire form
data = {
    "username": "john_doe",
    "email": "john@example.com",
    "age": 25,
    "password": "securepass123",  # pragma: allowlist secret
}

result = form.validate(data)

if result.is_valid:
    print("All fields valid!")
else:
    # Get all errors
    for error in result.errors:
        print(f"{error.field_name}: {error.message}")

    # Get errors for specific field
    username_errors = result.get_field_error_messages("username")
add_field(field_name, validators)[source]

Add field validation.

Parameters:
validate(data)[source]

Validate all fields.

Parameters:

data (dict[str, Any]) – Dictionary of field values

Returns:

Validation result

Return type:

ValidationResult

class qtframework.utils.validation.LengthValidator(min_length=None, max_length=None, message=None)[source]

Bases: Validator

Validates string length.

validate(value, field_name='')[source]

Validate string length.

class qtframework.utils.validation.NumberValidator(min_value=None, max_value=None, allow_float=True, message=None)[source]

Bases: Validator

Validates numeric values.

validate(value, field_name='')[source]

Validate numeric value.

class qtframework.utils.validation.PathValidator(must_exist=False, must_be_file=False, must_be_dir=False, message=None)[source]

Bases: Validator

Validates file and directory paths.

validate(value, field_name='')[source]

Validate path.

class qtframework.utils.validation.RegexValidator(pattern, message=None)[source]

Bases: Validator

Validates value against a regular expression.

validate(value, field_name='')[source]

Validate value against regex pattern.

class qtframework.utils.validation.RequiredValidator(message=None)[source]

Bases: Validator

Validates that a value is not empty.

validate(value, field_name='')[source]

Validate that value is not empty.

class qtframework.utils.validation.ValidationResult(is_valid=True, errors=None)[source]

Bases: object

Result of validation operation.

add_error(error)[source]

Add validation error.

get_error_messages()[source]

Get all error messages.

get_field_error_messages(field_name)[source]

Get error messages for specific field.

get_field_errors(field_name)[source]

Get errors for specific field.

class qtframework.utils.validation.Validator(message=None)[source]

Bases: ABC

Base class for validators.

abstractmethod validate(value, field_name='')[source]

Validate a value.

Parameters:
  • value (Any) – Value to validate

  • field_name (str) – Name of the field being validated

Returns:

True if valid

Raises:

ValidationError – If validation fails

Return type:

bool

class qtframework.utils.validation.ValidatorChain(validators=None)[source]

Bases: object

Chain of validators for a field.

add_validator(validator)[source]

Add validator to chain.

validate(value, field_name='')[source]

Validate value using all validators in chain.

qtframework.utils.validation.choice_field(choices)[source]

Create validator chain for choice field.

qtframework.utils.validation.email_field()[source]

Create validator chain for email field.

qtframework.utils.validation.number_field(min_value=None, max_value=None)[source]

Create validator chain for number field.

qtframework.utils.validation.optional_email_field()[source]

Create validator chain for optional email field.

qtframework.utils.validation.optional_string(max_length=None)[source]

Create validator chain for optional string.

qtframework.utils.validation.path_field(must_exist=False, must_be_file=False, must_be_dir=False)[source]

Create validator chain for path field.

qtframework.utils.validation.required_string(min_length=1, max_length=None)[source]

Create validator chain for required string.

Cross-platform path utilities for standard directories.

qtframework.utils.paths.ensure_directory(path)[source]

Ensure directory exists, creating it if necessary.

Parameters:

path (Path) – Directory path to ensure

Returns:

True if directory exists or was created successfully

Return type:

bool

qtframework.utils.paths.find_config_files(app_name, config_filename='config.json')[source]

Find all possible config files for an application in standard locations.

Parameters:
  • app_name (str) – Application name

  • config_filename (str) – Config file name (default: config.json)

Returns:

List of config file paths that exist, ordered by priority (system -> user -> local)

Return type:

list[Path]

qtframework.utils.paths.get_preferred_config_path(app_name, config_filename='config.json')[source]

Get the preferred path for saving user config.

Parameters:
  • app_name (str) – Application name

  • config_filename (str) – Config file name (default: config.json)

Returns:

Preferred config file path for saving

Return type:

Path

qtframework.utils.paths.get_system_config_dir(app_name)[source]

Get system-wide config directory for the application.

Parameters:

app_name (str) – Application name (used as subdirectory)

Returns:

Path to system config directory, or None if not applicable

Return type:

Path | None

Examples

Windows: None (no standard system config) macOS: /Library/Application Support/MyApp Linux: /etc/MyApp

qtframework.utils.paths.get_user_cache_dir(app_name)[source]

Get user-specific cache directory for the application.

Parameters:

app_name (str) – Application name (used as subdirectory)

Returns:

Path to user cache directory

Return type:

Path

Examples

Windows: C:/Users/username/AppData/Local/MyApp/Cache macOS: ~/Library/Caches/MyApp Linux: ~/.cache/MyApp

qtframework.utils.paths.get_user_config_dir(app_name)[source]

Get user-specific config directory for the application.

Parameters:

app_name (str) – Application name (used as subdirectory)

Returns:

Path to user config directory

Return type:

Path

Examples

Windows: C:/Users/username/AppData/Local/MyApp macOS: ~/Library/Application Support/MyApp Linux: ~/.config/MyApp

qtframework.utils.paths.get_user_data_dir(app_name)[source]

Get user-specific data directory for the application.

Parameters:

app_name (str) – Application name (used as subdirectory)

Returns:

Path to user data directory

Return type:

Path

Examples

Windows: C:/Users/username/AppData/Local/MyApp macOS: ~/Library/Application Support/MyApp Linux: ~/.local/share/MyApp

Custom exceptions for the Qt Framework.

exception qtframework.utils.exceptions.ConfigurationError(message, config_key=None, config_value=None, source=None)[source]

Bases: QtFrameworkError

Configuration-related errors.

exception qtframework.utils.exceptions.NavigationError(message, route_path=None, from_path=None, to_path=None)[source]

Bases: QtFrameworkError

Navigation and routing errors.

exception qtframework.utils.exceptions.PluginError(message, plugin_id=None, plugin_path=None, operation=None)[source]

Bases: QtFrameworkError

Plugin-related errors.

exception qtframework.utils.exceptions.QtFrameworkError(message, details=None)[source]

Bases: Exception

Base exception for Qt Framework errors.

exception qtframework.utils.exceptions.SecurityError(message, security_context=None, attempted_action=None)[source]

Bases: QtFrameworkError

Security-related errors.

exception qtframework.utils.exceptions.StateError(message, action_type=None, state_path=None)[source]

Bases: QtFrameworkError

State management errors.

exception qtframework.utils.exceptions.ThemeError(message, theme_name=None, theme_path=None)[source]

Bases: QtFrameworkError

Theme-related errors.

exception qtframework.utils.exceptions.ValidationError(message, field_name=None, field_value=None, validation_rule=None)[source]

Bases: QtFrameworkError

Input validation errors.