RinUI 0.0.9__py3-none-any.whl

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.
Files changed (102) hide show
  1. RinUI/__init__.py +4 -0
  2. RinUI/__pycache__/__init__.cpython-38.pyc +0 -0
  3. RinUI/assets/fonts/FluentSystemIcons-Index.js +5256 -0
  4. RinUI/assets/fonts/FluentSystemIcons-Resizable.ttf +0 -0
  5. RinUI/assets/img/default_app_icon.png +0 -0
  6. RinUI/components/Base.qml +79 -0
  7. RinUI/components/BasicInput/Button.qml +148 -0
  8. RinUI/components/BasicInput/CheckBox.qml +99 -0
  9. RinUI/components/BasicInput/ComboBox.qml +160 -0
  10. RinUI/components/BasicInput/DropDownButton.qml +21 -0
  11. RinUI/components/BasicInput/Hyperlink.qml +18 -0
  12. RinUI/components/BasicInput/RadioButton.qml +95 -0
  13. RinUI/components/BasicInput/Slider.qml +212 -0
  14. RinUI/components/BasicInput/Switch.qml +102 -0
  15. RinUI/components/BasicInput/ToggleButton.qml +11 -0
  16. RinUI/components/BasicInput/ToolButton.qml +31 -0
  17. RinUI/components/ContextMenu.qml +184 -0
  18. RinUI/components/DateAndTime/PickerView.qml +217 -0
  19. RinUI/components/DateAndTime/TimePicker.qml +115 -0
  20. RinUI/components/DialogsAndFlyouts/Dialog.qml +106 -0
  21. RinUI/components/DialogsAndFlyouts/DialogButtonBox.qml +47 -0
  22. RinUI/components/DialogsAndFlyouts/Flyout.qml +144 -0
  23. RinUI/components/DialogsAndFlyouts/Popup.qml +106 -0
  24. RinUI/components/FocusIndicator.qml +33 -0
  25. RinUI/components/IconWidget.qml +52 -0
  26. RinUI/components/Indicator.qml +90 -0
  27. RinUI/components/Layout/Expander.qml +160 -0
  28. RinUI/components/Layout/SettingExpander.qml +67 -0
  29. RinUI/components/Layout/SettingItem.qml +71 -0
  30. RinUI/components/ListAndCollections/Clip.qml +22 -0
  31. RinUI/components/ListAndCollections/Frame.qml +44 -0
  32. RinUI/components/ListAndCollections/ListView.qml +105 -0
  33. RinUI/components/ListAndCollections/ListViewDelegate.qml +83 -0
  34. RinUI/components/ListAndCollections/SettingCard.qml +73 -0
  35. RinUI/components/ListAndCollections/TableView.qml +82 -0
  36. RinUI/components/ListAndCollections/TableViewDelegate.qml +89 -0
  37. RinUI/components/MenusAndToolbars/Menu.qml +149 -0
  38. RinUI/components/MenusAndToolbars/MenuBar.qml +43 -0
  39. RinUI/components/MenusAndToolbars/MenuItem.qml +119 -0
  40. RinUI/components/MenusAndToolbars/MenuItemGroup.qml +43 -0
  41. RinUI/components/MenusAndToolbars/MenuSeparator.qml +14 -0
  42. RinUI/components/MenusAndToolbars/ToolSeparator.qml +17 -0
  43. RinUI/components/Navigation/ErrorPage.qml +48 -0
  44. RinUI/components/Navigation/NavigationBar.qml +179 -0
  45. RinUI/components/Navigation/NavigationItem.qml +193 -0
  46. RinUI/components/Navigation/NavigationSubItem.qml +103 -0
  47. RinUI/components/Navigation/NavigationView.qml +210 -0
  48. RinUI/components/Navigation/SelectorBar.qml +58 -0
  49. RinUI/components/ScrollBar.qml +163 -0
  50. RinUI/components/ScrollView.qml +13 -0
  51. RinUI/components/Shadow.qml +48 -0
  52. RinUI/components/StatusAndInfo/InfoBadge.qml +78 -0
  53. RinUI/components/StatusAndInfo/InfoBar.qml +246 -0
  54. RinUI/components/StatusAndInfo/ProgressBar.qml +127 -0
  55. RinUI/components/StatusAndInfo/Toast.qml +237 -0
  56. RinUI/components/StatusAndInfo/ToolTip.qml +93 -0
  57. RinUI/components/Text/SpinBox.qml +134 -0
  58. RinUI/components/Text/Text.qml +44 -0
  59. RinUI/components/Text/TextField.qml +94 -0
  60. RinUI/components/Text/TextInput.qml +29 -0
  61. RinUI/components/Utils/Blur.qml +42 -0
  62. RinUI/components/qmldir +76 -0
  63. RinUI/config/rin_ui.json +8 -0
  64. RinUI/core/__init__.py +3 -0
  65. RinUI/core/__pycache__/__init__.cpython-38.pyc +0 -0
  66. RinUI/core/__pycache__/config.cpython-38.pyc +0 -0
  67. RinUI/core/__pycache__/launcher.cpython-38.pyc +0 -0
  68. RinUI/core/__pycache__/theme.cpython-38.pyc +0 -0
  69. RinUI/core/config.py +109 -0
  70. RinUI/core/launcher.py +144 -0
  71. RinUI/core/theme.py +342 -0
  72. RinUI/hooks/__init__.py +3 -0
  73. RinUI/hooks/hook-RinUI.py +3 -0
  74. RinUI/qmldir +92 -0
  75. RinUI/themes/dark.qml +137 -0
  76. RinUI/themes/light.qml +137 -0
  77. RinUI/themes/qmldir +7 -0
  78. RinUI/themes/theme.qml +126 -0
  79. RinUI/themes/utils.qml +28 -0
  80. RinUI/utils/Animation.qml +12 -0
  81. RinUI/utils/FloatLayer.qml +123 -0
  82. RinUI/utils/FontIconLoader.qml +14 -0
  83. RinUI/utils/Position.qml +19 -0
  84. RinUI/utils/Severity.qml +13 -0
  85. RinUI/utils/Typography.qml +17 -0
  86. RinUI/utils/qmldir +5 -0
  87. RinUI/windows/CtrlBtn.qml +119 -0
  88. RinUI/windows/FluentPage.qml +92 -0
  89. RinUI/windows/FluentWindow.qml +32 -0
  90. RinUI/windows/FluentWindowBase.qml +157 -0
  91. RinUI/windows/TitleBar.qml +132 -0
  92. RinUI/windows/qmldir +8 -0
  93. RinUI/windows/window/ApplicationWindow.qml +9 -0
  94. RinUI/windows/window/Window.qml +112 -0
  95. rinui-0.0.9.data/data/LICENSE +21 -0
  96. rinui-0.0.9.data/data/README.md +90 -0
  97. rinui-0.0.9.dist-info/LICENSE +21 -0
  98. rinui-0.0.9.dist-info/METADATA +105 -0
  99. rinui-0.0.9.dist-info/RECORD +102 -0
  100. rinui-0.0.9.dist-info/WHEEL +5 -0
  101. rinui-0.0.9.dist-info/entry_points.txt +2 -0
  102. rinui-0.0.9.dist-info/top_level.txt +1 -0
