qyro-engine 1.0.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qyro_engine-1.0.0a1/LICENSE +21 -0
- qyro_engine-1.0.0a1/NOTICE +159 -0
- qyro_engine-1.0.0a1/PKG-INFO +477 -0
- qyro_engine-1.0.0a1/README.md +448 -0
- qyro_engine-1.0.0a1/pyproject.toml +35 -0
- qyro_engine-1.0.0a1/qyro/__init__.py +71 -0
- qyro_engine-1.0.0a1/qyro/adapters/__init__.py +22 -0
- qyro_engine-1.0.0a1/qyro/adapters/environment/__init__.py +3 -0
- qyro_engine-1.0.0a1/qyro/adapters/environment/system_environment.py +57 -0
- qyro_engine-1.0.0a1/qyro/adapters/frameworks/__init__.py +21 -0
- qyro_engine-1.0.0a1/qyro/adapters/frameworks/base.py +20 -0
- qyro_engine-1.0.0a1/qyro/adapters/frameworks/factory.py +62 -0
- qyro_engine-1.0.0a1/qyro/adapters/frameworks/headless_adapter.py +57 -0
- qyro_engine-1.0.0a1/qyro/adapters/frameworks/kivy_adapter.py +79 -0
- qyro_engine-1.0.0a1/qyro/adapters/frameworks/pyqt5_adapter.py +23 -0
- qyro_engine-1.0.0a1/qyro/adapters/frameworks/pyqt6_adapter.py +35 -0
- qyro_engine-1.0.0a1/qyro/adapters/frameworks/pyside2_adapter.py +28 -0
- qyro_engine-1.0.0a1/qyro/adapters/frameworks/pyside6_adapter.py +35 -0
- qyro_engine-1.0.0a1/qyro/adapters/frameworks/qt_base.py +107 -0
- qyro_engine-1.0.0a1/qyro/adapters/frameworks/tkinter_adapter.py +80 -0
- qyro_engine-1.0.0a1/qyro/adapters/platform/__init__.py +3 -0
- qyro_engine-1.0.0a1/qyro/adapters/platform/detector.py +73 -0
- qyro_engine-1.0.0a1/qyro/adapters/resources/__init__.py +3 -0
- qyro_engine-1.0.0a1/qyro/adapters/resources/filesystem_resources.py +120 -0
- qyro_engine-1.0.0a1/qyro/adapters/settings/__init__.py +3 -0
- qyro_engine-1.0.0a1/qyro/adapters/settings/json_settings.py +86 -0
- qyro_engine-1.0.0a1/qyro/adapters/telemetry/__init__.py +4 -0
- qyro_engine-1.0.0a1/qyro/adapters/telemetry/console_hook.py +38 -0
- qyro_engine-1.0.0a1/qyro/adapters/telemetry/sentry_hook.py +51 -0
- qyro_engine-1.0.0a1/qyro/application/__init__.py +28 -0
- qyro_engine-1.0.0a1/qyro/application/ports/__init__.py +18 -0
- qyro_engine-1.0.0a1/qyro/application/ports/environment.py +37 -0
- qyro_engine-1.0.0a1/qyro/application/ports/resources.py +23 -0
- qyro_engine-1.0.0a1/qyro/application/ports/settings.py +22 -0
- qyro_engine-1.0.0a1/qyro/application/ports/telemetry.py +27 -0
- qyro_engine-1.0.0a1/qyro/application/ports/ui_framework.py +49 -0
- qyro_engine-1.0.0a1/qyro/application/use_cases/__init__.py +13 -0
- qyro_engine-1.0.0a1/qyro/application/use_cases/initialize_engine.py +52 -0
- qyro_engine-1.0.0a1/qyro/application/use_cases/load_settings.py +25 -0
- qyro_engine-1.0.0a1/qyro/application/use_cases/resolve_resource.py +30 -0
- qyro_engine-1.0.0a1/qyro/client/__init__.py +3 -0
- qyro_engine-1.0.0a1/qyro/client/component.py +529 -0
- qyro_engine-1.0.0a1/qyro/client/context.py +510 -0
- qyro_engine-1.0.0a1/qyro/container.py +79 -0
- qyro_engine-1.0.0a1/qyro/domain/__init__.py +33 -0
- qyro_engine-1.0.0a1/qyro/domain/entities.py +83 -0
- qyro_engine-1.0.0a1/qyro/domain/errors.py +49 -0
- qyro_engine-1.0.0a1/qyro/ui/__init__.py +8 -0
- qyro_engine-1.0.0a1/qyro/ui/component.py +8 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Neuri
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Qyro CLI
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 - 2026 Neuri
|
|
4
|
+
|
|
5
|
+
Qyro CLI depends on several open source libraries and external tools. This file
|
|
6
|
+
describes the open source software used by, supported by, or integrated with
|
|
7
|
+
Qyro CLI and the applicable license terms.
|
|
8
|
+
|
|
9
|
+
Some third-party software may be used by applications generated by Qyro CLI,
|
|
10
|
+
while other software is invoked externally by Qyro CLI when performing specific
|
|
11
|
+
build or distribution operations. Third-party components are not necessarily
|
|
12
|
+
distributed with Qyro CLI and remain subject to their respective licenses.
|
|
13
|
+
|
|
14
|
+
For the complete license terms of a dependency, refer to the license provided
|
|
15
|
+
by the respective project.
|
|
16
|
+
|
|
17
|
+
# Qyro
|
|
18
|
+
|
|
19
|
+
URL: https://github.com/Neuri-AI/qyro
|
|
20
|
+
|
|
21
|
+
The Qyro CLI generates and orchestrates applications based on Qyro.
|
|
22
|
+
|
|
23
|
+
Qyro is distributed under its own applicable license terms.
|
|
24
|
+
See the Qyro repository for its license and third-party notices.
|
|
25
|
+
|
|
26
|
+
# PyInstaller
|
|
27
|
+
|
|
28
|
+
URL: https://www.pyinstaller.org
|
|
29
|
+
|
|
30
|
+
Qyro CLI invokes PyInstaller to freeze Python applications into standalone
|
|
31
|
+
application artifacts.
|
|
32
|
+
|
|
33
|
+
PyInstaller is distributed under the GNU General Public License, version 2
|
|
34
|
+
or later, with an exception that permits the distribution of applications
|
|
35
|
+
generated by PyInstaller under terms selected by the application author.
|
|
36
|
+
|
|
37
|
+
Qyro CLI does not link to PyInstaller as a library; it invokes PyInstaller
|
|
38
|
+
as a build tool.
|
|
39
|
+
|
|
40
|
+
# PySide6
|
|
41
|
+
|
|
42
|
+
URL: https://doc.qt.io/qtforpython/
|
|
43
|
+
|
|
44
|
+
PySide6 may be used by applications generated by Qyro CLI.
|
|
45
|
+
|
|
46
|
+
PySide6 is distributed under the GNU Lesser General Public License, version 3,
|
|
47
|
+
or other applicable Qt licensing terms.
|
|
48
|
+
|
|
49
|
+
See the PySide6 and Qt licensing documentation for complete terms.
|
|
50
|
+
|
|
51
|
+
# PyQt6
|
|
52
|
+
|
|
53
|
+
URL: https://www.riverbankcomputing.com/software/pyqt/
|
|
54
|
+
|
|
55
|
+
PyQt6 may be used by applications generated by Qyro CLI.
|
|
56
|
+
|
|
57
|
+
PyQt6 is available under the GNU General Public License, version 3, or a
|
|
58
|
+
commercial license from Riverbank Computing, subject to the applicable
|
|
59
|
+
licensing terms.
|
|
60
|
+
|
|
61
|
+
# PyQt5
|
|
62
|
+
|
|
63
|
+
URL: https://www.riverbankcomputing.com/software/pyqt/
|
|
64
|
+
|
|
65
|
+
PyQt5 may be used by applications generated by Qyro CLI.
|
|
66
|
+
|
|
67
|
+
PyQt5 is available under the GNU General Public License, version 3, or a
|
|
68
|
+
commercial license from Riverbank Computing, subject to the applicable
|
|
69
|
+
licensing terms.
|
|
70
|
+
|
|
71
|
+
# PySide2
|
|
72
|
+
|
|
73
|
+
URL: https://wiki.qt.io/Qt_for_Python
|
|
74
|
+
|
|
75
|
+
PySide2 may be used by applications generated by Qyro CLI.
|
|
76
|
+
|
|
77
|
+
PySide2 is distributed under the GNU Lesser General Public License, version 3,
|
|
78
|
+
or other applicable Qt licensing terms.
|
|
79
|
+
|
|
80
|
+
See the PySide2 and Qt licensing documentation for complete terms.
|
|
81
|
+
|
|
82
|
+
# Kivy
|
|
83
|
+
|
|
84
|
+
URL: https://kivy.org
|
|
85
|
+
|
|
86
|
+
Kivy may be used by applications generated by Qyro CLI.
|
|
87
|
+
|
|
88
|
+
Kivy is distributed under the MIT License.
|
|
89
|
+
|
|
90
|
+
# Tkinter
|
|
91
|
+
|
|
92
|
+
URL: https://docs.python.org/3/library/tkinter.html
|
|
93
|
+
|
|
94
|
+
Tkinter is part of the Python standard library and may be used by applications
|
|
95
|
+
generated by Qyro CLI.
|
|
96
|
+
|
|
97
|
+
Tkinter is distributed as part of Python and is subject to the applicable
|
|
98
|
+
Python license terms.
|
|
99
|
+
|
|
100
|
+
# External Distribution Tools
|
|
101
|
+
|
|
102
|
+
Qyro CLI may require external tools for specific distribution targets.
|
|
103
|
+
These tools are not bundled with or redistributed by Qyro CLI.
|
|
104
|
+
|
|
105
|
+
When an operation requires one of these tools and it is not installed,
|
|
106
|
+
Qyro CLI reports the missing requirement and instructs the user to install
|
|
107
|
+
the corresponding tool.
|
|
108
|
+
|
|
109
|
+
## create-dmg
|
|
110
|
+
|
|
111
|
+
URL: https://github.com/create-dmg/create-dmg
|
|
112
|
+
|
|
113
|
+
Qyro CLI may invoke create-dmg to create customized macOS disk images.
|
|
114
|
+
|
|
115
|
+
create-dmg is distributed under the MIT License.
|
|
116
|
+
|
|
117
|
+
## fpm
|
|
118
|
+
|
|
119
|
+
URL: https://github.com/jordansissel/fpm
|
|
120
|
+
|
|
121
|
+
Qyro CLI may invoke fpm to create Linux packages such as DEB, RPM,
|
|
122
|
+
and Arch packages.
|
|
123
|
+
|
|
124
|
+
fpm is distributed under the MIT License.
|
|
125
|
+
|
|
126
|
+
## NSIS
|
|
127
|
+
|
|
128
|
+
URL: https://nsis.sourceforge.io
|
|
129
|
+
|
|
130
|
+
Qyro CLI may invoke NSIS to create Windows installers.
|
|
131
|
+
|
|
132
|
+
NSIS is distributed under its own open source license terms.
|
|
133
|
+
|
|
134
|
+
The applicable copyright and license notices for these external tools are
|
|
135
|
+
provided by their respective projects.
|
|
136
|
+
|
|
137
|
+
# Open Source Licensing
|
|
138
|
+
|
|
139
|
+
Qyro CLI is designed to work with multiple independently licensed open source
|
|
140
|
+
frameworks, libraries, and packaging tools.
|
|
141
|
+
|
|
142
|
+
The licensing terms of a generated application depend on the frameworks,
|
|
143
|
+
libraries, resources, and external tools included in that application.
|
|
144
|
+
|
|
145
|
+
Users are responsible for reviewing and complying with the licenses applicable
|
|
146
|
+
to the dependencies and components they distribute.
|
|
147
|
+
|
|
148
|
+
Where a dependency requires attribution, license notices, or source code
|
|
149
|
+
availability, those requirements must be satisfied in accordance with the
|
|
150
|
+
dependency's license.
|
|
151
|
+
|
|
152
|
+
# Third-Party Notices
|
|
153
|
+
|
|
154
|
+
This NOTICE file is provided for informational and attribution purposes.
|
|
155
|
+
It does not replace, modify, or supersede the license terms of any third-party
|
|
156
|
+
software.
|
|
157
|
+
|
|
158
|
+
For components distributed separately from Qyro CLI, consult the corresponding
|
|
159
|
+
upstream project for the authoritative license text and copyright notices.
|
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: qyro-engine
|
|
3
|
+
Version: 1.0.0a1
|
|
4
|
+
Summary: Qyro Engine is the runtime engine for the Qyro ecosystem, providing the foundation for building and running Python applications across desktop and mobile platforms.
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: Qyro Team
|
|
7
|
+
Requires-Python: >=3.10,<3.16
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Provides-Extra: all
|
|
15
|
+
Provides-Extra: kivy
|
|
16
|
+
Provides-Extra: pyqt5
|
|
17
|
+
Provides-Extra: pyqt6
|
|
18
|
+
Provides-Extra: pyside2
|
|
19
|
+
Provides-Extra: pyside6
|
|
20
|
+
Provides-Extra: sentry
|
|
21
|
+
Requires-Dist: PyQt5 (>=5.15.0) ; (python_version >= "3.11" and python_version < "3.14") and (extra == "pyqt5" or extra == "all")
|
|
22
|
+
Requires-Dist: PyQt6 (>=6.5.0) ; (python_version >= "3.11" and python_version < "3.15") and (extra == "pyqt6" or extra == "all")
|
|
23
|
+
Requires-Dist: PySide2 (>=5.15.0) ; (python_version < "3.11") and (extra == "pyside2" or extra == "all")
|
|
24
|
+
Requires-Dist: PySide6 (>=6.5.0) ; (python_version >= "3.11" and python_version < "3.15") and (extra == "pyside6" or extra == "all")
|
|
25
|
+
Requires-Dist: kivy (>=2.2.0) ; extra == "kivy" or extra == "all"
|
|
26
|
+
Requires-Dist: sentry-sdk (>=1.30.0) ; extra == "sentry" or extra == "all"
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
<p align="center">
|
|
30
|
+
<img src="https://ik.imagekit.io/kummiktgaiq/ppg/Qyro-logo.svg?updatedAt=1755215983279" alt="Qyro Logo" width="50%">
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
> [!WARNING]
|
|
34
|
+
> **Qyro is currently in alpha.** APIs, adapters, and behavior may change between releases.
|
|
35
|
+
> Desktop workflows are the current focus. Mobile support is not yet considered stable.
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# ⚡ Qyro Runtime
|
|
39
|
+
|
|
40
|
+
> **Runtime engine for Python applications, providing a cross-platform foundation for desktop and mobile environments.**
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
[](https://python.org)
|
|
44
|
+

|
|
45
|
+

|
|
46
|
+

|
|
47
|
+

|
|
48
|
+

|
|
49
|
+
[](LICENSE)
|
|
50
|
+
[](https://buymeacoffee.com/neuri)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
> [!NOTE]
|
|
54
|
+
> **Need the Qyro automation and build tools?** This repository contains the **Qyro Runtime**, which provides the application context, framework adapters, resource handling, and component lifecycle for Python GUI applications. For **project scaffolding, build automation, packaging, distribution, code signing, and release workflows**, see **[Qyro CLI](https://github.com/Neuri-AI/qyro-cli)**.
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
## What it is
|
|
58
|
+
|
|
59
|
+
Qyro currently provides:
|
|
60
|
+
|
|
61
|
+
- A runtime container that wires settings, resource lookup, telemetry hook, and UI adapter.
|
|
62
|
+
- A single ApplicationContext API for Qt, Tkinter, and Kivy style apps.
|
|
63
|
+
- Automatic settings loading from JSON files.
|
|
64
|
+
- Resource resolution that works in source mode and frozen mode.
|
|
65
|
+
- A component lifecycle mixin for UI classes with flexible property handling.
|
|
66
|
+
|
|
67
|
+
## What it is not
|
|
68
|
+
|
|
69
|
+
Qyro is not the build/distribution CLI.
|
|
70
|
+
|
|
71
|
+
- Build, bundle, signing, notarization: qyro-cli concern.
|
|
72
|
+
- Web bridge APIs from legacy PPG examples: not part of qyro public API.
|
|
73
|
+
|
|
74
|
+
## Supported UI adapters
|
|
75
|
+
|
|
76
|
+
Framework adapters available in the engine:
|
|
77
|
+
|
|
78
|
+
- PySide6
|
|
79
|
+
- PyQt6
|
|
80
|
+
- PySide2
|
|
81
|
+
- PyQt5
|
|
82
|
+
- Kivy
|
|
83
|
+
- Tkinter
|
|
84
|
+
- Headless fallback
|
|
85
|
+
|
|
86
|
+
Adapter selection behavior:
|
|
87
|
+
|
|
88
|
+
- If binding/framework is provided in settings, it is used.
|
|
89
|
+
- Otherwise the engine auto-detects in this order:
|
|
90
|
+
PySide6 -> PyQt6 -> PySide2 -> PyQt5 -> Kivy -> Tkinter -> Headless
|
|
91
|
+
|
|
92
|
+
## Compatibility
|
|
93
|
+
|
|
94
|
+
The table below reports validation results for the complete desktop workflow:
|
|
95
|
+
|
|
96
|
+
```text
|
|
97
|
+
init → start → build → bundle
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
> Table last validated: **2026-10-02**
|
|
101
|
+
> CI run: [#37052349565](https://github.com/Neuri-AI/qyro-cli/actions/runs/37052349565)
|
|
102
|
+
|
|
103
|
+
| Framework | Platform | Python 3.10 | Python 3.11 | Python 3.12 | Python 3.13 | Python 3.14 | Notes |
|
|
104
|
+
| --------- | -------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----- |
|
|
105
|
+
| PySide6 | Windows | ✅ | ✅ | ✅ | ✅ | ✅ | Full pass |
|
|
106
|
+
| PySide6 | macOS | ✅ | ✅ | ✅ | ✅ | ✅ | Full pass |
|
|
107
|
+
| PySide6 | Linux | ✅ | ✅ | ✅ | ✅ | ✅ | Full pass |
|
|
108
|
+
| PySide2 | Linux | — | — | — | — | — | No CI coverage |
|
|
109
|
+
| PySide2 | Windows | — | — | — | — | — | No CI coverage |
|
|
110
|
+
| PySide2 | macOS | — | — | — | — | — | No CI coverage |
|
|
111
|
+
| PyQt6 | Windows | ✅ | ✅ | ✅ | ✅ | ✅ | Full pass |
|
|
112
|
+
| PyQt6 | macOS | ✅ | ✅ | ✅ | ✅ | ✅ | Full pass |
|
|
113
|
+
| PyQt6 | Linux | ✅ | ✅ | ✅ | ✅ | ✅ | Full pass |
|
|
114
|
+
| PyQt5 | Windows | ✅ | ✅ | ✅ | ✅ | ✅ | Full pass |
|
|
115
|
+
| PyQt5 | macOS | ✅ | ✅ | ✅ | ✅ | ✅ | Full pass |
|
|
116
|
+
| PyQt5 | Linux | ✅ | ✅ | ✅ | ✅ | ✅ | Full pass |
|
|
117
|
+
| Kivy | Windows | ✅ | ✅ | ✅ | ✅ | ❌ | Python 3.14 failed at `install` |
|
|
118
|
+
| Kivy | macOS | ✅ | ✅ | ✅ | ✅ | ✅ | Full pass |
|
|
119
|
+
| Kivy | Linux | ✅ | ✅ | ✅ | ✅ | ✅ | Full pass |
|
|
120
|
+
| Tkinter | Windows | ✅ | ✅ | ✅ | ✅ | ✅ | Full pass |
|
|
121
|
+
| Tkinter | macOS | ✅ | ✅ | ✅ | ✅ | ✅ | Full pass |
|
|
122
|
+
| Tkinter | Linux | ✅ | ✅ | ✅ | ✅ | ✅ | Full pass |
|
|
123
|
+
|
|
124
|
+
Legend:
|
|
125
|
+
|
|
126
|
+
- ✅ `FULL PASS`: all four workflow stages completed.
|
|
127
|
+
- ❌ `FAIL`: validation was attempted and failed.
|
|
128
|
+
- — `NOT TESTED`: no validation result is available.
|
|
129
|
+
|
|
130
|
+
Known failure:
|
|
131
|
+
|
|
132
|
+
- **Kivy · Python 3.14 · Windows:** failed during `install`.
|
|
133
|
+
|
|
134
|
+
Compatibility results are specific to the operating system, Python version,
|
|
135
|
+
framework, dependency state, and CI environment used during testing.
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
## Installation
|
|
139
|
+
|
|
140
|
+
This package is configured with Poetry extras.
|
|
141
|
+
|
|
142
|
+
Base package:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
poetry add qyro
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
With specific GUI stack:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
poetry add qyro -E pyside6
|
|
153
|
+
poetry add qyro -E pyqt6
|
|
154
|
+
poetry add qyro -E pyside2
|
|
155
|
+
poetry add qyro -E pyqt5
|
|
156
|
+
poetry add qyro -E kivy
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
With telemetry helper:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
poetry add qyro -E sentry
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Everything enabled:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
poetry add qyro -E all
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Expected project layout
|
|
175
|
+
|
|
176
|
+
Qyro looks for settings and resources in common locations.
|
|
177
|
+
Resources are resolved from OS-specific folders first, then base folders.
|
|
178
|
+
Typical layout:
|
|
179
|
+
|
|
180
|
+
```text
|
|
181
|
+
my-app/
|
|
182
|
+
├─ main.py
|
|
183
|
+
├─ settings/
|
|
184
|
+
│ ├─ base.json
|
|
185
|
+
│ ├─ windows.json
|
|
186
|
+
│ ├─ mac.json
|
|
187
|
+
│ └─ linux.json
|
|
188
|
+
└─ resources/
|
|
189
|
+
├─ base/
|
|
190
|
+
├─ windows/
|
|
191
|
+
├─ mac/
|
|
192
|
+
└─ linux/
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Qyro Settings Builder
|
|
197
|
+
|
|
198
|
+
Configuring application settings and release options manually can be
|
|
199
|
+
time-consuming and error-prone. The **Qyro Settings Builder** provides a
|
|
200
|
+
visual interface for creating and managing the settings used by Qyro
|
|
201
|
+
projects.
|
|
202
|
+
|
|
203
|
+
It helps configure:
|
|
204
|
+
|
|
205
|
+
- Application settings.
|
|
206
|
+
- Platform-specific settings.
|
|
207
|
+
- Resource-related options.
|
|
208
|
+
- Release and packaging settings.
|
|
209
|
+
- Distribution metadata.
|
|
210
|
+
|
|
211
|
+
Use the online builder here:
|
|
212
|
+
|
|
213
|
+
[Open Qyro Settings Builder](https://qyro-settings-builder.up.railway.app/)
|
|
214
|
+
|
|
215
|
+
The generated configuration files can be placed in the project's `settings/`
|
|
216
|
+
directory and reviewed or customized before running Qyro CLI commands.
|
|
217
|
+
> [!NOTE]
|
|
218
|
+
> The Settings Builder is an auxiliary tool for preparing configuration files.
|
|
219
|
+
> The final settings remain part of your project and should be reviewed before
|
|
220
|
+
> building or releasing an application.
|
|
221
|
+
|
|
222
|
+
## Quick start (Qt)
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
import sys
|
|
226
|
+
from PySide6.QtWidgets import QMainWindow, QLabel
|
|
227
|
+
from qyro import ApplicationContext
|
|
228
|
+
from qyro.ui.component import Component
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
class MyWindow(QMainWindow, Component, ApplicationContext):
|
|
232
|
+
def component_will_mount(self):
|
|
233
|
+
self.resize(640, 480)
|
|
234
|
+
|
|
235
|
+
def render(self):
|
|
236
|
+
label = QLabel(
|
|
237
|
+
f"App: {self.window_title}\n"
|
|
238
|
+
f"Platform: {self.platform.value}\n"
|
|
239
|
+
f"Frozen: {self.is_frozen}",
|
|
240
|
+
parent=self,
|
|
241
|
+
)
|
|
242
|
+
label.move(24, 24)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
if __name__ == "__main__":
|
|
246
|
+
window = MyWindow()
|
|
247
|
+
window.show()
|
|
248
|
+
sys.exit(window.run())
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Quick start (Kivy)
|
|
253
|
+
|
|
254
|
+
```python
|
|
255
|
+
from kivy.app import App
|
|
256
|
+
from kivy.uix.label import Label
|
|
257
|
+
from kivy.core.window import Window
|
|
258
|
+
from qyro import ApplicationContext
|
|
259
|
+
from qyro.ui.component import Component
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class MyKvApp(App, Component, ApplicationContext):
|
|
263
|
+
|
|
264
|
+
def component_will_mount(self):
|
|
265
|
+
Window.size = (640, 480)
|
|
266
|
+
|
|
267
|
+
def render(self):
|
|
268
|
+
label = Label(
|
|
269
|
+
text=(
|
|
270
|
+
f"Hello, World!\n\n"
|
|
271
|
+
f"App Title: {self.window_title}\n"
|
|
272
|
+
f"Platform: {self.platform.value} (Frozen: {self.is_frozen})\n\n"
|
|
273
|
+
),
|
|
274
|
+
halign="left",
|
|
275
|
+
valign="middle",
|
|
276
|
+
)
|
|
277
|
+
label.bind(size=label.setter("text_size"))
|
|
278
|
+
return label
|
|
279
|
+
|
|
280
|
+
def build(self):
|
|
281
|
+
return self.render()
|
|
282
|
+
|
|
283
|
+
if __name__ == "__main__":
|
|
284
|
+
MyKvApp().run()
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Quick start (Tkinter)
|
|
289
|
+
|
|
290
|
+
```python
|
|
291
|
+
import tkinter as tk
|
|
292
|
+
from qyro import ApplicationContext
|
|
293
|
+
from qyro.ui.component import Component
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
class MyTkApp(tk.Tk, Component, ApplicationContext):
|
|
297
|
+
def component_will_mount(self):
|
|
298
|
+
self.geometry("480x240")
|
|
299
|
+
|
|
300
|
+
def render(self):
|
|
301
|
+
tk.Label(
|
|
302
|
+
self,
|
|
303
|
+
text=f"{self.window_title} | {self.platform.value} | frozen={self.is_frozen}",
|
|
304
|
+
).pack(padx=16, pady=16)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
if __name__ == "__main__":
|
|
308
|
+
app = MyTkApp()
|
|
309
|
+
app.run()
|
|
310
|
+
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## API Reference
|
|
314
|
+
|
|
315
|
+
This section documents the public runtime API that is available in the current codebase.
|
|
316
|
+
|
|
317
|
+
### Top-level API (`qyro`)
|
|
318
|
+
|
|
319
|
+
Exports:
|
|
320
|
+
|
|
321
|
+
* ApplicationContext
|
|
322
|
+
* Component
|
|
323
|
+
* EngineContainer
|
|
324
|
+
* PlatformDetector
|
|
325
|
+
* PlatformType
|
|
326
|
+
* ExecutionMode
|
|
327
|
+
* AppMetadata
|
|
328
|
+
* QyroEngineError
|
|
329
|
+
* ResourceNotFoundError
|
|
330
|
+
* SettingsNotFoundError
|
|
331
|
+
* FrameworkNotAvailableError
|
|
332
|
+
* get_resource
|
|
333
|
+
* load_build_settings
|
|
334
|
+
* is_frozen
|
|
335
|
+
|
|
336
|
+
Function signatures:
|
|
337
|
+
|
|
338
|
+
```python
|
|
339
|
+
def get_resource(*segments: str, required: bool = True) -> str
|
|
340
|
+
def load_build_settings() -> dict
|
|
341
|
+
def is_frozen() -> bool
|
|
342
|
+
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Behavior notes:
|
|
346
|
+
|
|
347
|
+
* get_resource returns an absolute path string.
|
|
348
|
+
* If required=True and a resource is not found, the resolver may raise a runtime error.
|
|
349
|
+
|
|
350
|
+
### ApplicationContext
|
|
351
|
+
|
|
352
|
+
Constructor:
|
|
353
|
+
|
|
354
|
+
```python
|
|
355
|
+
ApplicationContext(
|
|
356
|
+
framework: str | None = None,
|
|
357
|
+
custom_root: Path | None = None,
|
|
358
|
+
enable_sentry: bool = True,
|
|
359
|
+
argv: list[str] | None = None,
|
|
360
|
+
*args,
|
|
361
|
+
**kwargs,
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Parameter reference:
|
|
367
|
+
|
|
368
|
+
| Parameter | Type | Default | Description |
|
|
369
|
+
|---|---|---|---|
|
|
370
|
+
| `framework` | `str \| None` | `None` | Forces a specific framework adapter. |
|
|
371
|
+
| `custom_root` | `Path \| None` | `None` | Overrides the project root directory. |
|
|
372
|
+
| `enable_sentry` | `bool` | `True` | Enables the Sentry hook when a DSN is available. |
|
|
373
|
+
| `argv` | `list[str] \| None` | `None` | Optional arguments passed when creating the application. |
|
|
374
|
+
|
|
375
|
+
Property reference:
|
|
376
|
+
|
|
377
|
+
| Property | Type | Description |
|
|
378
|
+
|---|---|---|
|
|
379
|
+
| `container` | `EngineContainer` | The underlying dependency container instance. |
|
|
380
|
+
| `app` | `Any` | The native framework application instance, such as `QApplication`, a Tk root, or a Kivy app. |
|
|
381
|
+
| `metadata` | `AppMetadata` | Application metadata loaded from the settings. |
|
|
382
|
+
| `app_settings` | `dict[str, Any]` | The final merged settings dictionary. |
|
|
383
|
+
| `is_frozen` | `bool` | Indicates whether the application is running from a frozen bundle. |
|
|
384
|
+
| `platform` | `PlatformType` | The detected platform enum value. |
|
|
385
|
+
| `execution_mode` | `ExecutionMode` | The current execution mode: source or frozen. |
|
|
386
|
+
| `window_title` | `str` | The current window title, with getter and setter support. |
|
|
387
|
+
| `app_icon` | `str \| None` | The resolved application icon path, with setter support. |
|
|
388
|
+
|
|
389
|
+
Method reference:
|
|
390
|
+
|
|
391
|
+
| Method | Signature | Returns | Notes |
|
|
392
|
+
|---|---|---|---|
|
|
393
|
+
| `get_default_window_title` | `get_default_window_title()` | `str` | Uses the metadata-to-`app_name` fallback chain. |
|
|
394
|
+
| `get_window_title` | `get_window_title()` | `str` | Reads the current title from the native window when possible. |
|
|
395
|
+
| `set_window_title` | `set_window_title(title, window=None)` | `bool` | Best-effort cross-toolkit title assignment. |
|
|
396
|
+
| `get_app_icon_path` | `get_app_icon_path()` | `str \| None` | Automatically discovers the icon from settings and resource conventions. |
|
|
397
|
+
| `set_window_icon` | `set_window_icon(icon_path_or_relative, window=None)` | `bool` | Accepts an absolute path or a relative resource path. |
|
|
398
|
+
| `get_resource` | `get_resource(*segments, required=True)` | `str` | Resolves a resource to an absolute path string. |
|
|
399
|
+
| `run` | `run()` | `int` | Starts the event loop through the active framework adapter. |
|
|
400
|
+
|
|
401
|
+
### Component (`qyro.ui.component`)
|
|
402
|
+
|
|
403
|
+
Component is a lifecycle mixin designed for UI classes supporting multi-toolkit frameworks.
|
|
404
|
+
|
|
405
|
+
#### Instantiation & Props
|
|
406
|
+
|
|
407
|
+
Components can receive properties (`props`) in two ways upon instantiation:
|
|
408
|
+
|
|
409
|
+
1. Via an explicit dictionary: `MyComponent(parent=self, props={"title": "Hello"})`
|
|
410
|
+
2. Via direct keyword arguments: `MyComponent(parent=self, title="Hello")` (automatically isolating toolkit-specific arguments like `parent`).
|
|
411
|
+
|
|
412
|
+
Lifecycle hook order:
|
|
413
|
+
|
|
414
|
+
1. `component_will_mount`
|
|
415
|
+
2. `render`
|
|
416
|
+
3. `component_did_mount`
|
|
417
|
+
4. `set_styles`
|
|
418
|
+
5. `on_resize`
|
|
419
|
+
|
|
420
|
+
Primary hooks:
|
|
421
|
+
|
|
422
|
+
| Hook | Signature | Purpose |
|
|
423
|
+
|---|---|---|
|
|
424
|
+
| `component_will_mount` | `component_will_mount()` | Performs initialization before rendering. |
|
|
425
|
+
| `render` | `render()` | Builds the component's widgets and layouts. |
|
|
426
|
+
| `component_did_mount` | `component_did_mount()` | Performs setup after rendering. |
|
|
427
|
+
| `set_styles` | `set_styles(path_or_styles=None)` | Applies a stylesheet from a file path or an inline style definition. |
|
|
428
|
+
| `on_resize` | `on_resize()` | Handles responsive behavior when the component is mounted or resized. |
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
Utility methods:
|
|
432
|
+
|
|
433
|
+
| Method | Signature | Description |
|
|
434
|
+
| --- | --- | --- |
|
|
435
|
+
| `calc` | `calc(a, b)` | Returns a percentage-based integer value. |
|
|
436
|
+
| `find` | `find(target_type, name="")` | Delegates to the native `findChild` when available. |
|
|
437
|
+
| `destroy_component` | `destroy_component()` | Detaches and schedules widget cleanup safely. |
|
|
438
|
+
| `get_resource` | `get_resource(*segments, required=True)` | Top-level resource resolver shortcut. |
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
* Automatic icon/title assignment is best-effort and depends on toolkit capabilities and available files.
|
|
443
|
+
|
|
444
|
+
## Repository pointers
|
|
445
|
+
|
|
446
|
+
* Public entrypoint: qyro/**init**.py
|
|
447
|
+
* Application context facade: qyro/client/context.py
|
|
448
|
+
* Component lifecycle mixin: qyro/client/component.py
|
|
449
|
+
* Framework adapters: qyro/adapters/frameworks/
|
|
450
|
+
* Resource resolver: qyro/adapters/resources/filesystem_resources.py
|
|
451
|
+
* Settings loader: qyro/adapters/settings/json_settings.py
|
|
452
|
+
|
|
453
|
+
## 🤝 Contributing
|
|
454
|
+
|
|
455
|
+
Contributions to `qyro` and the Qyro ecosystem are welcome.
|
|
456
|
+
|
|
457
|
+
1. Fork the repository on GitHub.
|
|
458
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`).
|
|
459
|
+
3. Run test suites (`poetry run pytest`).
|
|
460
|
+
4. Commit your changes (`git commit -m 'feat: add amazing feature'`).
|
|
461
|
+
5. Push to your branch (`git push origin feature/amazing-feature`).
|
|
462
|
+
6. Open a Pull Request.
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
## 📄 License
|
|
467
|
+
|
|
468
|
+
MIT. See [LICENSE](LICENSE).
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
## 👥 Organization & Maintainers
|
|
473
|
+
|
|
474
|
+
- **Organization:** [Neuri](https://github.com/Neuri-AI)
|
|
475
|
+
- **Lead Maintainer:** Luis Alfredo De Los Reyes ([luisalfredoreyes98@gmail.com](mailto:luisalfredoreyes98@gmail.com))
|
|
476
|
+
- **Ecosystem:** [Qyro](https://github.com/Neuri-AI/qyro) • [Qyro CLI](https://github.com/Neuri-AI/qyro-cli) • [Boilerplates](https://github.com/Neuri-AI)
|
|
477
|
+
|