frontengine 1.0.0__tar.gz → 1.0.1__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.
- {frontengine-1.0.0 → frontengine-1.0.1}/LICENSE +21 -21
- frontengine-1.0.1/PKG-INFO +121 -0
- frontengine-1.0.1/README.md +97 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/__init__.py +30 -30
- frontengine-1.0.1/frontengine/__main__.py +8 -0
- frontengine-1.0.1/frontengine/show/base_widget.py +47 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/gif/paint_gif.py +47 -47
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/image/paint_image.py +51 -35
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/load/load_someone_make_ui.py +68 -68
- frontengine-1.0.1/frontengine/show/overlay_factory.py +112 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/particle/particle_ui.py +166 -175
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/scene/extend_graphic_scene.py +32 -32
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/scene/extend_graphic_view.py +78 -78
- frontengine-1.0.1/frontengine/show/scene/scene.py +47 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/sound_player/sound_effect.py +58 -82
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/sound_player/sound_player.py +65 -88
- frontengine-1.0.1/frontengine/show/text/draw_text.py +112 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/video/video_player.py +75 -130
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/web/webview.py +87 -108
- frontengine-1.0.1/frontengine/show/window_helpers.py +40 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/system_tray/extend_system_tray.py +117 -76
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/color/global_color.py +4 -4
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/dialog/choose_file_dialog.py +95 -95
- frontengine-1.0.1/frontengine/ui/dialog/hotkey_settings_dialog.py +112 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/dialog/save_file_dialog.py +26 -26
- frontengine-1.0.1/frontengine/ui/main_ui.py +403 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/menu/help_menu.py +61 -61
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/menu/how_to_menu.py +44 -44
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/menu/language_menu.py +57 -57
- frontengine-1.0.1/frontengine/ui/menu/preset_menu.py +298 -0
- frontengine-1.0.1/frontengine/ui/menu/settings_menu.py +111 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/control_center/control_center_ui.py +266 -158
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/gif/gif_setting_ui.py +207 -132
- frontengine-1.0.1/frontengine/ui/page/image/image_setting_ui.py +286 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/particle/particle_setting_ui.py +240 -170
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/scene_setting/scene_manager.py +120 -120
- frontengine-1.0.1/frontengine/ui/page/scene_setting/scene_page/base_scene_page.py +72 -0
- frontengine-1.0.1/frontengine/ui/page/scene_setting/scene_page/gif.py +52 -0
- frontengine-1.0.1/frontengine/ui/page/scene_setting/scene_page/image.py +47 -0
- frontengine-1.0.1/frontengine/ui/page/scene_setting/scene_page/registry.py +18 -0
- frontengine-1.0.1/frontengine/ui/page/scene_setting/scene_page/sound.py +49 -0
- frontengine-1.0.1/frontengine/ui/page/scene_setting/scene_page/text.py +45 -0
- frontengine-1.0.1/frontengine/ui/page/scene_setting/scene_page/video.py +57 -0
- frontengine-1.0.1/frontengine/ui/page/scene_setting/scene_page/web.py +35 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/scene_setting/scene_setting_ui.py +42 -56
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/sound_player/sound_player_setting_ui.py +131 -111
- frontengine-1.0.1/frontengine/ui/page/text/text_setting_ui.py +235 -0
- frontengine-1.0.1/frontengine/ui/page/utils.py +272 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/video/video_setting_ui.py +236 -156
- frontengine-1.0.1/frontengine/ui/page/web/web_setting_ui.py +189 -0
- frontengine-1.0.1/frontengine/user_setting/preset_repository.py +209 -0
- frontengine-1.0.1/frontengine/user_setting/scene_setting.py +46 -0
- frontengine-1.0.1/frontengine/user_setting/user_setting_file.py +131 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/browser/browser.py +20 -20
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/critical_exit/check_key_is_press.py +19 -19
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/critical_exit/critical_exit.py +64 -64
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/critical_exit/win32_vk.py +368 -368
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/exception/__init__.py +1 -1
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/exception/exception_tags.py +10 -10
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/exception/exceptions.py +18 -18
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/file/open/__init__.py +1 -1
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/file/open/open_file.py +35 -35
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/file/save/__init__.py +1 -1
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/file/save/save_file.py +32 -32
- frontengine-1.0.1/frontengine/utils/hotkey/hotkey_service.py +99 -0
- frontengine-1.0.1/frontengine/utils/json/json_file.py +37 -0
- frontengine-1.0.1/frontengine/utils/json/json_repository.py +42 -0
- frontengine-1.0.1/frontengine/utils/json_format/__init__.py +1 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/json_format/json_process.py +41 -41
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/logging/loggin_instance.py +45 -45
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/multi_language/english.py +217 -146
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/multi_language/france.py +147 -147
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/multi_language/germany.py +147 -147
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/multi_language/italy.py +147 -147
- frontengine-1.0.1/frontengine/utils/multi_language/language_wrapper.py +52 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/multi_language/russian.py +147 -147
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/multi_language/simplified_chinese.py +147 -147
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/multi_language/traditional_chinese.py +218 -147
- frontengine-1.0.1/frontengine/utils/preset_schedule/preset_schedule_service.py +85 -0
- frontengine-1.0.1/frontengine/utils/redirect_manager/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/redirect_manager/redirect_manager_class.py +84 -84
- frontengine-1.0.1/frontengine/utils/smart_pause/__init__.py +0 -0
- frontengine-1.0.1/frontengine/utils/smart_pause/smart_pause_service.py +119 -0
- frontengine-1.0.1/frontengine/utils/theme_schedule/__init__.py +0 -0
- frontengine-1.0.1/frontengine/utils/theme_schedule/theme_schedule_service.py +97 -0
- frontengine-1.0.1/frontengine/utils/web_url.py +49 -0
- frontengine-1.0.1/frontengine/worker/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/worker/qthread_worker.py +59 -59
- frontengine-1.0.1/frontengine.egg-info/PKG-INFO +121 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine.egg-info/SOURCES.txt +20 -0
- frontengine-1.0.1/frontengine.egg-info/entry_points.txt +2 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine.egg-info/requires.txt +1 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/pyproject.toml +40 -37
- {frontengine-1.0.0 → frontengine-1.0.1}/setup.cfg +4 -4
- frontengine-1.0.0/PKG-INFO +0 -73
- frontengine-1.0.0/README.md +0 -50
- frontengine-1.0.0/frontengine/show/base_widget.py +0 -83
- frontengine-1.0.0/frontengine/show/scene/scene.py +0 -120
- frontengine-1.0.0/frontengine/show/text/draw_text.py +0 -131
- frontengine-1.0.0/frontengine/ui/main_ui.py +0 -221
- frontengine-1.0.0/frontengine/ui/page/image/image_setting_ui.py +0 -116
- frontengine-1.0.0/frontengine/ui/page/scene_setting/scene_page/gif.py +0 -87
- frontengine-1.0.0/frontengine/ui/page/scene_setting/scene_page/image.py +0 -72
- frontengine-1.0.0/frontengine/ui/page/scene_setting/scene_page/sound.py +0 -77
- frontengine-1.0.0/frontengine/ui/page/scene_setting/scene_page/text.py +0 -80
- frontengine-1.0.0/frontengine/ui/page/scene_setting/scene_page/video.py +0 -107
- frontengine-1.0.0/frontengine/ui/page/scene_setting/scene_page/web.py +0 -58
- frontengine-1.0.0/frontengine/ui/page/text/text_setting_ui.py +0 -124
- frontengine-1.0.0/frontengine/ui/page/utils.py +0 -84
- frontengine-1.0.0/frontengine/ui/page/web/web_setting_ui.py +0 -115
- frontengine-1.0.0/frontengine/user_setting/scene_setting.py +0 -70
- frontengine-1.0.0/frontengine/user_setting/user_setting_file.py +0 -37
- frontengine-1.0.0/frontengine/utils/json/json_file.py +0 -43
- frontengine-1.0.0/frontengine/utils/json_format/__init__.py +0 -1
- frontengine-1.0.0/frontengine/utils/multi_language/language_wrapper.py +0 -41
- frontengine-1.0.0/frontengine.egg-info/PKG-INFO +0 -73
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/gif/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/image/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/load/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/particle/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/scene/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/sound_player/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/text/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/video/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/show/web/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/system_tray/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/color/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/dialog/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/menu/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/control_center/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/gif/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/image/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/particle/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/scene_setting/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/scene_setting/scene_page/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/sound_player/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/text/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/video/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/ui/page/web/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/user_setting/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/browser/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/critical_exit/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine/utils/file/__init__.py +0 -0
- {frontengine-1.0.0/frontengine/utils/json → frontengine-1.0.1/frontengine/utils/hotkey}/__init__.py +0 -0
- {frontengine-1.0.0/frontengine/utils/logging → frontengine-1.0.1/frontengine/utils/json}/__init__.py +0 -0
- {frontengine-1.0.0/frontengine/utils/multi_language → frontengine-1.0.1/frontengine/utils/logging}/__init__.py +0 -0
- {frontengine-1.0.0/frontengine/utils/redirect_manager → frontengine-1.0.1/frontengine/utils/multi_language}/__init__.py +0 -0
- {frontengine-1.0.0/frontengine/worker → frontengine-1.0.1/frontengine/utils/preset_schedule}/__init__.py +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine.egg-info/dependency_links.txt +0 -0
- {frontengine-1.0.0 → frontengine-1.0.1}/frontengine.egg-info/top_level.txt +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2023 JE-Chen
|
|
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.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 JE-Chen
|
|
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,121 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: frontengine
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: FrontEngine is use-define frontview or only use like screen saver
|
|
5
|
+
Author-email: JE-Chen <jechenmailman@gmail.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/Intergration-Automation-Testing/FrontEngine
|
|
7
|
+
Project-URL: Code, https://github.com/Intergration-Automation-Testing/FrontEngine
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
9
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
10
|
+
Classifier: Environment :: Win32 (MS Windows)
|
|
11
|
+
Classifier: Environment :: MacOS X
|
|
12
|
+
Classifier: Environment :: X11 Applications
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: PySide6==6.10.2
|
|
18
|
+
Requires-Dist: qt-material
|
|
19
|
+
Requires-Dist: PyOpenGL
|
|
20
|
+
Requires-Dist: PyOpenGL_accelerate
|
|
21
|
+
Requires-Dist: numpy
|
|
22
|
+
Requires-Dist: pynput
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# FrontEngine
|
|
26
|
+
|
|
27
|
+
[Support this project on Steam](https://store.steampowered.com/app/2793470/FrontEngine/)
|
|
28
|
+
|
|
29
|
+
## About
|
|
30
|
+
|
|
31
|
+
FrontEngine is a lightweight and flexible framework designed to simplify automation and visualization tasks.
|
|
32
|
+
It provides an intuitive interface and supports multiple media formats for interactive demonstrations.
|
|
33
|
+
|
|
34
|
+

|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Features
|
|
39
|
+
|
|
40
|
+
- **GIFs & Animations**
|
|
41
|
+
*(GIFs may take time to load)*
|
|
42
|
+

|
|
43
|
+

|
|
44
|
+
|
|
45
|
+
- **Video**
|
|
46
|
+

|
|
47
|
+
|
|
48
|
+
- **Website**
|
|
49
|
+

|
|
50
|
+
|
|
51
|
+
- **YouTube Showcase**
|
|
52
|
+
[Watch on YouTube](https://youtu.be/fewogcb3b8Y)
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Install
|
|
57
|
+
|
|
58
|
+
- **System Requirements**
|
|
59
|
+
- Python **3.10+**
|
|
60
|
+
- Windows 10/11 is the primary target; macOS and Linux are supported but may need extra OS dependencies.
|
|
61
|
+
|
|
62
|
+
- **From PyPI**
|
|
63
|
+
```bash
|
|
64
|
+
pip install frontengine
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
- **Pre-built binaries**
|
|
68
|
+
- [GitHub Releases](https://github.com/Intergration-Automation-Testing/FrontEngine/releases)
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Development
|
|
73
|
+
|
|
74
|
+
- Requires **Python 3.10+**.
|
|
75
|
+
- Install the dev toolchain:
|
|
76
|
+
```bash
|
|
77
|
+
pip install -r dev_requirements.txt
|
|
78
|
+
pip install -e .
|
|
79
|
+
```
|
|
80
|
+
- Run the unit smoke tests:
|
|
81
|
+
```bash
|
|
82
|
+
python ./tests/unit_test/start/start_front_engine.py
|
|
83
|
+
python ./tests/unit_test/start/extend_front_engine.py
|
|
84
|
+
```
|
|
85
|
+
- Contributions and pull requests are welcome!
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Continuous Integration & Release
|
|
90
|
+
|
|
91
|
+
This repository ships two GitHub Actions workflows:
|
|
92
|
+
|
|
93
|
+
| Workflow | Trigger | Purpose |
|
|
94
|
+
|----------|---------|---------|
|
|
95
|
+
| `CI` (`.github/workflows/ci.yml`) | Push / PR to `main` or `dev`, daily cron | Matrix smoke test across Python 3.10 / 3.11 / 3.12 on Windows |
|
|
96
|
+
| `Release` (`.github/workflows/release.yml`) | A pull request is merged into `main` (or manual dispatch) | Auto-bumps the version in `stable.toml`/`pyproject.toml`, commits the bump back to `main`, swaps `stable.toml` → `pyproject.toml`, builds sdist + wheel, uploads to PyPI as `frontengine` via `twine`, creates a GitHub release tagged `v<version>` |
|
|
97
|
+
|
|
98
|
+
Publishing **only happens on merge to `main`** — pushing to `dev` runs CI but
|
|
99
|
+
never publishes. On merge, the workflow **automatically bumps the patch
|
|
100
|
+
segment** of the version (configurable via manual dispatch: `patch` / `minor`
|
|
101
|
+
/ `major`), commits the bump back to `main` with `[skip ci]`, then builds,
|
|
102
|
+
uploads, and releases under the new version. Both the PyPI upload and the
|
|
103
|
+
GitHub release see the bumped version, not the previous one.
|
|
104
|
+
|
|
105
|
+
### Cutting a new release
|
|
106
|
+
|
|
107
|
+
1. Merge a pull request into `main` — the patch version bumps automatically.
|
|
108
|
+
2. That's it. PyPI publish and GitHub release happen in one workflow run.
|
|
109
|
+
|
|
110
|
+
For a minor or major bump, trigger the workflow manually via *Actions →
|
|
111
|
+
Release → Run workflow* and pick the `bump` segment. That path also works
|
|
112
|
+
when you need to re-run a failed publish without a new merge.
|
|
113
|
+
|
|
114
|
+
### Required repository secrets
|
|
115
|
+
|
|
116
|
+
| Secret | Used by | Contents |
|
|
117
|
+
|--------|---------|----------|
|
|
118
|
+
| `PYPI_API_TOKEN` | `release.yml` | A PyPI API token scoped to the `frontengine` project |
|
|
119
|
+
|
|
120
|
+
The workflow uses `__token__` as the twine username, so only the token itself
|
|
121
|
+
needs to be stored.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# FrontEngine
|
|
2
|
+
|
|
3
|
+
[Support this project on Steam](https://store.steampowered.com/app/2793470/FrontEngine/)
|
|
4
|
+
|
|
5
|
+
## About
|
|
6
|
+
|
|
7
|
+
FrontEngine is a lightweight and flexible framework designed to simplify automation and visualization tasks.
|
|
8
|
+
It provides an intuitive interface and supports multiple media formats for interactive demonstrations.
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **GIFs & Animations**
|
|
17
|
+
*(GIFs may take time to load)*
|
|
18
|
+

|
|
19
|
+

|
|
20
|
+
|
|
21
|
+
- **Video**
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
- **Website**
|
|
25
|
+

|
|
26
|
+
|
|
27
|
+
- **YouTube Showcase**
|
|
28
|
+
[Watch on YouTube](https://youtu.be/fewogcb3b8Y)
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
- **System Requirements**
|
|
35
|
+
- Python **3.10+**
|
|
36
|
+
- Windows 10/11 is the primary target; macOS and Linux are supported but may need extra OS dependencies.
|
|
37
|
+
|
|
38
|
+
- **From PyPI**
|
|
39
|
+
```bash
|
|
40
|
+
pip install frontengine
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
- **Pre-built binaries**
|
|
44
|
+
- [GitHub Releases](https://github.com/Intergration-Automation-Testing/FrontEngine/releases)
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Development
|
|
49
|
+
|
|
50
|
+
- Requires **Python 3.10+**.
|
|
51
|
+
- Install the dev toolchain:
|
|
52
|
+
```bash
|
|
53
|
+
pip install -r dev_requirements.txt
|
|
54
|
+
pip install -e .
|
|
55
|
+
```
|
|
56
|
+
- Run the unit smoke tests:
|
|
57
|
+
```bash
|
|
58
|
+
python ./tests/unit_test/start/start_front_engine.py
|
|
59
|
+
python ./tests/unit_test/start/extend_front_engine.py
|
|
60
|
+
```
|
|
61
|
+
- Contributions and pull requests are welcome!
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Continuous Integration & Release
|
|
66
|
+
|
|
67
|
+
This repository ships two GitHub Actions workflows:
|
|
68
|
+
|
|
69
|
+
| Workflow | Trigger | Purpose |
|
|
70
|
+
|----------|---------|---------|
|
|
71
|
+
| `CI` (`.github/workflows/ci.yml`) | Push / PR to `main` or `dev`, daily cron | Matrix smoke test across Python 3.10 / 3.11 / 3.12 on Windows |
|
|
72
|
+
| `Release` (`.github/workflows/release.yml`) | A pull request is merged into `main` (or manual dispatch) | Auto-bumps the version in `stable.toml`/`pyproject.toml`, commits the bump back to `main`, swaps `stable.toml` → `pyproject.toml`, builds sdist + wheel, uploads to PyPI as `frontengine` via `twine`, creates a GitHub release tagged `v<version>` |
|
|
73
|
+
|
|
74
|
+
Publishing **only happens on merge to `main`** — pushing to `dev` runs CI but
|
|
75
|
+
never publishes. On merge, the workflow **automatically bumps the patch
|
|
76
|
+
segment** of the version (configurable via manual dispatch: `patch` / `minor`
|
|
77
|
+
/ `major`), commits the bump back to `main` with `[skip ci]`, then builds,
|
|
78
|
+
uploads, and releases under the new version. Both the PyPI upload and the
|
|
79
|
+
GitHub release see the bumped version, not the previous one.
|
|
80
|
+
|
|
81
|
+
### Cutting a new release
|
|
82
|
+
|
|
83
|
+
1. Merge a pull request into `main` — the patch version bumps automatically.
|
|
84
|
+
2. That's it. PyPI publish and GitHub release happen in one workflow run.
|
|
85
|
+
|
|
86
|
+
For a minor or major bump, trigger the workflow manually via *Actions →
|
|
87
|
+
Release → Run workflow* and pick the `bump` segment. That path also works
|
|
88
|
+
when you need to re-run a failed publish without a new merge.
|
|
89
|
+
|
|
90
|
+
### Required repository secrets
|
|
91
|
+
|
|
92
|
+
| Secret | Used by | Contents |
|
|
93
|
+
|--------|---------|----------|
|
|
94
|
+
| `PYPI_API_TOKEN` | `release.yml` | A PyPI API token scoped to the `frontengine` project |
|
|
95
|
+
|
|
96
|
+
The workflow uses `__token__` as the twine username, so only the token itself
|
|
97
|
+
needs to be stored.
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
from frontengine.show.gif.paint_gif import GifWidget
|
|
2
|
-
from frontengine.show.image.paint_image import ImageWidget
|
|
3
|
-
from frontengine.show.load.load_someone_make_ui import load_extend_ui_file
|
|
4
|
-
from frontengine.show.load.load_someone_make_ui import load_ui_file
|
|
5
|
-
from frontengine.show.sound_player.sound_effect import SoundEffectWidget
|
|
6
|
-
from frontengine.show.sound_player.sound_player import SoundPlayer
|
|
7
|
-
from frontengine.show.text.draw_text import TextWidget
|
|
8
|
-
from frontengine.show.video.video_player import VideoWidget
|
|
9
|
-
from frontengine.show.web.webview import WebWidget
|
|
10
|
-
from frontengine.ui.main_ui import start_front_engine
|
|
11
|
-
from frontengine.utils.multi_language.language_wrapper import language_wrapper
|
|
12
|
-
from frontengine.ui.page.text.text_setting_ui import TextSettingUI
|
|
13
|
-
from frontengine.ui.page.web.web_setting_ui import WEBSettingUI
|
|
14
|
-
from frontengine.ui.page.gif.gif_setting_ui import GIFSettingUI
|
|
15
|
-
from frontengine.ui.page.image.image_setting_ui import ImageSettingUI
|
|
16
|
-
from frontengine.ui.page.sound_player.sound_player_setting_ui import SoundPlayerSettingUI
|
|
17
|
-
from frontengine.ui.page.video.video_setting_ui import VideoSettingUI
|
|
18
|
-
from frontengine.ui.page.control_center.control_center_ui import ControlCenterUI
|
|
19
|
-
from frontengine.ui.page.scene_setting.scene_setting_ui import SceneSettingUI
|
|
20
|
-
from frontengine.ui.main_ui import FrontEngineMainUI
|
|
21
|
-
from frontengine.ui.main_ui import FrontEngine_EXTEND_TAB
|
|
22
|
-
from frontengine.utils.redirect_manager.redirect_manager_class import RedirectManager
|
|
23
|
-
|
|
24
|
-
__all__ = [
|
|
25
|
-
"start_front_engine", "GifWidget", "SoundPlayer", "SoundEffectWidget", "TextWidget",
|
|
26
|
-
"WebWidget", "ImageWidget", "VideoWidget", "language_wrapper", "load_extend_ui_file", "load_ui_file",
|
|
27
|
-
"TextSettingUI", "WEBSettingUI", "GIFSettingUI", "ImageSettingUI", "SoundPlayerSettingUI",
|
|
28
|
-
"VideoSettingUI", "ControlCenterUI", "SceneSettingUI", "FrontEngineMainUI",
|
|
29
|
-
"FrontEngine_EXTEND_TAB", "RedirectManager"
|
|
30
|
-
]
|
|
1
|
+
from frontengine.show.gif.paint_gif import GifWidget
|
|
2
|
+
from frontengine.show.image.paint_image import ImageWidget
|
|
3
|
+
from frontengine.show.load.load_someone_make_ui import load_extend_ui_file
|
|
4
|
+
from frontengine.show.load.load_someone_make_ui import load_ui_file
|
|
5
|
+
from frontengine.show.sound_player.sound_effect import SoundEffectWidget
|
|
6
|
+
from frontengine.show.sound_player.sound_player import SoundPlayer
|
|
7
|
+
from frontengine.show.text.draw_text import TextWidget
|
|
8
|
+
from frontengine.show.video.video_player import VideoWidget
|
|
9
|
+
from frontengine.show.web.webview import WebWidget
|
|
10
|
+
from frontengine.ui.main_ui import start_front_engine
|
|
11
|
+
from frontengine.utils.multi_language.language_wrapper import language_wrapper
|
|
12
|
+
from frontengine.ui.page.text.text_setting_ui import TextSettingUI
|
|
13
|
+
from frontengine.ui.page.web.web_setting_ui import WEBSettingUI
|
|
14
|
+
from frontengine.ui.page.gif.gif_setting_ui import GIFSettingUI
|
|
15
|
+
from frontengine.ui.page.image.image_setting_ui import ImageSettingUI
|
|
16
|
+
from frontengine.ui.page.sound_player.sound_player_setting_ui import SoundPlayerSettingUI
|
|
17
|
+
from frontengine.ui.page.video.video_setting_ui import VideoSettingUI
|
|
18
|
+
from frontengine.ui.page.control_center.control_center_ui import ControlCenterUI
|
|
19
|
+
from frontengine.ui.page.scene_setting.scene_setting_ui import SceneSettingUI
|
|
20
|
+
from frontengine.ui.main_ui import FrontEngineMainUI
|
|
21
|
+
from frontengine.ui.main_ui import FrontEngine_EXTEND_TAB
|
|
22
|
+
from frontengine.utils.redirect_manager.redirect_manager_class import RedirectManager
|
|
23
|
+
|
|
24
|
+
__all__ = [
|
|
25
|
+
"start_front_engine", "GifWidget", "SoundPlayer", "SoundEffectWidget", "TextWidget",
|
|
26
|
+
"WebWidget", "ImageWidget", "VideoWidget", "language_wrapper", "load_extend_ui_file", "load_ui_file",
|
|
27
|
+
"TextSettingUI", "WEBSettingUI", "GIFSettingUI", "ImageSettingUI", "SoundPlayerSettingUI",
|
|
28
|
+
"VideoSettingUI", "ControlCenterUI", "SceneSettingUI", "FrontEngineMainUI",
|
|
29
|
+
"FrontEngine_EXTEND_TAB", "RedirectManager"
|
|
30
|
+
]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
|
|
3
|
+
from PySide6.QtCore import Qt
|
|
4
|
+
from PySide6.QtGui import QPainter
|
|
5
|
+
from PySide6.QtWidgets import QWidget
|
|
6
|
+
|
|
7
|
+
from frontengine.show.window_helpers import apply_overlay_window_flags, load_overlay_icon
|
|
8
|
+
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class BaseWidget(QWidget):
|
|
12
|
+
"""
|
|
13
|
+
BaseWidget: 提供共用 UI 屬性與事件處理的基底類別
|
|
14
|
+
BaseWidget: Base class providing shared UI attributes and event handling
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, draw_location_x: int = 0, draw_location_y: int = 0):
|
|
18
|
+
super().__init__()
|
|
19
|
+
self.draw_location_x: int = draw_location_x
|
|
20
|
+
self.draw_location_y: int = draw_location_y
|
|
21
|
+
self.opacity: float = 0.2
|
|
22
|
+
|
|
23
|
+
self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
|
|
24
|
+
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
|
|
25
|
+
load_overlay_icon(self)
|
|
26
|
+
|
|
27
|
+
def set_ui_window_flag(self, show_on_bottom: bool = False) -> None:
|
|
28
|
+
front_engine_logger.info(f"{self.__class__.__name__} set_ui_window_flag | show_on_bottom: {show_on_bottom}")
|
|
29
|
+
apply_overlay_window_flags(self, show_on_bottom=show_on_bottom)
|
|
30
|
+
|
|
31
|
+
def set_ui_variable(self, opacity: float = 0.2) -> None:
|
|
32
|
+
front_engine_logger.info(f"{self.__class__.__name__} set_ui_variable | opacity: {opacity}")
|
|
33
|
+
self.opacity = opacity
|
|
34
|
+
|
|
35
|
+
def paintEvent(self, event) -> None:
|
|
36
|
+
front_engine_logger.debug(f"{self.__class__.__name__} paintEvent | event: {event}")
|
|
37
|
+
painter = QPainter(self)
|
|
38
|
+
painter.save()
|
|
39
|
+
painter.setOpacity(self.opacity)
|
|
40
|
+
try:
|
|
41
|
+
self.draw_content(painter)
|
|
42
|
+
finally:
|
|
43
|
+
painter.restore()
|
|
44
|
+
|
|
45
|
+
@abstractmethod
|
|
46
|
+
def draw_content(self, painter: QPainter) -> None:
|
|
47
|
+
"""Subclass hook that renders the widget content onto the shared painter."""
|
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
from PySide6.QtCore import QRect
|
|
4
|
-
from PySide6.QtGui import QPainter, QMovie
|
|
5
|
-
from PySide6.QtWidgets import QMessageBox, QLabel
|
|
6
|
-
|
|
7
|
-
from frontengine.show.base_widget import BaseWidget
|
|
8
|
-
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
9
|
-
from frontengine.utils.multi_language.language_wrapper import language_wrapper
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class GifWidget(BaseWidget):
|
|
13
|
-
"""
|
|
14
|
-
GifWidget: 顯示 GIF 動畫
|
|
15
|
-
GifWidget: Display animated GIF
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
def __init__(self, gif_image_path: str, draw_location_x: int = 0, draw_location_y: int = 0):
|
|
19
|
-
super().__init__(draw_location_x, draw_location_y)
|
|
20
|
-
self.speed: int = 100
|
|
21
|
-
self.gif_path: Path = Path(gif_image_path)
|
|
22
|
-
self.movie: QMovie = QMovie()
|
|
23
|
-
self.gif_label: QLabel = QLabel()
|
|
24
|
-
|
|
25
|
-
if self.gif_path.exists() and self.gif_path.is_file():
|
|
26
|
-
front_engine_logger.info(f"Loading GIF file: {self.gif_path}")
|
|
27
|
-
self.movie.setFileName(str(self.gif_path))
|
|
28
|
-
self.movie.frameChanged.connect(self.repaint)
|
|
29
|
-
self.gif_label.setMovie(self.movie)
|
|
30
|
-
self.movie.start()
|
|
31
|
-
self.resize(self.movie.frameRect().size())
|
|
32
|
-
else:
|
|
33
|
-
message_box: QMessageBox = QMessageBox(self)
|
|
34
|
-
message_box.setText(language_wrapper.language_word_dict.get("paint_gif_message_box_text"))
|
|
35
|
-
message_box.show()
|
|
36
|
-
|
|
37
|
-
def set_gif_variable(self, speed: int = 100) -> None:
|
|
38
|
-
front_engine_logger.info(f"GifWidget set_gif_variable | speed: {speed}")
|
|
39
|
-
self.speed = speed
|
|
40
|
-
self.movie.setSpeed(self.speed)
|
|
41
|
-
|
|
42
|
-
def draw_content(self, painter: QPainter) -> None:
|
|
43
|
-
current_gif_frame = self.movie.currentPixmap()
|
|
44
|
-
painter.drawPixmap(
|
|
45
|
-
QRect(self.draw_location_x, self.draw_location_y, self.width(), self.height()),
|
|
46
|
-
current_gif_frame
|
|
47
|
-
)
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from PySide6.QtCore import QRect
|
|
4
|
+
from PySide6.QtGui import QPainter, QMovie
|
|
5
|
+
from PySide6.QtWidgets import QMessageBox, QLabel
|
|
6
|
+
|
|
7
|
+
from frontengine.show.base_widget import BaseWidget
|
|
8
|
+
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
9
|
+
from frontengine.utils.multi_language.language_wrapper import language_wrapper
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class GifWidget(BaseWidget):
|
|
13
|
+
"""
|
|
14
|
+
GifWidget: 顯示 GIF 動畫
|
|
15
|
+
GifWidget: Display animated GIF
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, gif_image_path: str, draw_location_x: int = 0, draw_location_y: int = 0):
|
|
19
|
+
super().__init__(draw_location_x, draw_location_y)
|
|
20
|
+
self.speed: int = 100
|
|
21
|
+
self.gif_path: Path = Path(gif_image_path)
|
|
22
|
+
self.movie: QMovie = QMovie()
|
|
23
|
+
self.gif_label: QLabel = QLabel()
|
|
24
|
+
|
|
25
|
+
if self.gif_path.exists() and self.gif_path.is_file():
|
|
26
|
+
front_engine_logger.info(f"Loading GIF file: {self.gif_path}")
|
|
27
|
+
self.movie.setFileName(str(self.gif_path))
|
|
28
|
+
self.movie.frameChanged.connect(self.repaint)
|
|
29
|
+
self.gif_label.setMovie(self.movie)
|
|
30
|
+
self.movie.start()
|
|
31
|
+
self.resize(self.movie.frameRect().size())
|
|
32
|
+
else:
|
|
33
|
+
message_box: QMessageBox = QMessageBox(self)
|
|
34
|
+
message_box.setText(language_wrapper.language_word_dict.get("paint_gif_message_box_text"))
|
|
35
|
+
message_box.show()
|
|
36
|
+
|
|
37
|
+
def set_gif_variable(self, speed: int = 100) -> None:
|
|
38
|
+
front_engine_logger.info(f"GifWidget set_gif_variable | speed: {speed}")
|
|
39
|
+
self.speed = speed
|
|
40
|
+
self.movie.setSpeed(self.speed)
|
|
41
|
+
|
|
42
|
+
def draw_content(self, painter: QPainter) -> None:
|
|
43
|
+
current_gif_frame = self.movie.currentPixmap()
|
|
44
|
+
painter.drawPixmap(
|
|
45
|
+
QRect(self.draw_location_x, self.draw_location_y, self.width(), self.height()),
|
|
46
|
+
current_gif_frame
|
|
47
|
+
)
|
|
@@ -1,35 +1,51 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
from PySide6.QtCore import QRect
|
|
4
|
-
from PySide6.QtGui import QPainter, QImage
|
|
5
|
-
from PySide6.QtWidgets import QMessageBox
|
|
6
|
-
|
|
7
|
-
from frontengine.show.base_widget import BaseWidget
|
|
8
|
-
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
9
|
-
from frontengine.utils.multi_language.language_wrapper import language_wrapper
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ImageWidget(BaseWidget):
|
|
13
|
-
"""
|
|
14
|
-
ImageWidget: 顯示靜態圖片
|
|
15
|
-
ImageWidget: Display static image
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
def __init__(self, image_path: str, draw_location_x: int = 0, draw_location_y: int = 0):
|
|
19
|
-
super().__init__(draw_location_x, draw_location_y)
|
|
20
|
-
self.image_path: Path = Path(image_path)
|
|
21
|
-
|
|
22
|
-
if self.image_path.exists() and self.image_path.is_file():
|
|
23
|
-
front_engine_logger.info(f"Loading image file: {self.image_path}")
|
|
24
|
-
self.image: QImage = QImage(str(self.image_path))
|
|
25
|
-
self.resize(self.image.size())
|
|
26
|
-
else:
|
|
27
|
-
message_box: QMessageBox = QMessageBox(self)
|
|
28
|
-
message_box.setText(language_wrapper.language_word_dict.get("paint_image_message_box_text"))
|
|
29
|
-
message_box.show()
|
|
30
|
-
|
|
31
|
-
def
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from PySide6.QtCore import QRect
|
|
4
|
+
from PySide6.QtGui import QPainter, QImage
|
|
5
|
+
from PySide6.QtWidgets import QMessageBox
|
|
6
|
+
|
|
7
|
+
from frontengine.show.base_widget import BaseWidget
|
|
8
|
+
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
9
|
+
from frontengine.utils.multi_language.language_wrapper import language_wrapper
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ImageWidget(BaseWidget):
|
|
13
|
+
"""
|
|
14
|
+
ImageWidget: 顯示靜態圖片
|
|
15
|
+
ImageWidget: Display static image
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, image_path: str, draw_location_x: int = 0, draw_location_y: int = 0):
|
|
19
|
+
super().__init__(draw_location_x, draw_location_y)
|
|
20
|
+
self.image_path: Path = Path(image_path)
|
|
21
|
+
|
|
22
|
+
if self.image_path.exists() and self.image_path.is_file():
|
|
23
|
+
front_engine_logger.info(f"Loading image file: {self.image_path}")
|
|
24
|
+
self.image: QImage = QImage(str(self.image_path))
|
|
25
|
+
self.resize(self.image.size())
|
|
26
|
+
else:
|
|
27
|
+
message_box: QMessageBox = QMessageBox(self)
|
|
28
|
+
message_box.setText(language_wrapper.language_word_dict.get("paint_image_message_box_text"))
|
|
29
|
+
message_box.show()
|
|
30
|
+
|
|
31
|
+
def set_image_path(self, image_path: str) -> bool:
|
|
32
|
+
"""
|
|
33
|
+
熱換顯示的圖片(用於輪播)。路徑無效時保持原圖並回傳 False。
|
|
34
|
+
Hot-swap the displayed image (used by the slideshow). Keeps the
|
|
35
|
+
current image and returns False when the path is invalid.
|
|
36
|
+
"""
|
|
37
|
+
path = Path(image_path)
|
|
38
|
+
if not (path.exists() and path.is_file()):
|
|
39
|
+
front_engine_logger.warning(f"[ImageWidget] set_image_path skip invalid: {path}")
|
|
40
|
+
return False
|
|
41
|
+
self.image_path = path
|
|
42
|
+
self.image = QImage(str(path))
|
|
43
|
+
self.resize(self.image.size())
|
|
44
|
+
self.update()
|
|
45
|
+
return True
|
|
46
|
+
|
|
47
|
+
def draw_content(self, painter: QPainter) -> None:
|
|
48
|
+
painter.drawImage(
|
|
49
|
+
QRect(self.draw_location_x, self.draw_location_y, self.width(), self.height()),
|
|
50
|
+
self.image
|
|
51
|
+
)
|