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: 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 tansautn/dat_amzir_py my-app cd my-app pixi installFor full Pixi usage, see docs/provided-by-base/pixi-usage.md
-
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.
project_root/
├── app/ # 🏠 Application Logic (Userland)
│ ├── components/ # UI Components specific to this app
│ ├── controllers/ # Controllers for app logic
│ └── ... # Other app-specific files
├── core/ # ⚙️ Base Framework (Immutable Core)
│ ├── BaseController.py
│ ├── taskSystem/
│ ├── WidgetManager.py
│ └── ... # Core modules provided by the Base
├── tests/ # 🧪 Application Tests
│ └── ... # Tests for your 'app/' directory
├── tests_core/ # 🔬 Core Framework Tests
│ └── ... # Tests for 'core/' (Contributors/Authors only)
└── docs/ # 📚 Documentation
The core directory contains the foundational building blocks of the framework (TaskSystem, BaseController, etc.).
- Managed by Base: This directory is maintained by the framework authors.
- Do Not Modify: Avoid changing files here directly, as updates will overwrite changes.
- Extendable: Use the components provided here to build your application in
app/.
The app directory is your workspace.
- Your Code: innovative features, UI logic, and business rules go here.
- Safe from Updates: Changes in
corewill not touch your work inapp.
We maintain a clear separation in testing as well:
tests/: Place all tests for your application features here.tests_core/: Contains internal tests for the framework itself. Use this only if you are contributing to the Base Core.
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 = {
'openBtnClick': ['pushButton', 'clicked']
}
# in handler
class MyControllerHandler(Subscriber):
def onOpenBtnClick(self, data = None):
# Event handling logic
passMindset: 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', 50, saveToConfig=True)Mindset: Each component has a clear responsibility; state is managed centrally to avoid side effects.
- Supports multi-threading, scheduling, and task chaining.
- Provides robust retry logic, persistence, and progress tracking.
# Add a task
task = AdbCommandTask(name="Install APK", command="install app.apk")
taskManager.addTask(task)
# Create a chain of tasks
chain = taskManager.addChainTask(
name="Workflow",
tasks=[task1, task2],
retryBehaviorMap={'Task1': ChainRetryBehavior.SKIP_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 MyServiceMindset: 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<PascalCasedEventName>handlers—add or remove listeners without touching Controllers.
def onButtonClicked(self, data = None):
# Event handling logic
passMindset: 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.