Also have a Tiếng Việt version of this README: README.vi.md
This base Qt application is not just a code scaffold but a mindset for software development: clear separation of responsibilities, leveraging the Observer Pattern, and automating workflows, so you can focus on creativity. Every line of code here is designed to encourage flexibility, reusability, and long-term scalability.
-
- Controller & Handler: Separate UI and events
- Service: Pure logic, UI-agnostic
- Component & Widget Manager: Reusable, stateful
- Task System & Middleware: Automated, non-blocking UI
There are other components also documented. See in Docs.
- Separation of Concerns: Each module has a single responsibility—UI displays, Service handles logic, Handler responds to events. This keeps code maintainable and scalable.
- Automation First: The Task System and CLI scaffolding accelerate development, reduce manual errors, and let you focus on core algorithms.
- Observer Pattern: Reduces coupling between classes; components communicate via events, ensuring extensibility and flexible changes.
- Modularity & Reusability: Everything is a plugin or small component—easy to replace, test, and reuse across projects.
Get your app skeleton ready with the right mindset:
-
Use template:
gh repo create my-app --template=https://github.com/ultra-bugs/pyside-base
-
Clone & Install
git clone <your-new-repo-url> my-app cd my-app pip install -r requirements.txt
-
Set Basic Info
python scripts/set_app_info.py --name "My App" --version "1.0.0"
-
Generate Main Controller & UI
python scripts/generate.py controller YourController python scripts/compile_ui.py
Mindset: Automate setup, save time, and ensure every project starts with a consistent structure.
base/
├── core/ # Framework & template patterns
├── windows/ # Views, controllers and event handlers
│ ├── components/ # Reusable UI components (widgets)
│ └── main/ # Main window
├── services/ # Independent business logic
├── models/ # Reusable UI components
├── scripts/ # CLI tools & scaffolding
├── assets/ # Resources (images, sounds, translations)
│ └── icon.png # Default application icon
├── data/ # User data and embedded app data
│ ├── config/ # Configuration files
│ └── logs/ # Log files
├── vendor/ # Third-party resources
└── plugins/ # App plugins
Mindset: Each folder is an independent module, easy to test, develop in parallel, and swap without affecting the system.
- Controller wires up UI to events using a
slot_map
, without embedding business logic. - Handler (Subscriber) listens for events, processes them, and responds, completely decoupled from UI concerns.
# in controller
class MyController(BaseController):
# Mapping show: when `pushButton` has been `clicked`. The method named `on_open_btn_click` on handler will be called
slot_map = {
'open_btn_click': ['pushButton', 'clicked']
}
# in handler
class MyControllerHandler(Subscriber):
def on_open_btn_click(self, data = None):
# Event handling logic
pass
Mindset: Keep business logic out of UI events—Controllers merely proxy events.
- Receives input, processes it, returns results—has no knowledge of the UI.
- Fully unit-testable and reusable.
class MyService:
def fetch_data(self) -> List[Dict]:
# Data processing logic
return []
Mindset: Treat each service as a microservice within the repo—independent and maintainable.
- WidgetManager provides dot-notation access, suppresses signals during updates, and auto-saves configuration.
widget_manager.set('slider.value', 50, save_to_config=True)
Mindset: Each component has a clear responsibility; state is managed centrally to avoid side effects.
- Supports multi-threading, scheduling, and chainable middleware.
- Breaks workflows into
TaskStep
s for easy monitoring, retries, logging, and captcha handling.
task = task_manager.create_task("SyncData")
task.add_step(FetchStep())
task.add_step(ProcessStep())
task_manager.run_task(task)
Mindset: Offload heavy tasks to the background; keep the UI responsive.
Quickly scaffold Controllers, Services, Components, Tasks, and Steps with a single command:
python scripts/generate.py controller MyController
python scripts/generate.py service MyService
Mindset: Enforce naming and structure conventions, reduce boilerplate time.
For full list scripts/commands. See CLI.md
Leverage qdarktheme
with auto | light | dark
modes. Configuration is done via the Config
class.
config.set('ui.theme', 'dark')
qdarktheme.setup_theme(config.get('ui.theme'))
Mindset: Empower both end-users and developers to customize without hardcoding.
- Publisher: A singleton that connects Qt signals into a unified event system.
- Subscriber (Handler): Registers
on_<event_name>
handlers—add or remove listeners without touching Controllers.
def on_button_clicked(self, data = None):
# Event handling logic
pass
Mindset: Modules know only about events, not each other—enabling easy system expansion.
- Single Responsibility: Each file and class has one reason to change.
- Testable: Write unit tests for Services and Middleware.
- Config-Driven: Alter behavior via configuration, not code changes.
- Logging & Error Handling: Use middleware to capture errors, retry logic, and contextual logging.
- Documentation: Provide clear help for every component, service, and CLI command.
Contributions are welcome! Please read CONTRIBUTING.md
for guidelines.
Released under the MIT License. See the LICENSE
file for details.