Advanced docking system for PySide6 β a feature-rich, themeable widget layout framework for building professional Qt desktop applications in Python.
Version: 0.4.0
- Multi-area docking β Dock widgets to left, right, top, bottom, or center regions within a window
- Tabbed dock areas β Multiple widgets share a single dock area as tabs, with full tab management (reorder, close, float)
- Floating windows β Detach any dock widget into its own top-level window; drag it back to dock
- Drag-and-drop layout β Intuitive resize, re-order, and re-dock via visual drop indicators
- Nested splitters β Arbitrary nesting of horizontal and vertical split panes
- Maximize/restore β Expand any dock area to fill its container
- Auto-hide panels β VS Code-style slide-out sidebars that appear on hover
- Pinned widgets β Pin dock widgets to sidebars with visual tab buttons
- Notification badges β Numerical or symbolic badges on sidebar tabs
- Configurable focus behavior β Choose whether sidebars steal keyboard focus
- Drag to detach β Tear pinned widgets out of sidebars back into the main layout
- 14 built-in themes β Dark, light, midnight, warm, nordic, monokai, neutral, tokyo_night, catppuccin, dracula, solarized_dark/light, and cyberpunk_neon
- Declarative
ThemeSpecβ Define custom themes with color palettes and geometrical tokens (corner radius, border width, title height, tab radius, content margin, etc.) - JSON theme files β Ship themes as JSON (Pydantic-validated via
ThemeJson/load_theme_json); colors as[r,g,b,a]lists or"#rrggbb"strings - Reactive borders β Active dock area shows a vibrant focus border; inactive areas show a subtle neutral border
- OS auto-sync β Automatically switch between light/dark themes when the OS changes (
ThemeManager.sync_theme(force, path)) - Custom QSS/stylesheet support β Point themes to external
.qssor.cssfiles, or a directory of<name>.json|.qss|.cssfiles viadefault_theme_path
- 16 global flags β Control tab visibility, button visibility, drag behavior, floating window chrome, icon styling, and more
- Per-widget feature flags β Granular control over what each dock widget can do: closable, movable, floatable, pinnable
- Insertion order β Sort "Show View" menu items alphabetically or chronologically
- Toggle view actions β Integrate dock widget show/hide into menu bars or toolbars as checkable toggles or one-way show buttons
- JSON layout serialization β Save and restore complete window layouts to/from JSON files
- Perspectives β Save named layout presets (e.g., "Coding Mode", "Presentation Mode") and switch between them instantly
- Atomic file I/O β Layouts are written atomically (temp file + rename) to prevent corruption
- SVG-based icon system β Theme-aware SVG icons with automatic color tinting
- Custom icon provider β Register a directory of SVG icons for use across tabs and menus
- Painted chrome β Custom-drawn title bars, tab buttons, splitter handles, and drop indicators with rounded corners and hover states
- Frameless windows β Custom (PySideSix-Frameless-Window) title bars for the main window and floating containers with a synchronous double-click-to-maximize, DWM shadow, and resize borders
- Configurable custom title bars β Set different title-bar classes for the main window and floating dock containers (
title_bar=constructor arg,DockManager.main_title_bar/floating_title_bar); embed menus, search fields, or any widget directly in the frameless chrome - Chromeless floating windows β Optional bare floating surfaces without any title bar
pip install pyside6
# Clone Lace
git clone https://github.com/yourusername/lace.git
cd laceimport sys
from PySide6.QtWidgets import QApplication, QMainWindow, QTextEdit
from lace import DockManager, DockWidget, DockWidgetArea, apply_dock_theme
app = QApplication(sys.argv)
app.setStyle("Fusion")
window = QMainWindow()
window.setWindowTitle("My App")
window.resize(1200, 800)
# Create the dock manager
dock_manager = DockManager(window)
window.setCentralWidget(dock_manager._root)
# Apply a theme
apply_dock_theme("cyberpunk_neon")
# Add a dock widget
editor = DockWidget("Editor", window)
editor.set_widget(QTextEdit())
editor.set_features(DockWidgetFeature.all_features)
dock_manager.add_dock_widget(DockWidgetArea.center, editor)
window.show()
app.exec()Run the demo application to explore all features:
python demo_app.pyThe demo includes:
- Multiple dock widgets with different feature flags (closable, movable, floatable, pinnable)
- Sidebar setup with notification badges
- Theme switching menu with 14 built-in themes
- Global flags menu for live configuration toggling
For frameless/custom-title-bar examples, see:
python demo_app_custom_titlebar.py # standard custom title bar
python demo_app_custom_titlebar_menus.py # menu-embedded main title bar + search bar for floatsThe second demo shows configurable custom title bars: the main window
uses a title bar with a QMenuBar embedded directly in the frameless chrome
(no separate menu bar below it), while every floating dock container gets a
different title bar with a centered, resizable search QLineEdit.
Custom title bars are configured with a title-bar descriptor β None (the
standard Lace title bar), a QWidget instance, a QWidget subclass, or a
callable factory. Pass one to the window constructor or to the dock manager:
from lace import DockManager, TitleBarMode
from lace.frameless_window import FramelessLaceMainWindow
class MainWindow(FramelessLaceMainWindow):
def __init__(self):
# Custom title bar for the main window (class or instance).
super().__init__(title_bar=MenuEmbeddedTitleBar)
self.dock_manager = DockManager(self)
self.dock_manager.title_bar_mode = TitleBarMode.custom
# Different title bar for every floating dock container.
self.dock_manager.floating_title_bar = SearchTitleBarDockManager.main_title_bar configures the main window, and
DockManager.floating_title_bar configures new floating containers created
when dock widgets are torn off. See Quick Reference β Frameless Windows
& the Custom Title Bar
for the full API.
- Insertion order control
- Sidebar focus mode and badge position controls
- Preset configurations (Default, Minimal, Full)
The frameless main window (custom title bar, dock panels, splitters) across 12 built-in themes.
Full-size captures (main window + frameless floating containers) are in the
screenshots/ folder.
Lace is built around a clean, modular architecture:
DockManager (facade)
βββ DockContainerWidget (root + floating windows)
β βββ DockSplitter (nested, orientation-aware)
β βββ DockAreaWidget (tabbed regions)
β βββ DockAreaTitleBar
β β βββ DockAreaTabBar β DockWidgetTab (ΓN)
β βββ DockWidget β user content (QTextEdit, QWidget, etc.)
βββ SidebarManager (auto-hide panels)
β βββ SideTabBar β VerticalTabButton (ΓN)
β βββ SideBarContainer (overlay panel)
βββ LayoutSerializer (JSON persistence)
βββ DockStyleManager (theme engine)
βββ DockThemeBridge (QPalette β Qt children)
βββ ThemeManager (OS-aware auto light/dark)
See the Architecture Documentation for a complete module-by-module reference with class hierarchies, signals, and method tables.
| Document | Description |
|---|---|
| Quick Reference | 5-minute guide β installation, common patterns, API lookup |
| Architecture | Complete system architecture β all modules, classes, signals, and data flow |
| Theming & Geometry | ThemeSpec tokens, titlebar flushness, reactive borders, content margin |
| Enum Mapping | Comprehensive mapping of all enumerations and flags with wiring status |
lace/
βββ lace/ # Main package
β βββ dock_manager.py # Central orchestrator (facade)
β βββ dock_widget.py # User-facing dock widget wrapper
β βββ dock_widget_tab.py # Painted-chrome tab button
β βββ dock_container_widget.py # Root + floating container
β βββ dock_area_widget.py # Single tabbed region
β βββ dock_splitter.py # Nested splitters + resize handles
β βββ floating_dock_container.py # Top-level floating window
β βββ floating_dock_container_frameless.py # Frameless floating window
β βββ frameless_window.py # Frameless main/window + LaceStandardTitleBar
β βββ frameless_titlebar.py # Dock-theme styling for the custom title bar
β βββ dock_overlay.py # Drop-target visual overlays
β βββ dock_chrome.py # Drag detector, chrome buttons, frames
β βββ dock_paint.py # Painting primitives
β βββ dock_theme.py # Theme schemas, ThemeSpec, color math
β βββ dock_custom_theme.py # 14 built-in theme presets
β βββ theme_models.py # ThemeJson β Pydantic JSON theme loading
β βββ dock_style_manager.py # Singleton style manager (subscriber model)
β βββ dock_theme_bridge.py # QPalette push to Qt children
β βββ theme_manager.py # OS-aware auto dark/light switching
β βββ layout_serializer.py # JSON save/restore, perspectives
β βββ dock_container_state.py # Low-level tree state save/restore
β βββ dock_signals.py # Internal event bus
β βββ dock_menu.py # Unified context menu system
β βββ dock_styled.py # DockStyled mixin (auto-style registration)
β βββ dock_icon_provider.py # SVG icon provider with tinting
β βββ sidebar_manager.py # Auto-hide sidebar controller
β βββ sidebar_tab.py # Vertical tab button
β βββ sidebar_tab_bar.py # Vertical tab strip
β βββ sidebar_container.py # Animated overlay panel
β βββ sidebar_title_bar.py # Title bar inside overlay panel
β βββ sidebar_state.py # Sidebar state compatibility shim
β βββ eliding_label.py # QLabel with text elision
β βββ enums.py # All enumerations and flags
β βββ util.py # Utility functions
β βββ _trace.py # Optional debug tracing
βββ demo_app.py # Full-featured demo application
βββ dev_smoke/ # Smoke tests for individual features
βββ tests/ # pytest suite (theme engine, JSON themes, style manager, enums, paint, layout errors, circular-import detector)
βββ docs/ # Documentation
βββ lace/resources/lace_icons/ # SVG icons (close, dock, float, pin, etc.)
βββ LICENSE # Apache-2.0
βββ README.md # This file
Two complementary test layers:
-
tests/(pytest) β fast logic/contract tests for the theme engine,ThemeJsonloading,DockStyleManager, enums/config masks, paint primitives, layout-serializer errors, and an AST-based circular-import detector that fails if a real module-level import cycle is introduced.pytest tests/
-
dev_smoke/(offscreen Qt) β each check builds its ownQApplicationand drives real widgets offscreen (theme switching, sidebar chrome, save/restore round-trips, dock flags, JSON theme application):python dev_smoke/run_all.py
Contributions are welcome! Please:
- Open an issue to discuss significant changes before starting work
- Follow the existing code style and naming conventions
- Add smoke tests in
dev_smoke/for new features - Update documentation (
docs/) for user-facing changes
Lace is licensed under the Apache License 2.0. See LICENSE for details.
This project incorporates components from qtpydocking under the BSD 3-Clause License. See LICENSE for full attribution.
Author: opticsWolf
Contact: opticswolf@protonmail.com
