frontengine-dev 0.0.89__tar.gz → 0.0.92__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_dev-0.0.89 → frontengine_dev-0.0.92}/PKG-INFO +2 -2
- frontengine_dev-0.0.92/frontengine/show/base_widget.py +83 -0
- frontengine_dev-0.0.92/frontengine/show/gif/paint_gif.py +47 -0
- frontengine_dev-0.0.92/frontengine/show/image/paint_image.py +35 -0
- frontengine_dev-0.0.92/frontengine/show/load/load_someone_make_ui.py +68 -0
- frontengine_dev-0.0.92/frontengine/show/particle/particle_scene.py +134 -0
- frontengine_dev-0.0.92/frontengine/show/particle/particle_ui.py +80 -0
- frontengine_dev-0.0.92/frontengine/show/particle/particle_utils.py +120 -0
- frontengine_dev-0.0.92/frontengine/show/scene/extend_graphic_scene.py +32 -0
- frontengine_dev-0.0.92/frontengine/show/scene/extend_graphic_view.py +78 -0
- frontengine_dev-0.0.92/frontengine/show/scene/scene.py +120 -0
- frontengine_dev-0.0.92/frontengine/show/sound_player/sound_effect.py +82 -0
- frontengine_dev-0.0.92/frontengine/show/sound_player/sound_player.py +88 -0
- frontengine_dev-0.0.92/frontengine/show/text/draw_text.py +131 -0
- frontengine_dev-0.0.92/frontengine/show/video/video_player.py +130 -0
- frontengine_dev-0.0.92/frontengine/show/web/webview.py +108 -0
- frontengine_dev-0.0.92/frontengine/system_tray/extend_system_tray.py +77 -0
- frontengine_dev-0.0.92/frontengine/ui/dialog/choose_file_dialog.py +95 -0
- frontengine_dev-0.0.92/frontengine/ui/dialog/save_file_dialog.py +26 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/main_ui.py +101 -50
- frontengine_dev-0.0.92/frontengine/ui/menu/help_menu.py +61 -0
- frontengine_dev-0.0.92/frontengine/ui/menu/how_to_menu.py +44 -0
- frontengine_dev-0.0.92/frontengine/ui/menu/language_menu.py +57 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/page/control_center/control_center_ui.py +45 -75
- frontengine_dev-0.0.92/frontengine/ui/page/gif/gif_setting_ui.py +132 -0
- frontengine_dev-0.0.92/frontengine/ui/page/image/image_setting_ui.py +116 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/page/particle/particle_setting_ui.py +76 -83
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/page/scene_setting/scene_manager.py +48 -29
- frontengine_dev-0.0.92/frontengine/ui/page/scene_setting/scene_page/gif.py +87 -0
- frontengine_dev-0.0.92/frontengine/ui/page/scene_setting/scene_page/image.py +72 -0
- frontengine_dev-0.0.92/frontengine/ui/page/scene_setting/scene_page/sound.py +77 -0
- frontengine_dev-0.0.92/frontengine/ui/page/scene_setting/scene_page/text.py +80 -0
- frontengine_dev-0.0.92/frontengine/ui/page/scene_setting/scene_page/video.py +107 -0
- frontengine_dev-0.0.92/frontengine/ui/page/scene_setting/scene_page/web.py +58 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/page/scene_setting/scene_setting_ui.py +27 -26
- frontengine_dev-0.0.92/frontengine/ui/page/sound_player/sound_player_setting_ui.py +111 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/page/text/text_setting_ui.py +50 -55
- frontengine_dev-0.0.92/frontengine/ui/page/utils.py +84 -0
- frontengine_dev-0.0.92/frontengine/ui/page/video/video_setting_ui.py +156 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/page/web/web_setting_ui.py +43 -48
- frontengine_dev-0.0.92/frontengine/user_setting/scene_setting.py +70 -0
- frontengine_dev-0.0.92/frontengine/user_setting/user_setting_file.py +37 -0
- frontengine_dev-0.0.92/frontengine/utils/browser/browser.py +21 -0
- frontengine_dev-0.0.92/frontengine/utils/critical_exit/check_key_is_press.py +28 -0
- frontengine_dev-0.0.92/frontengine/utils/critical_exit/critical_exit.py +62 -0
- frontengine_dev-0.0.92/frontengine/utils/file/open/open_file.py +36 -0
- frontengine_dev-0.0.92/frontengine/utils/file/save/save_file.py +33 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/json/json_file.py +2 -2
- frontengine_dev-0.0.92/frontengine/utils/json_format/json_process.py +42 -0
- frontengine_dev-0.0.92/frontengine/utils/logging/loggin_instance.py +46 -0
- frontengine_dev-0.0.92/frontengine/utils/redirect_manager/redirect_manager_class.py +85 -0
- frontengine_dev-0.0.92/frontengine/worker/qthread_worker.py +60 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine_dev.egg-info/PKG-INFO +2 -2
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine_dev.egg-info/SOURCES.txt +1 -3
- frontengine_dev-0.0.92/frontengine_dev.egg-info/requires.txt +2 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/pyproject.toml +2 -2
- frontengine_dev-0.0.89/frontengine/show/clicker/clicker_scene.py +0 -10
- frontengine_dev-0.0.89/frontengine/show/clicker/clicker_ui.py +0 -33
- frontengine_dev-0.0.89/frontengine/show/gif/paint_gif.py +0 -93
- frontengine_dev-0.0.89/frontengine/show/image/paint_image.py +0 -76
- frontengine_dev-0.0.89/frontengine/show/load/load_someone_make_ui.py +0 -43
- frontengine_dev-0.0.89/frontengine/show/particle/particle_scene.py +0 -82
- frontengine_dev-0.0.89/frontengine/show/particle/particle_ui.py +0 -51
- frontengine_dev-0.0.89/frontengine/show/particle/particle_utils.py +0 -96
- frontengine_dev-0.0.89/frontengine/show/scene/extend_graphic_scene.py +0 -10
- frontengine_dev-0.0.89/frontengine/show/scene/extend_graphic_view.py +0 -53
- frontengine_dev-0.0.89/frontengine/show/scene/scene.py +0 -104
- frontengine_dev-0.0.89/frontengine/show/sound_player/sound_effect.py +0 -56
- frontengine_dev-0.0.89/frontengine/show/sound_player/sound_player.py +0 -57
- frontengine_dev-0.0.89/frontengine/show/text/draw_text.py +0 -106
- frontengine_dev-0.0.89/frontengine/show/video/video_player.py +0 -96
- frontengine_dev-0.0.89/frontengine/show/web/webview.py +0 -90
- frontengine_dev-0.0.89/frontengine/system_tray/extend_system_tray.py +0 -44
- frontengine_dev-0.0.89/frontengine/ui/dialog/choose_file_dialog.py +0 -95
- frontengine_dev-0.0.89/frontengine/ui/dialog/save_file_dialog.py +0 -19
- frontengine_dev-0.0.89/frontengine/ui/menu/help_menu.py +0 -48
- frontengine_dev-0.0.89/frontengine/ui/menu/how_to_menu.py +0 -27
- frontengine_dev-0.0.89/frontengine/ui/menu/language_menu.py +0 -94
- frontengine_dev-0.0.89/frontengine/ui/page/gif/gif_setting_ui.py +0 -155
- frontengine_dev-0.0.89/frontengine/ui/page/image/image_setting_ui.py +0 -137
- frontengine_dev-0.0.89/frontengine/ui/page/scene_setting/scene_page/gif.py +0 -108
- frontengine_dev-0.0.89/frontengine/ui/page/scene_setting/scene_page/image.py +0 -88
- frontengine_dev-0.0.89/frontengine/ui/page/scene_setting/scene_page/sound.py +0 -89
- frontengine_dev-0.0.89/frontengine/ui/page/scene_setting/scene_page/text.py +0 -98
- frontengine_dev-0.0.89/frontengine/ui/page/scene_setting/scene_page/video.py +0 -122
- frontengine_dev-0.0.89/frontengine/ui/page/scene_setting/scene_page/web.py +0 -66
- frontengine_dev-0.0.89/frontengine/ui/page/sound_player/sound_player_setting_ui.py +0 -126
- frontengine_dev-0.0.89/frontengine/ui/page/utils.py +0 -43
- frontengine_dev-0.0.89/frontengine/ui/page/video/video_setting_ui.py +0 -170
- frontengine_dev-0.0.89/frontengine/user_setting/scene_setting.py +0 -34
- frontengine_dev-0.0.89/frontengine/user_setting/user_setting_file.py +0 -21
- frontengine_dev-0.0.89/frontengine/utils/browser/browser.py +0 -5
- frontengine_dev-0.0.89/frontengine/utils/critical_exit/check_key_is_press.py +0 -11
- frontengine_dev-0.0.89/frontengine/utils/critical_exit/critical_exit.py +0 -52
- frontengine_dev-0.0.89/frontengine/utils/file/open/open_file.py +0 -35
- frontengine_dev-0.0.89/frontengine/utils/file/save/save_file.py +0 -28
- frontengine_dev-0.0.89/frontengine/utils/json_format/json_process.py +0 -28
- frontengine_dev-0.0.89/frontengine/utils/logging/loggin_instance.py +0 -26
- frontengine_dev-0.0.89/frontengine/utils/redirect_manager/redirect_manager_class.py +0 -74
- frontengine_dev-0.0.89/frontengine/worker/__init__.py +0 -0
- frontengine_dev-0.0.89/frontengine/worker/qthread_worker.py +0 -34
- frontengine_dev-0.0.89/frontengine_dev.egg-info/requires.txt +0 -2
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/LICENSE +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/README.md +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/__init__.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/show/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/show/clicker → frontengine_dev-0.0.92/frontengine/show/gif}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/show/gif → frontengine_dev-0.0.92/frontengine/show/image}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/show/image → frontengine_dev-0.0.92/frontengine/show/load}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/show/load → frontengine_dev-0.0.92/frontengine/show/particle}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/show/particle → frontengine_dev-0.0.92/frontengine/show/scene}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/show/scene → frontengine_dev-0.0.92/frontengine/show/sound_player}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/show/sound_player → frontengine_dev-0.0.92/frontengine/show/text}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/show/text → frontengine_dev-0.0.92/frontengine/show/video}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/show/video → frontengine_dev-0.0.92/frontengine/show/web}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/show/web → frontengine_dev-0.0.92/frontengine/system_tray}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/system_tray → frontengine_dev-0.0.92/frontengine/ui}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui → frontengine_dev-0.0.92/frontengine/ui/color}/__init__.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/color/global_color.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui/color → frontengine_dev-0.0.92/frontengine/ui/dialog}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui/dialog → frontengine_dev-0.0.92/frontengine/ui/menu}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui/menu → frontengine_dev-0.0.92/frontengine/ui/page}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui/page → frontengine_dev-0.0.92/frontengine/ui/page/control_center}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui/page/control_center → frontengine_dev-0.0.92/frontengine/ui/page/gif}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui/page/gif → frontengine_dev-0.0.92/frontengine/ui/page/image}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui/page/image → frontengine_dev-0.0.92/frontengine/ui/page/particle}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui/page/particle → frontengine_dev-0.0.92/frontengine/ui/page/scene_setting}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui/page/scene_setting → frontengine_dev-0.0.92/frontengine/ui/page/scene_setting/scene_page}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui/page/scene_setting/scene_page → frontengine_dev-0.0.92/frontengine/ui/page/sound_player}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui/page/sound_player → frontengine_dev-0.0.92/frontengine/ui/page/text}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui/page/text → frontengine_dev-0.0.92/frontengine/ui/page/video}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui/page/video → frontengine_dev-0.0.92/frontengine/ui/page/web}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/ui/page/web → frontengine_dev-0.0.92/frontengine/user_setting}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/user_setting → frontengine_dev-0.0.92/frontengine/utils}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/utils → frontengine_dev-0.0.92/frontengine/utils/browser}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/utils/browser → frontengine_dev-0.0.92/frontengine/utils/critical_exit}/__init__.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/critical_exit/win32_vk.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/exception/__init__.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/exception/exception_tags.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/exception/exceptions.py +0 -0
- {frontengine_dev-0.0.89/frontengine/utils/critical_exit → frontengine_dev-0.0.92/frontengine/utils/file}/__init__.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/file/open/__init__.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/file/save/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/utils/file → frontengine_dev-0.0.92/frontengine/utils/json}/__init__.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/json_format/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/utils/json → frontengine_dev-0.0.92/frontengine/utils/logging}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/utils/logging → frontengine_dev-0.0.92/frontengine/utils/multi_language}/__init__.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/english.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/france.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/germany.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/italy.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/language_wrapper.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/russian.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/simplified_chinese.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/traditional_chinese.py +0 -0
- {frontengine_dev-0.0.89/frontengine/utils/multi_language → frontengine_dev-0.0.92/frontengine/utils/redirect_manager}/__init__.py +0 -0
- {frontengine_dev-0.0.89/frontengine/utils/redirect_manager → frontengine_dev-0.0.92/frontengine/worker}/__init__.py +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine_dev.egg-info/dependency_links.txt +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine_dev.egg-info/top_level.txt +0 -0
- {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: frontengine_dev
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.92
|
|
4
4
|
Summary: FrontEngine is use-define frontview or only use like screen saver
|
|
5
5
|
Author-email: JE-Chen <jechenmailman@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/Intergration-Automation-Testing/FrontEngine
|
|
@@ -14,7 +14,7 @@ Classifier: Operating System :: OS Independent
|
|
|
14
14
|
Requires-Python: >=3.10
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
|
-
Requires-Dist: PySide6==6.
|
|
17
|
+
Requires-Dist: PySide6==6.10.0
|
|
18
18
|
Requires-Dist: qt-material
|
|
19
19
|
Dynamic: license-file
|
|
20
20
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from abc import abstractmethod
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from PySide6.QtCore import Qt
|
|
6
|
+
from PySide6.QtGui import QPainter, QIcon
|
|
7
|
+
from PySide6.QtWidgets import QWidget
|
|
8
|
+
|
|
9
|
+
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BaseWidget(QWidget):
|
|
13
|
+
"""
|
|
14
|
+
BaseWidget: 提供共用 UI 屬性與事件處理的基底類別
|
|
15
|
+
BaseWidget: Base class providing shared UI attributes and event handling
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, draw_location_x: int = 0, draw_location_y: int = 0):
|
|
19
|
+
super().__init__()
|
|
20
|
+
self.draw_location_x: int = draw_location_x
|
|
21
|
+
self.draw_location_y: int = draw_location_y
|
|
22
|
+
self.opacity: float = 0.2
|
|
23
|
+
|
|
24
|
+
# 設定視窗屬性 / Set widget attributes
|
|
25
|
+
self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
|
|
26
|
+
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
|
|
27
|
+
|
|
28
|
+
# 設定視窗 Icon / Set window icon
|
|
29
|
+
self.icon_path: Path = Path(os.getcwd()) / "je_driver_icon.ico"
|
|
30
|
+
if self.icon_path.exists() and self.icon_path.is_file():
|
|
31
|
+
self.setWindowIcon(QIcon(str(self.icon_path)))
|
|
32
|
+
|
|
33
|
+
def set_ui_window_flag(self, show_on_bottom: bool = False) -> None:
|
|
34
|
+
"""
|
|
35
|
+
設定視窗旗標 (保持最上層或最下層)
|
|
36
|
+
Set window flags (stay on top or bottom)
|
|
37
|
+
"""
|
|
38
|
+
front_engine_logger.info(f"{self.__class__.__name__} set_ui_window_flag | show_on_bottom: {show_on_bottom}")
|
|
39
|
+
self.setWindowFlag(
|
|
40
|
+
Qt.WindowType.WindowTransparentForInput |
|
|
41
|
+
Qt.WindowType.FramelessWindowHint |
|
|
42
|
+
Qt.WindowType.Tool
|
|
43
|
+
)
|
|
44
|
+
if not show_on_bottom:
|
|
45
|
+
self.setWindowFlag(Qt.WindowType.WindowStaysOnTopHint)
|
|
46
|
+
else:
|
|
47
|
+
self.setWindowFlag(Qt.WindowType.WindowStaysOnBottomHint)
|
|
48
|
+
|
|
49
|
+
def set_ui_variable(self, opacity: float = 0.2) -> None:
|
|
50
|
+
"""
|
|
51
|
+
設定 UI 透明度
|
|
52
|
+
Set UI opacity
|
|
53
|
+
"""
|
|
54
|
+
front_engine_logger.info(f"{self.__class__.__name__} set_ui_variable | opacity: {opacity}")
|
|
55
|
+
self.opacity = opacity
|
|
56
|
+
|
|
57
|
+
def paintEvent(self, event) -> None:
|
|
58
|
+
"""
|
|
59
|
+
呼叫子類別的繪製方法
|
|
60
|
+
Call subclass draw_content method
|
|
61
|
+
"""
|
|
62
|
+
front_engine_logger.debug(f"{self.__class__.__name__} paintEvent | event: {event}")
|
|
63
|
+
painter = QPainter(self)
|
|
64
|
+
painter.setOpacity(self.opacity)
|
|
65
|
+
self.draw_content(painter)
|
|
66
|
+
painter.restore()
|
|
67
|
+
|
|
68
|
+
@abstractmethod
|
|
69
|
+
def draw_content(self, painter: QPainter) -> None:
|
|
70
|
+
"""
|
|
71
|
+
子類別必須實作的繪製方法
|
|
72
|
+
Subclasses must implement this drawing method
|
|
73
|
+
"""
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
# --- 共用滑鼠事件 / Shared mouse events ---
|
|
77
|
+
def mousePressEvent(self, event) -> None:
|
|
78
|
+
front_engine_logger.debug(f"{self.__class__.__name__} mousePressEvent | event: {event}")
|
|
79
|
+
super().mousePressEvent(event)
|
|
80
|
+
|
|
81
|
+
def mouseDoubleClickEvent(self, event) -> None:
|
|
82
|
+
front_engine_logger.debug(f"{self.__class__.__name__} mouseDoubleClickEvent | event: {event}")
|
|
83
|
+
super().mouseDoubleClickEvent(event)
|
|
@@ -0,0 +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
|
+
)
|
|
@@ -0,0 +1,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 draw_content(self, painter: QPainter) -> None:
|
|
32
|
+
painter.drawImage(
|
|
33
|
+
QRect(self.draw_location_x, self.draw_location_y, self.width(), self.height()),
|
|
34
|
+
self.image
|
|
35
|
+
)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from typing import Optional, List
|
|
2
|
+
|
|
3
|
+
from PySide6.QtGui import QScreen
|
|
4
|
+
from PySide6.QtUiTools import QUiLoader
|
|
5
|
+
from PySide6.QtWidgets import QWidget
|
|
6
|
+
|
|
7
|
+
from frontengine.utils.exception.exceptions import FrontEngineLoadUIException
|
|
8
|
+
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def load_extend_ui_file(ui_path: str, show_all_screen: bool = False) -> None:
|
|
12
|
+
"""
|
|
13
|
+
載入並顯示 UI 檔案
|
|
14
|
+
Load and display a UI file
|
|
15
|
+
|
|
16
|
+
:param ui_path: UI 檔案路徑 / Path to the UI file
|
|
17
|
+
:param show_all_screen: 是否顯示在所有螢幕上 / Show on all screens
|
|
18
|
+
"""
|
|
19
|
+
front_engine_logger.info(
|
|
20
|
+
f"[load_extend_ui_file] ui_path={ui_path}, show_all_screen={show_all_screen}"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
ui: QWidget = load_ui_file(ui_path)
|
|
24
|
+
|
|
25
|
+
if show_all_screen:
|
|
26
|
+
ui.showFullScreen()
|
|
27
|
+
else:
|
|
28
|
+
# 取得所有螢幕並在每個螢幕上顯示 UI
|
|
29
|
+
# Get all monitors and display UI on each
|
|
30
|
+
monitors: List[QScreen] = QScreen.virtualSiblings(ui.screen())
|
|
31
|
+
for screen in monitors:
|
|
32
|
+
monitor_geometry = screen.availableGeometry()
|
|
33
|
+
ui.move(monitor_geometry.left(), monitor_geometry.top())
|
|
34
|
+
ui.showFullScreen()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def load_ui_file(ui_path: str) -> QWidget:
|
|
38
|
+
"""
|
|
39
|
+
載入 UI 檔案
|
|
40
|
+
Load a UI file
|
|
41
|
+
|
|
42
|
+
:param ui_path: UI 檔案路徑 / Path to the UI file
|
|
43
|
+
:return: QWidget 物件 / QWidget object
|
|
44
|
+
:raises FrontEngineLoadUIException: 若載入失敗 / If loading fails
|
|
45
|
+
"""
|
|
46
|
+
front_engine_logger.info(f"[load_ui_file] ui_path={ui_path}")
|
|
47
|
+
ui: QWidget = QUiLoader().load(ui_path)
|
|
48
|
+
|
|
49
|
+
if not ui:
|
|
50
|
+
front_engine_logger.error(f"[load_ui_file] Failed to load UI: {ui_path}")
|
|
51
|
+
raise FrontEngineLoadUIException(f"Failed to load UI file: {ui_path}")
|
|
52
|
+
|
|
53
|
+
return ui
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def read_extend_ui(ui: QWidget) -> Optional[QWidget]:
|
|
57
|
+
"""
|
|
58
|
+
驗證並回傳 UI 物件
|
|
59
|
+
Validate and return UI object
|
|
60
|
+
|
|
61
|
+
:param ui: QWidget 物件 / QWidget object
|
|
62
|
+
:return: QWidget 或 None / QWidget or None
|
|
63
|
+
"""
|
|
64
|
+
front_engine_logger.info(f"[read_extend_ui] ui={ui}")
|
|
65
|
+
|
|
66
|
+
if not isinstance(ui, QWidget):
|
|
67
|
+
return None
|
|
68
|
+
return ui
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import random
|
|
2
|
+
from typing import Callable, Dict, Any
|
|
3
|
+
|
|
4
|
+
from PySide6.QtCore import QTimer, QPoint, QRect
|
|
5
|
+
from PySide6.QtGui import QPixmap
|
|
6
|
+
from PySide6.QtWidgets import QGraphicsScene
|
|
7
|
+
|
|
8
|
+
from frontengine.show.particle.particle_utils import (
|
|
9
|
+
particle_down, particle_up, particle_left, particle_right,
|
|
10
|
+
particle_left_down, particle_left_up, particle_right_down, particle_right_up,
|
|
11
|
+
particle_random_minus, particle_random_add, particle_random
|
|
12
|
+
)
|
|
13
|
+
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ParticleGraphicScene(QGraphicsScene):
|
|
17
|
+
"""
|
|
18
|
+
粒子特效場景,用於顯示粒子動畫
|
|
19
|
+
ParticleGraphicScene: A QGraphicsScene subclass for particle animation
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self,
|
|
23
|
+
particle_pixmap: QPixmap,
|
|
24
|
+
particle_direction: str,
|
|
25
|
+
particle_count: int = 500,
|
|
26
|
+
screen_height: int = 1920,
|
|
27
|
+
screen_width: int = 1080,
|
|
28
|
+
opacity: float = 0.2,
|
|
29
|
+
particle_speed: int = 1):
|
|
30
|
+
"""
|
|
31
|
+
初始化粒子場景
|
|
32
|
+
Initialize particle scene
|
|
33
|
+
|
|
34
|
+
:param particle_pixmap: 粒子圖片 / Particle pixmap
|
|
35
|
+
:param particle_direction: 粒子移動方向 / Particle movement direction
|
|
36
|
+
:param particle_count: 粒子數量 / Number of particles
|
|
37
|
+
:param screen_height: 畫布高度 / Screen height
|
|
38
|
+
:param screen_width: 畫布寬度 / Screen width
|
|
39
|
+
:param opacity: 粒子透明度 / Particle opacity
|
|
40
|
+
:param particle_speed: 粒子移動速度 / Particle speed
|
|
41
|
+
"""
|
|
42
|
+
front_engine_logger.info(
|
|
43
|
+
f"Init ParticleGraphicScene | "
|
|
44
|
+
f"particle_direction={particle_direction}, "
|
|
45
|
+
f"particle_count={particle_count}, "
|
|
46
|
+
f"screen_height={screen_height}, screen_width={screen_width}, "
|
|
47
|
+
f"opacity={opacity}, particle_speed={particle_speed}"
|
|
48
|
+
)
|
|
49
|
+
super().__init__()
|
|
50
|
+
|
|
51
|
+
# --- 基本屬性 / Basic attributes ---
|
|
52
|
+
self.particle_pixmap: QPixmap = particle_pixmap
|
|
53
|
+
self.particle_direction: str = particle_direction
|
|
54
|
+
self.particle_count: int = particle_count
|
|
55
|
+
self.opacity: float = opacity
|
|
56
|
+
self.particle_speed: int = particle_speed
|
|
57
|
+
self.screen_height: int = screen_height
|
|
58
|
+
self.screen_width: int = screen_width
|
|
59
|
+
|
|
60
|
+
# 儲存粒子資訊的字典 / Dictionary to store particle info
|
|
61
|
+
self.particle_dict: Dict[str, Dict[str, Any]] = {}
|
|
62
|
+
|
|
63
|
+
# 建立粒子 / Create particles
|
|
64
|
+
self.create_particle()
|
|
65
|
+
|
|
66
|
+
# 設定更新函式 / Set update function
|
|
67
|
+
self.update_function: Callable = {
|
|
68
|
+
"down": particle_down,
|
|
69
|
+
"up": particle_up,
|
|
70
|
+
"left": particle_left,
|
|
71
|
+
"right": particle_right,
|
|
72
|
+
"left_down": particle_left_down,
|
|
73
|
+
"left_up": particle_left_up,
|
|
74
|
+
"right_down": particle_right_down,
|
|
75
|
+
"right_up": particle_right_up,
|
|
76
|
+
"random_minus": particle_random_minus,
|
|
77
|
+
"random_add": particle_random_add,
|
|
78
|
+
"random": particle_random
|
|
79
|
+
}.get(self.particle_direction)
|
|
80
|
+
|
|
81
|
+
if not self.update_function:
|
|
82
|
+
front_engine_logger.error(f"Invalid particle direction: {self.particle_direction}")
|
|
83
|
+
raise ValueError(f"Unsupported particle direction: {self.particle_direction}")
|
|
84
|
+
|
|
85
|
+
# 設定場景大小 / Set scene size
|
|
86
|
+
self.setSceneRect(QRect(0, 0, screen_width, screen_height))
|
|
87
|
+
|
|
88
|
+
# 啟動定時器 / Start update timer
|
|
89
|
+
self.update_timer: QTimer = QTimer()
|
|
90
|
+
self.update_timer.setInterval(100) # 更新間隔 (毫秒) / Update interval (ms)
|
|
91
|
+
self.update_timer.timeout.connect(self.update_particle_xy)
|
|
92
|
+
self.update_timer.start()
|
|
93
|
+
|
|
94
|
+
def create_particle(self) -> None:
|
|
95
|
+
"""
|
|
96
|
+
建立粒子並隨機分布在場景中
|
|
97
|
+
Create particles and randomly distribute them in the scene
|
|
98
|
+
"""
|
|
99
|
+
front_engine_logger.info("ParticleGraphicScene create_particle")
|
|
100
|
+
self.particle_dict.clear()
|
|
101
|
+
|
|
102
|
+
for count in range(self.particle_count):
|
|
103
|
+
item = self.addPixmap(self.particle_pixmap)
|
|
104
|
+
item.setOpacity(self.opacity)
|
|
105
|
+
self.particle_dict[f"particle_{count}"] = {
|
|
106
|
+
"x": random.randint(0, self.screen_width),
|
|
107
|
+
"y": random.randint(0, self.screen_height),
|
|
108
|
+
"height": self.screen_height,
|
|
109
|
+
"width": self.screen_width,
|
|
110
|
+
"pixmap_item": item,
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
def update_particle_xy(self) -> None:
|
|
114
|
+
"""
|
|
115
|
+
更新粒子座標並重新繪製
|
|
116
|
+
Update particle positions and redraw
|
|
117
|
+
"""
|
|
118
|
+
front_engine_logger.debug("ParticleGraphicScene update_particle_xy")
|
|
119
|
+
|
|
120
|
+
# 更新粒子座標 / Update particle positions
|
|
121
|
+
self.update_function(self.particle_dict, self.particle_speed)
|
|
122
|
+
|
|
123
|
+
# 更新場景中的粒子位置 / Update positions in scene
|
|
124
|
+
for particle in self.particle_dict.values():
|
|
125
|
+
pixmap_item = particle["pixmap_item"]
|
|
126
|
+
pixmap_item.setPos(particle["x"], particle["y"])
|
|
127
|
+
|
|
128
|
+
# 如果粒子超出場景範圍,移除它 / Remove particle if out of bounds
|
|
129
|
+
if not self.sceneRect().contains(QPoint(particle["x"], particle["y"])):
|
|
130
|
+
self.removeItem(pixmap_item)
|
|
131
|
+
|
|
132
|
+
# 如果場景中沒有粒子,重新建立 / Recreate particles if all removed
|
|
133
|
+
if not self.items():
|
|
134
|
+
self.create_particle()
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
from PySide6.QtCore import QSize
|
|
2
|
+
from PySide6.QtGui import QPixmap, Qt
|
|
3
|
+
from PySide6.QtWidgets import QWidget, QGridLayout
|
|
4
|
+
|
|
5
|
+
from frontengine.show.particle.particle_scene import ParticleGraphicScene
|
|
6
|
+
from frontengine.show.scene.extend_graphic_view import ExtendGraphicView
|
|
7
|
+
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ParticleWidget(QWidget):
|
|
11
|
+
"""
|
|
12
|
+
粒子特效顯示元件
|
|
13
|
+
ParticleWidget: A QWidget wrapper for displaying particle effects
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self,
|
|
17
|
+
pixmap: QPixmap,
|
|
18
|
+
particle_size: int,
|
|
19
|
+
particle_direction: str,
|
|
20
|
+
particle_count: int = 50,
|
|
21
|
+
screen_height: int = 1080,
|
|
22
|
+
screen_width: int = 1920,
|
|
23
|
+
opacity: float = 0.2,
|
|
24
|
+
particle_speed: int = 1):
|
|
25
|
+
"""
|
|
26
|
+
初始化粒子元件
|
|
27
|
+
Initialize particle widget
|
|
28
|
+
|
|
29
|
+
:param pixmap: 粒子圖片 / Particle pixmap
|
|
30
|
+
:param particle_size: 粒子大小 / Particle size
|
|
31
|
+
:param particle_direction: 粒子方向 / Particle direction
|
|
32
|
+
:param particle_count: 粒子數量 / Number of particles
|
|
33
|
+
:param screen_height: 畫布高度 / Screen height
|
|
34
|
+
:param screen_width: 畫布寬度 / Screen width
|
|
35
|
+
:param opacity: 粒子透明度 / Particle opacity
|
|
36
|
+
:param particle_speed: 粒子速度 / Particle speed
|
|
37
|
+
"""
|
|
38
|
+
front_engine_logger.info(
|
|
39
|
+
f"[ParticleWidget] Init | direction={particle_direction}, "
|
|
40
|
+
f"count={particle_count}, size={particle_size}, "
|
|
41
|
+
f"screen=({screen_width}x{screen_height}), opacity={opacity}, speed={particle_speed}"
|
|
42
|
+
)
|
|
43
|
+
super().__init__()
|
|
44
|
+
|
|
45
|
+
# 設定視窗屬性 / Set widget attributes
|
|
46
|
+
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
|
|
47
|
+
self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
|
|
48
|
+
|
|
49
|
+
# --- 設定粒子圖片大小 / Scale particle pixmap ---
|
|
50
|
+
target_size = QSize(particle_size, particle_size) if particle_size else QSize(pixmap.width(), pixmap.height())
|
|
51
|
+
self.pixmap: QPixmap = pixmap.scaled(target_size, Qt.AspectRatioMode.KeepAspectRatio)
|
|
52
|
+
|
|
53
|
+
# --- 建立場景與視圖 / Create scene and view ---
|
|
54
|
+
self.particle_view: ExtendGraphicView = ExtendGraphicView()
|
|
55
|
+
self.particle_scene: ParticleGraphicScene = ParticleGraphicScene(
|
|
56
|
+
self.pixmap, particle_direction, particle_count,
|
|
57
|
+
screen_height, screen_width, opacity, particle_speed
|
|
58
|
+
)
|
|
59
|
+
self.particle_view.setScene(self.particle_scene)
|
|
60
|
+
|
|
61
|
+
# --- 設定版面配置 / Set layout ---
|
|
62
|
+
self.grid_layout: QGridLayout = QGridLayout()
|
|
63
|
+
self.grid_layout.addWidget(self.particle_view, 0, 0, -1, -1)
|
|
64
|
+
self.setLayout(self.grid_layout)
|
|
65
|
+
|
|
66
|
+
def set_ui_window_flag(self, show_on_bottom: bool = False) -> None:
|
|
67
|
+
"""
|
|
68
|
+
設定視窗旗標 (保持最上層或最下層)
|
|
69
|
+
Set window flags (stay on top or bottom)
|
|
70
|
+
"""
|
|
71
|
+
front_engine_logger.info(f"[ParticleWidget] set_ui_window_flag | show_on_bottom={show_on_bottom}")
|
|
72
|
+
self.setWindowFlag(
|
|
73
|
+
Qt.WindowType.WindowTransparentForInput |
|
|
74
|
+
Qt.WindowType.FramelessWindowHint |
|
|
75
|
+
Qt.WindowType.Tool
|
|
76
|
+
)
|
|
77
|
+
if not show_on_bottom:
|
|
78
|
+
self.setWindowFlag(Qt.WindowType.WindowStaysOnTopHint)
|
|
79
|
+
else:
|
|
80
|
+
self.setWindowFlag(Qt.WindowType.WindowStaysOnBottomHint)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import random
|
|
2
|
+
from typing import Dict, Callable
|
|
3
|
+
|
|
4
|
+
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def particle_down(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
|
|
8
|
+
"""
|
|
9
|
+
粒子向下移動
|
|
10
|
+
Move particles downward
|
|
11
|
+
"""
|
|
12
|
+
front_engine_logger.debug(f"[particle_down] speed={particle_speed}, count={len(particle_dict)}")
|
|
13
|
+
for particle in particle_dict.values():
|
|
14
|
+
particle["y"] = particle.get("y", 0) + random.randint(0, particle_speed)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def particle_up(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
|
|
18
|
+
"""
|
|
19
|
+
粒子向上移動
|
|
20
|
+
Move particles upward
|
|
21
|
+
"""
|
|
22
|
+
front_engine_logger.debug(f"[particle_up] speed={particle_speed}, count={len(particle_dict)}")
|
|
23
|
+
for particle in particle_dict.values():
|
|
24
|
+
particle["y"] = particle.get("y", 0) - random.randint(0, particle_speed)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def particle_left(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
|
|
28
|
+
"""
|
|
29
|
+
粒子向左移動
|
|
30
|
+
Move particles left
|
|
31
|
+
"""
|
|
32
|
+
front_engine_logger.debug(f"[particle_left] speed={particle_speed}, count={len(particle_dict)}")
|
|
33
|
+
for particle in particle_dict.values():
|
|
34
|
+
particle["x"] = particle.get("x", 0) - random.randint(0, particle_speed)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def particle_right(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
|
|
38
|
+
"""
|
|
39
|
+
粒子向右移動
|
|
40
|
+
Move particles right
|
|
41
|
+
"""
|
|
42
|
+
front_engine_logger.debug(f"[particle_right] speed={particle_speed}, count={len(particle_dict)}")
|
|
43
|
+
for particle in particle_dict.values():
|
|
44
|
+
particle["x"] = particle.get("x", 0) + random.randint(0, particle_speed)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def particle_left_down(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
|
|
48
|
+
"""
|
|
49
|
+
粒子向左下移動
|
|
50
|
+
Move particles left and down
|
|
51
|
+
"""
|
|
52
|
+
front_engine_logger.debug(f"[particle_left_down] speed={particle_speed}")
|
|
53
|
+
particle_left(particle_dict, particle_speed)
|
|
54
|
+
particle_down(particle_dict, particle_speed)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def particle_left_up(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
|
|
58
|
+
"""
|
|
59
|
+
粒子向左上移動
|
|
60
|
+
Move particles left and up
|
|
61
|
+
"""
|
|
62
|
+
front_engine_logger.debug(f"[particle_left_up] speed={particle_speed}")
|
|
63
|
+
particle_left(particle_dict, particle_speed)
|
|
64
|
+
particle_up(particle_dict, particle_speed)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def particle_right_down(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
|
|
68
|
+
"""
|
|
69
|
+
粒子向右下移動
|
|
70
|
+
Move particles right and down
|
|
71
|
+
"""
|
|
72
|
+
front_engine_logger.debug(f"[particle_right_down] speed={particle_speed}")
|
|
73
|
+
particle_right(particle_dict, particle_speed)
|
|
74
|
+
particle_down(particle_dict, particle_speed)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def particle_right_up(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
|
|
78
|
+
"""
|
|
79
|
+
粒子向右上移動
|
|
80
|
+
Move particles right and up
|
|
81
|
+
"""
|
|
82
|
+
front_engine_logger.debug(f"[particle_right_up] speed={particle_speed}")
|
|
83
|
+
particle_right(particle_dict, particle_speed)
|
|
84
|
+
particle_up(particle_dict, particle_speed)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def particle_random_minus(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
|
|
88
|
+
"""
|
|
89
|
+
粒子隨機往左下移動
|
|
90
|
+
Move particles randomly left and down
|
|
91
|
+
"""
|
|
92
|
+
front_engine_logger.debug(f"[particle_random_minus] speed={particle_speed}")
|
|
93
|
+
for particle in particle_dict.values():
|
|
94
|
+
particle["y"] = particle.get("y", 0) + random.randint(0, particle_speed)
|
|
95
|
+
particle["x"] = particle.get("x", 0) - random.randint(0, particle_speed)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def particle_random_add(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
|
|
99
|
+
"""
|
|
100
|
+
粒子隨機往右上移動
|
|
101
|
+
Move particles randomly right and up
|
|
102
|
+
"""
|
|
103
|
+
front_engine_logger.debug(f"[particle_random_add] speed={particle_speed}")
|
|
104
|
+
for particle in particle_dict.values():
|
|
105
|
+
particle["y"] = particle.get("y", 0) - random.randint(0, particle_speed)
|
|
106
|
+
particle["x"] = particle.get("x", 0) + random.randint(0, particle_speed)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def particle_random(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
|
|
110
|
+
"""
|
|
111
|
+
粒子隨機選擇一種方向移動
|
|
112
|
+
Move particles in a random direction
|
|
113
|
+
"""
|
|
114
|
+
front_engine_logger.debug(f"[particle_random] speed={particle_speed}")
|
|
115
|
+
function: Callable = random.choice([
|
|
116
|
+
particle_down, particle_up, particle_left, particle_right,
|
|
117
|
+
particle_right_up, particle_left_down, particle_left_up, particle_right_down,
|
|
118
|
+
particle_random_add, particle_random_minus
|
|
119
|
+
])
|
|
120
|
+
function(particle_dict, particle_speed)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from PySide6.QtGui import QBrush, QColor
|
|
2
|
+
from PySide6.QtWidgets import QGraphicsScene
|
|
3
|
+
|
|
4
|
+
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ExtendGraphicScene(QGraphicsScene):
|
|
8
|
+
"""
|
|
9
|
+
ExtendGraphicScene: 可擴展的 QGraphicsScene 基底類別
|
|
10
|
+
ExtendGraphicScene: A base class extending QGraphicsScene for custom scenes
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, background_color: QColor = QColor(0, 0, 0, 0)):
|
|
14
|
+
"""
|
|
15
|
+
初始化場景
|
|
16
|
+
Initialize the scene
|
|
17
|
+
|
|
18
|
+
:param background_color: 場景背景顏色 (預設透明) / Scene background color (default transparent)
|
|
19
|
+
"""
|
|
20
|
+
front_engine_logger.info("Init ExtendGraphicScene")
|
|
21
|
+
super().__init__()
|
|
22
|
+
|
|
23
|
+
# 設定背景顏色 / Set background color
|
|
24
|
+
self.setBackgroundBrush(QBrush(background_color))
|
|
25
|
+
|
|
26
|
+
def clear_scene(self) -> None:
|
|
27
|
+
"""
|
|
28
|
+
清除場景內所有項目
|
|
29
|
+
Clear all items in the scene
|
|
30
|
+
"""
|
|
31
|
+
front_engine_logger.debug("ExtendGraphicScene clear_scene")
|
|
32
|
+
self.clear()
|