RinUI/core/launcher.py ADDED
@@ -0,0 +1,144 @@
1
+ import os
2
+ import sys
3
+
4
+ from PySide6.QtCore import QCoreApplication
5
+ from PySide6.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout
6
+ from PySide6.QtQml import QQmlApplicationEngine
7
+ from .theme import ThemeManager
8
+ from .config import BackdropEffect, is_windows, Theme
9
+
10
+
11
+ def resource_path(relative_path):
12
+ """兼容 PyInstaller 打包和开发环境的路径"""
13
+ if hasattr(sys, '_MEIPASS'):
14
+ return os.path.join(sys._MEIPASS, relative_path)
15
+ return os.path.abspath(relative_path)
16
+
17
+
18
+ class TestWindow(QWidget):
19
+ def __init__(self, theme_manager):
20
+ super().__init__()
21
+ layout = QVBoxLayout()
22
+ self.setLayout(layout)
23
+ self.setWindowTitle("Test Window")
24
+ btn = QPushButton(theme_manager.current_theme)
25
+ btn.clicked.connect(
26
+ lambda: theme_manager.toggle_theme("Light" if theme_manager.current_theme == "Dark" else "Dark")
27
+ )
28
+ self.layout().addWidget(btn)
29
+ self.resize(400, 300)
30
+
31
+
32
+ class RinUIWindow:
33
+ # _instance = None
34
+ #
35
+ # def __new__(cls, *args, **kwargs): # 单例模式管理
36
+ # if cls._instance is None:
37
+ # cls._instance = super().__new__(cls)
38
+ # return cls._instance
39
+
40
+ def __init__(self, qml_path: str):
41
+ """
42
+ 创建基于 RinUI 的 QML 应用程序。
43
+ :param qml_path: str, QML 文件路径
44
+ """
45
+ if hasattr(self, "_initialized") and self._initialized:
46
+ return
47
+ self._initialized = True
48
+ print("✨ RinUIWindow Initializing")
49
+
50
+ self.engine = QQmlApplicationEngine()
51
+ self.theme_manager = ThemeManager()
52
+ self.qml_path = qml_path
53
+ self.autoSetWindowsEffect = True
54
+
55
+ self._setup_application()
56
+ self.print_startup_info()
57
+
58
+ # 退出清理
59
+ app_instance = QCoreApplication.instance()
60
+ if app_instance:
61
+ app_instance.aboutToQuit.connect(self.theme_manager.clean_up)
62
+
63
+ def _setup_application(self):
64
+ """Setup"""
65
+ # RInUI 模块
66
+ rinui_path = os.path.abspath(os.path.dirname(__file__)) # RinUI/core 目录
67
+ rinui_import_path = resource_path(os.path.join(rinui_path, "../../")) # 使用 resource_path 处理路径
68
+ print(f"UI Module Path: {rinui_import_path}")
69
+
70
+ if os.path.exists(rinui_import_path):
71
+ self.engine.addImportPath(rinui_import_path)
72
+ else:
73
+ raise FileNotFoundError(f"Cannot find RinUI module: {rinui_import_path}")
74
+
75
+ # 主题管理器
76
+
77
+ self.engine.rootContext().setContextProperty("ThemeManager", self.theme_manager)
78
+ try:
79
+ self.engine.load(self.qml_path)
80
+ except Exception as e:
81
+ print(f"Cannot Load QML file: {e}")
82
+
83
+ if not self.engine.rootObjects():
84
+ raise RuntimeError(f"Error loading QML file: {self.qml_path}")
85
+
86
+ # 窗口设置
87
+
88
+ self.root_window = self.engine.rootObjects()[0]
89
+
90
+ self.theme_manager.set_window(self.root_window)
91
+ self._apply_windows_effects() if self.autoSetWindowsEffect else None
92
+
93
+ def _apply_windows_effects(self):
94
+ """
95
+ Apply Windows effects to the window.
96
+ :return:
97
+ """
98
+ if sys.platform == "win32":
99
+ self.theme_manager.apply_backdrop_effect(self.theme_manager.get_backdrop_effect())
100
+ self.theme_manager.apply_window_effects()
101
+
102
+ # func名称遵循 Qt 命名规范
103
+ def setBackdropEffect(self, effect: BackdropEffect):
104
+ """
105
+ Sets the backdrop effect for the window. (Only available on Windows)
106
+ :param effect: BackdropEffect, type of backdrop effect(Acrylic, Mica, Tabbed, None_)
107
+ :return:
108
+ """
109
+ if not is_windows() and effect != BackdropEffect.None_:
110
+ raise OSError("Only can set backdrop effect on Windows platform.")
111
+ self.theme_manager.apply_backdrop_effect(effect.value)
112
+
113
+ def setTheme(self, theme: Theme):
114
+ """
115
+ Sets the theme for the window.
116
+ :param theme: Theme, type of theme(Auto, Dark, Light)
117
+ :return:
118
+ """
119
+ self.theme_manager.toggle_theme(theme.value)
120
+
121
+ def __getattr__(self, name):
122
+ """获取 QML 窗口属性"""
123
+ try:
124
+ root = object.__getattribute__(self, "root_window")
125
+ return getattr(root, name)
126
+ except AttributeError:
127
+ raise AttributeError(f"\"RinUIWindow\" object has no attribute '{name}'")
128
+
129
+ def print_startup_info(self):
130
+ border = "=" * 40
131
+ print(f"\n{border}")
132
+ print("✨ RinUIWindow Loaded Successfully!")
133
+ print(f"QML File Path: {self.qml_path}")
134
+ print(f"Current Theme: {self.theme_manager.current_theme}")
135
+ print(f"Backdrop Effect: {self.theme_manager.get_backdrop_effect()}")
136
+ print(f"OS: {sys.platform}")
137
+ print(border + "\n")
138
+
139
+
140
+ if __name__ == "__main__":
141
+ # 新用法,应该更规范了捏
142
+ app = QApplication(sys.argv)
143
+ example = RinUIWindow("../../examples/gallery.qml")
144
+ sys.exit(app.exec())
RinUI/core/theme.py ADDED
@@ -0,0 +1,342 @@
1
+ import ctypes
2
+ import platform
3
+ import time
4
+
5
+ from PySide6.QtCore import QObject, Signal, Slot, QThread
6
+
7
+ from .config import DEFAULT_CONFIG, ConfigCenter, PATH, is_win10, is_windows, is_win11, BackdropEffect
8
+ import sys
9
+ import darkdetect
10
+
11
+
12
+ def check_darkdetect_support():
13
+ system = platform.system()
14
+ if system == "Darwin":
15
+ mac_ver = platform.mac_ver()[0]
16
+ major, minor, *_ = map(int, mac_ver.split("."))
17
+ return (major == 10 and minor >= 14) or major > 10
18
+
19
+ elif system == "Windows":
20
+ return platform.release() >= "10"
21
+ else:
22
+ return False
23
+
24
+
25
+ ACCENT_STATES = {
26
+ "acrylic": 3,
27
+ "mica": 2,
28
+ "tabbed": 4,
29
+ "none": 0
30
+ }
31
+
32
+ ACCENT_SUPPORT = {
33
+ "acrylic": is_win10(),
34
+ "mica": is_win11(),
35
+ "tabbed": is_win10(),
36
+ "none": True
37
+ }
38
+
39
+
40
+ class ACCENT_POLICY(ctypes.Structure):
41
+ _fields_ = [
42
+ ("AccentState", ctypes.c_int),
43
+ ("AccentFlags", ctypes.c_int),
44
+ ("GradientColor", ctypes.c_int),
45
+ ("AnimationId", ctypes.c_int),
46
+ ]
47
+
48
+
49
+ class WINDOWCOMPOSITIONATTRIBDATA(ctypes.Structure):
50
+ _fields_ = [
51
+ ("Attrib", ctypes.c_int),
52
+ ("pvData", ctypes.c_void_p),
53
+ ("cbData", ctypes.c_size_t),
54
+ ]
55
+
56
+
57
+ class ThemeListener(QThread):
58
+ """
59
+ 监听系统颜色模式
60
+ """
61
+ themeChanged = Signal(str)
62
+
63
+ def run(self):
64
+ last_theme = darkdetect.theme()
65
+ while True:
66
+ current_theme = darkdetect.theme()
67
+ if current_theme != last_theme:
68
+ last_theme = current_theme
69
+ self.themeChanged.emit(current_theme)
70
+ print(f"Theme changed: {current_theme}")
71
+ time.sleep(1)
72
+
73
+ def stop(self):
74
+ self.terminate()
75
+
76
+
77
+ class ThemeManager(QObject):
78
+ themeChanged = Signal(str)
79
+ backdropChanged = Signal(str)
80
+ windows = [] # 窗口句柄们(
81
+ _instance = None
82
+
83
+ # DWM 常量保持不变
84
+ DWMWA_USE_IMMERSIVE_DARK_MODE = 20
85
+ DWMWA_WINDOW_CORNER_PREFERENCE = 33
86
+ DWMWA_NCRENDERING_POLICY = 2
87
+ DWMNCRENDERINGPOLICY_ENABLED = 2
88
+ DWMWA_SYSTEMBACKDROP_TYPE = 38
89
+ WCA_ACCENT_POLICY = 19
90
+
91
+ # 圆角
92
+ DWMWCP_DEFAULT = 0
93
+ DWMWCP_DONOTROUND = 1
94
+ DWMWCP_ROUND = 2
95
+ DWMWCP_ROUNDSMALL = 3
96
+
97
+ def clean_up(self):
98
+ """
99
+ 清理资源并停止主题监听。
100
+ """
101
+ if self.listener:
102
+ self.config.save_config()
103
+ print("Save config.")
104
+ self.listener.stop()
105
+ self.listener.wait() # 等待线程结束
106
+ print("Theme listener stopped.")
107
+
108
+ def __new__(cls, *args, **kwargs):
109
+ """
110
+ 单例管理,共享主题状态
111
+ :param args:
112
+ :param kwargs:
113
+ """
114
+ if cls._instance is None:
115
+ cls._instance = super().__new__(cls)
116
+ return cls._instance
117
+
118
+ def __init__(self):
119
+ if hasattr(self, "_initialized") and self._initialized:
120
+ return
121
+ self._initialized = True
122
+ super().__init__()
123
+ self.theme_dict = {
124
+ "Light": 0,
125
+ "Dark": 1
126
+ }
127
+
128
+ self.listener = None # 监听线程
129
+ self.current_theme = DEFAULT_CONFIG["theme"]["current_theme"] # 当前主题
130
+ self.is_darkdetect_supported = check_darkdetect_support()
131
+
132
+ self.config = ConfigCenter(PATH, "rin_ui.json") # 配置中心
133
+ self.config.load_config(DEFAULT_CONFIG) # 加载配置
134
+
135
+ try:
136
+ self.current_theme = self.config["theme"]["current_theme"]
137
+ except Exception as e:
138
+ print(f"Failed to load config because of {e}, using default config")
139
+
140
+ # self.hwnd = None # 窗口句柄
141
+
142
+ self.start_listener()
143
+
144
+ def start_listener(self):
145
+ if not self.is_darkdetect_supported:
146
+ print("darkdetect not supported on this platform")
147
+ return
148
+ self.listener = ThemeListener()
149
+ self.listener.themeChanged.connect(self._handle_system_theme)
150
+ self.listener.start()
151
+
152
+ def set_window(self, window): # 绑定窗口句柄
153
+ hwnd = int(window.winId())
154
+ self.windows.append(hwnd)
155
+ print(f"Window handle set: {hwnd}")
156
+
157
+ def _handle_system_theme(self, system_theme):
158
+ if self.current_theme == "Auto":
159
+ self._update_window_theme()
160
+ self.themeChanged.emit(self._actual_theme())
161
+ else:
162
+ # 保持当前背景效果不变
163
+ self._update_window_theme()
164
+
165
+ @Slot(str)
166
+ def apply_backdrop_effect(self, effect_type: str):
167
+ """
168
+ 应用背景效果
169
+ :param effect_type: str, 背景效果类型(acrylic, mica, tabbed, none)
170
+ """
171
+ self._update_window_theme()
172
+ if not is_windows() or not self.windows:
173
+ print(f"Cannot apply effect \"{effect_type}\" on this platform")
174
+ return -2 # 非 windows或未绑定窗口
175
+ self.backdropChanged.emit(effect_type)
176
+
177
+ accent_state = ACCENT_STATES.get(effect_type, 0)
178
+ if not ACCENT_SUPPORT.get(effect_type, False):
179
+ print(f"Effect \"{effect_type}\" not supported on this platform")
180
+ return -1 # 效果不支持
181
+
182
+ for hwnd in self.windows:
183
+ if is_win11():
184
+ ctypes.windll.dwmapi.DwmSetWindowAttribute(
185
+ hwnd,
186
+ self.DWMWA_SYSTEMBACKDROP_TYPE,
187
+ ctypes.byref(ctypes.c_int(accent_state)),
188
+ ctypes.sizeof(ctypes.c_int)
189
+ )
190
+ elif is_win10() and effect_type == BackdropEffect.Acrylic.value:
191
+ self._apply_win10_effect(effect_type, hwnd)
192
+
193
+ self.config["backdrop_effect"] = effect_type
194
+ print(
195
+ f"Applied \"{effect_type.strip().capitalize()}\" effect with "
196
+ f"{platform.system() + '11' if is_win11() else '10'}"
197
+ )
198
+ return 0 # 成功
199
+
200
+ def _apply_win10_effect(self, effect_type, hwnd):
201
+ """
202
+ 应用 Windows 10 背景效果
203
+ :param effect_type: str, 背景效果类型(acrylic, tabbed(actually blur)
204
+ """
205
+ backdrop_color = self.config["win10_feat"]["backdrop_dark" if self.is_dark_theme() else "backdrop_light"]
206
+
207
+ accent = ACCENT_POLICY()
208
+ accent.AccentState = ACCENT_STATES[effect_type]
209
+ accent.AccentFlags = 2
210
+ accent.GradientColor = backdrop_color
211
+ data = WINDOWCOMPOSITIONATTRIBDATA()
212
+ data.Attrib = self.WCA_ACCENT_POLICY
213
+ data.pvData = ctypes.cast(ctypes.pointer(accent), ctypes.c_void_p)
214
+ data.cbData = ctypes.sizeof(accent)
215
+
216
+ try:
217
+ set_window_composition = ctypes.windll.user32.SetWindowCompositionAttribute
218
+ set_window_composition(hwnd, ctypes.byref(data))
219
+ except Exception as e:
220
+ print(f"Failed to apply acrylic on Win10: {e}")
221
+
222
+ def apply_window_effects(self): # 启用圆角阴影
223
+ if sys.platform != "win32" or not self.windows:
224
+ return
225
+
226
+ dwm = ctypes.windll.dwmapi
227
+
228
+ # 启用非客户端渲染策略(让窗口边框具备阴影)
229
+ ncrp = ctypes.c_int(self.DWMNCRENDERINGPOLICY_ENABLED)
230
+ for hwnd in self.windows:
231
+ dwm.DwmSetWindowAttribute(
232
+ hwnd,
233
+ self.DWMWA_NCRENDERING_POLICY,
234
+ ctypes.byref(ncrp),
235
+ ctypes.sizeof(ncrp)
236
+ )
237
+
238
+ # 启用圆角效果
239
+ corner_preference = ctypes.c_int(self.DWMWCP_ROUND)
240
+ dwm.DwmSetWindowAttribute(
241
+ hwnd,
242
+ self.DWMWA_WINDOW_CORNER_PREFERENCE,
243
+ ctypes.byref(corner_preference),
244
+ ctypes.sizeof(corner_preference)
245
+ )
246
+ print("Enabled Rounded and Shadows")
247
+
248
+ def _update_window_theme(self): # 更新窗口的颜色模式
249
+ if sys.platform != "win32" or not self.windows:
250
+ return
251
+ actual_theme = self._actual_theme()
252
+ for hwnd in self.windows:
253
+ if is_win11():
254
+ ctypes.windll.dwmapi.DwmSetWindowAttribute(
255
+ hwnd,
256
+ self.DWMWA_USE_IMMERSIVE_DARK_MODE,
257
+ ctypes.byref(ctypes.c_int(self.theme_dict[actual_theme])),
258
+ ctypes.sizeof(ctypes.c_int)
259
+ )
260
+ elif is_win10() and self.config["backdrop_effect"] == BackdropEffect.Acrylic.value:
261
+ self._apply_win10_effect(self.config["backdrop_effect"], hwnd)
262
+ else:
263
+ print(f"Cannot apply backdrop on {platform.system()}")
264
+
265
+ print(f"Window theme updated to {actual_theme}")
266
+
267
+ def is_dark_theme(self):
268
+ """是否为暗黑主题"""
269
+ return self._actual_theme() == "Dark"
270
+
271
+ def _actual_theme(self):
272
+ """实际应用的主题"""
273
+ if self.current_theme == "Auto":
274
+ return darkdetect.theme() if self.is_darkdetect_supported else "Light"
275
+ return self.current_theme
276
+
277
+ @Slot(str)
278
+ def toggle_theme(self, theme: str): # 切换主题
279
+ if theme not in ["Auto", "Light", "Dark"]: # 三状态
280
+ return
281
+ if self.current_theme != theme:
282
+ print(f"Switching to '{theme}' theme")
283
+ self.current_theme = theme
284
+ self.config["theme"]["current_theme"] = theme
285
+ self._update_window_theme()
286
+ self.themeChanged.emit(self._actual_theme())
287
+
288
+ @Slot(result=str)
289
+ def get_theme(self):
290
+ return self._actual_theme()
291
+
292
+ @Slot(result=str)
293
+ def get_theme_name(self):
294
+ """获取当前主题名称"""
295
+ return self.current_theme
296
+
297
+ @Slot(str)
298
+ def receive(self, message):
299
+ print(message)
300
+
301
+ @Slot(result=str)
302
+ def get_backdrop_effect(self):
303
+ """获取当前背景效果"""
304
+ return self.config["backdrop_effect"]
305
+
306
+ @Slot(result=str)
307
+ def get_theme_color(self):
308
+ """获取当前主题颜色"""
309
+ return self.config["theme_color"]
310
+
311
+ @Slot(result=str)
312
+ def set_theme_color(self, color):
313
+ """设置当前主题颜色"""
314
+ self.config["theme_color"] = color
315
+ self.config.save_config()
316
+
317
+ @Slot(QObject, result=int)
318
+ def getWindowId(self, window):
319
+ """获取窗口的句柄"""
320
+ print(f"GetWindowId: {window.winId()}")
321
+ return int(window.winId())
322
+
323
+ @Slot(int)
324
+ def dragWindowEvent(self, hwnd):
325
+ """ 在Windows 用原生方法拖动"""
326
+ if not is_windows() or hwnd not in self.windows:
327
+ print(
328
+ f"Use Qt method to drag window on: {platform.system()}"
329
+ if not is_windows() else f"Invalid window handle: {hwnd}"
330
+ )
331
+ return
332
+
333
+ import win32con
334
+ from win32gui import ReleaseCapture
335
+ from win32api import SendMessage
336
+
337
+ ReleaseCapture()
338
+ SendMessage(
339
+ hwnd,
340
+ win32con.WM_SYSCOMMAND,
341
+ win32con.SC_MOVE | win32con.HTCAPTION, 0
342
+ )
@@ -0,0 +1,3 @@
1
+ def get_hook_dirs():
2
+ import os
3
+ return [os.path.dirname(__file__)]
@@ -0,0 +1,3 @@
1
+ from PyInstaller.utils.hooks import collect_data_files
2
+
3
+ datas = collect_data_files('RinUI', include_py_files=False)
RinUI/qmldir ADDED
@@ -0,0 +1,92 @@
1
+ module RinUI
2
+
3
+ singleton Theme 1.0 themes/theme.qml
4
+ singleton Utils 1.0 themes/utils.qml
5
+
6
+ Shadow 1.0 components/Shadow.qml
7
+ FocusIndicator 1.0 components/FocusIndicator.qml
8
+
9
+ # Basic Input
10
+ Button 1.0 components/BasicInput/Button.qml
11
+ DropDownButton 1.0 components/BasicInput/DropDownButton.qml
12
+ ToggleButton 1.0 components/BasicInput/ToggleButton.qml
13
+ ToolButton 1.0 components/BasicInput/ToolButton.qml
14
+ ComboBox 1.0 components/BasicInput/ComboBox.qml
15
+ Switch 1.0 components/BasicInput/Switch.qml
16
+ Hyperlink 1.0 components/BasicInput/Hyperlink.qml
17
+ RadioButton 1.0 components/BasicInput/RadioButton.qml
18
+ CheckBox 1.0 components/BasicInput/CheckBox.qml
19
+ Slider 1.0 components/BasicInput/Slider.qml
20
+
21
+ # Date & Time
22
+ TimePicker 1.0 components/DateAndTime/TimePicker.qml
23
+ PickerView 1.0 components/DateAndTime/PickerView.qml
24
+
25
+ # Dialogs & Flyouts
26
+ Dialog 1.0 components/DialogsAndFlyouts/Dialog.qml
27
+ Flyout 1.0 components/DialogsAndFlyouts/Flyout.qml
28
+
29
+ # Layout
30
+ Expander 1.0 components/Layout/Expander.qml
31
+ SettingExpander 1.0 components/Layout/SettingExpander.qml
32
+ SettingItem 1.0 components/Layout/SettingItem.qml
33
+
34
+
35
+ # Text
36
+ Text 1.0 components/Text/Text.qml
37
+ TextField 1.0 components/Text/TextField.qml
38
+ SpinBox 1.0 components/Text/SpinBox.qml
39
+ TextInput 1.0 components/Text/TextInput.qml
40
+
41
+
42
+ # Status & Info
43
+ InfoBadge 1.0 components/StatusAndInfo/InfoBadge.qml
44
+ InfoBar 1.0 components/StatusAndInfo/InfoBar.qml
45
+ ProgressBar 1.0 components/StatusAndInfo/ProgressBar.qml
46
+ ToolTip 1.0 components/StatusAndInfo/ToolTip.qml
47
+
48
+ # ListAndCollections
49
+ Clip 1.0 components/ListAndCollections/Clip.qml
50
+ Frame 1.0 components/ListAndCollections/Frame.qml
51
+ SettingCard 1.0 components/ListAndCollections/SettingCard.qml
52
+ ListView 1.0 components/ListAndCollections/ListView.qml
53
+ ListViewDelegate 1.0 components/ListAndCollections/ListViewDelegate.qml
54
+ TableView 1.0 components/ListAndCollections/TableView.qml
55
+ TableViewDelegate 1.0 components/ListAndCollections/TableViewDelegate.qml
56
+
57
+ # Menus & Toolbars
58
+ Menu 1.0 components/MenusAndToolbars/Menu.qml
59
+ MenuItem 1.0 components/MenusAndToolbars/MenuItem.qml
60
+ MenuItemGroup 1.0 components/MenusAndToolbars/MenuItemGroup.qml
61
+ MenuSeparator 1.0 components/MenusAndToolbars/MenuSeparator.qml
62
+ ToolSeparator 1.0 components/MenusAndToolbars/ToolSeparator.qml
63
+ MenuBar 1.0 components/MenusAndToolbars/MenuBar.qml
64
+
65
+ # Navigation
66
+ NavigationView 1.0 components/Navigation/NavigationView.qml
67
+ NavigationBar 1.0 components/Navigation/NavigationBar.qml
68
+ SelectorBar 1.0 components/Navigation/SelectorBar.qml
69
+
70
+ # Window
71
+ ApplicationWindow 1.0 windows/window/ApplicationWindow.qml
72
+ Window 1.0 windows/window/Window.qml
73
+
74
+
75
+ ScrollViewer 1.0 components/ScrollViewer.qml
76
+ ScrollBar 1.0 components/ScrollBar.qml
77
+
78
+ IconWidget 1.0 components/IconWidget.qml
79
+
80
+
81
+ ContextMenu 1.0 components/ContextMenu.qml
82
+
83
+ FluentWindow 1.0 windows/FluentWindow.qml
84
+ FluentWindowBase 1.0 windows/FluentWindowBase.qml
85
+ CtrlBtn 1.0 windows/CtrlBtn.qml
86
+ FluentPage 1.0 windows/FluentPage.qml
87
+
88
+ singleton Typography 1.0 utils/Typography.qml
89
+ singleton Severity 1.0 utils/Severity.qml
90
+ singleton Position 1.0 utils/Position.qml
91
+
92
+ FloatLayer 1.0 utils/FloatLayer.qml