RinUI 0.0.10__tar.gz → 0.0.11__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.
- {rinui-0.0.10/RinUI.egg-info → rinui-0.0.11}/PKG-INFO +3 -2
- {rinui-0.0.10 → rinui-0.0.11}/README.md +2 -1
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/__init__.py +1 -1
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/ContextMenu.qml +1 -1
- rinui-0.0.11/RinUI/components/MenusAndToolbars/TextInputMenu.qml +38 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/StatusAndInfo/InfoBar.qml +1 -1
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Text/TextArea.qml +1 -29
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Text/TextField.qml +1 -29
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Text/TextInput.qml +19 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/qmldir +1 -0
- rinui-0.0.11/RinUI/core/__init__.py +4 -0
- rinui-0.0.11/RinUI/core/__pycache__/__init__.cpython-38.pyc +0 -0
- rinui-0.0.11/RinUI/core/__pycache__/config.cpython-38.pyc +0 -0
- rinui-0.0.11/RinUI/core/__pycache__/launcher.cpython-38.pyc +0 -0
- rinui-0.0.11/RinUI/core/__pycache__/theme.cpython-38.pyc +0 -0
- rinui-0.0.11/RinUI/core/__pycache__/translator.cpython-38.pyc +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/core/config.py +11 -2
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/core/launcher.py +24 -37
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/core/theme.py +17 -20
- rinui-0.0.11/RinUI/core/translator.py +25 -0
- rinui-0.0.11/RinUI/languages/en_US.qm +1 -0
- rinui-0.0.11/RinUI/languages/en_US.ts +201 -0
- rinui-0.0.11/RinUI/languages/zh_CN.qm +0 -0
- rinui-0.0.11/RinUI/languages/zh_CN.ts +204 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/qmldir +1 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/themes/theme.qml +39 -15
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/themes/utils.qml +4 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/windows/FluentWindow.qml +0 -1
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/windows/FluentWindowBase.qml +0 -1
- {rinui-0.0.10 → rinui-0.0.11/RinUI.egg-info}/PKG-INFO +3 -2
- {rinui-0.0.10 → rinui-0.0.11}/RinUI.egg-info/SOURCES.txt +7 -0
- {rinui-0.0.10 → rinui-0.0.11}/pyproject.toml +1 -1
- rinui-0.0.10/RinUI/core/__init__.py +0 -3
- rinui-0.0.10/RinUI/core/__pycache__/__init__.cpython-38.pyc +0 -0
- rinui-0.0.10/RinUI/core/__pycache__/config.cpython-38.pyc +0 -0
- rinui-0.0.10/RinUI/core/__pycache__/launcher.cpython-38.pyc +0 -0
- rinui-0.0.10/RinUI/core/__pycache__/theme.cpython-38.pyc +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/LICENSE +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/MANIFEST.in +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/__pycache__/__init__.cpython-38.pyc +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/assets/fonts/FluentSystemIcons-Index.js +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/assets/fonts/FluentSystemIcons-Resizable.ttf +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/assets/img/default_app_icon.png +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Base.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/BasicInput/Button.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/BasicInput/CheckBox.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/BasicInput/ComboBox.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/BasicInput/DropDownButton.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/BasicInput/Hyperlink.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/BasicInput/PillButton.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/BasicInput/RadioButton.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/BasicInput/RoundButton.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/BasicInput/Slider.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/BasicInput/Switch.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/BasicInput/ToggleButton.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/BasicInput/ToolButton.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/DateAndTime/DatePicker.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/DateAndTime/PickerView.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/DateAndTime/TimePicker.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/DialogsAndFlyouts/Dialog.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/DialogsAndFlyouts/DialogButtonBox.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/DialogsAndFlyouts/Flyout.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/DialogsAndFlyouts/Popup.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/FocusIndicator.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/IconWidget.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Indicator.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Layout/Expander.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Layout/SettingExpander.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Layout/SettingItem.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/ListAndCollections/Clip.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/ListAndCollections/Frame.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/ListAndCollections/ListView.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/ListAndCollections/ListViewDelegate.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/ListAndCollections/SettingCard.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/ListAndCollections/TableView.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/ListAndCollections/TableViewDelegate.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/MenusAndToolbars/Menu.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/MenusAndToolbars/MenuBar.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/MenusAndToolbars/MenuItem.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/MenusAndToolbars/MenuItemGroup.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/MenusAndToolbars/MenuSeparator.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/MenusAndToolbars/ToolSeparator.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Navigation/ErrorPage.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Navigation/NavigationBar.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Navigation/NavigationItem.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Navigation/NavigationSubItem.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Navigation/NavigationView.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Navigation/SelectorBar.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/ScrollBar.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/ScrollView.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Shadow.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/StatusAndInfo/InfoBadge.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/StatusAndInfo/ProgressBar.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/StatusAndInfo/Toast.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/StatusAndInfo/ToolTip.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Text/SpinBox.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/components/Text/Text.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/config/rin_ui.json +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/hooks/__init__.py +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/hooks/hook-RinUI.py +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/themes/dark.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/themes/light.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/themes/qmldir +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/utils/Animation.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/utils/FloatLayer.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/utils/FontIconLoader.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/utils/Position.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/utils/Severity.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/utils/Typography.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/utils/qmldir +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/windows/CtrlBtn.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/windows/FluentPage.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/windows/TitleBar.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/windows/qmldir +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/windows/window/ApplicationWindow.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI/windows/window/Window.qml +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI.egg-info/dependency_links.txt +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI.egg-info/entry_points.txt +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI.egg-info/requires.txt +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/RinUI.egg-info/top_level.txt +0 -0
- {rinui-0.0.10 → rinui-0.0.11}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: RinUI
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.11
|
4
4
|
Summary: A Fluent Design-like UI library for Qt Quick (QML) based on PySide6
|
5
5
|
Author-email: RinLit <lintu233_qwq@icloud.com>
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
@@ -35,7 +35,8 @@ With simple configuration, you can quickly develop elegant UI interfaces in the
|
|
35
35
|
* Elegant Fluent Design controls (WIP)
|
36
36
|
* Dark and light mode, automatic switching
|
37
37
|
* Compatible with original QML control names
|
38
|
-
*
|
38
|
+
* i18n Internationalization
|
39
|
+
* Multi-programming language support (WIP)
|
39
40
|
* Theme system (WIP)
|
40
41
|
* Development documentation, [preview](https://ui.rinlit.cn/) now. (WIP)
|
41
42
|
|
@@ -20,7 +20,8 @@ With simple configuration, you can quickly develop elegant UI interfaces in the
|
|
20
20
|
* Elegant Fluent Design controls (WIP)
|
21
21
|
* Dark and light mode, automatic switching
|
22
22
|
* Compatible with original QML control names
|
23
|
-
*
|
23
|
+
* i18n Internationalization
|
24
|
+
* Multi-programming language support (WIP)
|
24
25
|
* Theme system (WIP)
|
25
26
|
* Development documentation, [preview](https://ui.rinlit.cn/) now. (WIP)
|
26
27
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import QtQuick 2.15
|
2
|
+
import QtQuick.Controls 2.15
|
3
|
+
import "../../themes"
|
4
|
+
import "../../components"
|
5
|
+
|
6
|
+
|
7
|
+
// Menu
|
8
|
+
Menu {
|
9
|
+
id: contextMenu
|
10
|
+
position: -1
|
11
|
+
Action {
|
12
|
+
icon.name: "ic_fluent_cut_20_regular"
|
13
|
+
text: qsTr("Cut")
|
14
|
+
enabled: root.selectedText.length > 0 && root.editable // 选中&可编辑
|
15
|
+
shortcut: "Ctrl+X"
|
16
|
+
onTriggered: root.cut()
|
17
|
+
}
|
18
|
+
Action {
|
19
|
+
icon.name: "ic_fluent_copy_20_regular"
|
20
|
+
text: qsTr("Copy")
|
21
|
+
enabled: root.selectedText.length > 0 // 选中内容
|
22
|
+
shortcut: "Ctrl+C"
|
23
|
+
onTriggered: root.copy()
|
24
|
+
}
|
25
|
+
Action {
|
26
|
+
icon.name: "ic_fluent_clipboard_paste_20_regular"
|
27
|
+
text: qsTr("Paste")
|
28
|
+
enabled: root.editable
|
29
|
+
shortcut: "Ctrl+V"
|
30
|
+
onTriggered: root.paste()
|
31
|
+
}
|
32
|
+
Action {
|
33
|
+
icon.name: " "
|
34
|
+
text: qsTr("Select All")
|
35
|
+
shortcut: "Ctrl+A"
|
36
|
+
onTriggered: root.selectAll()
|
37
|
+
}
|
38
|
+
}
|
@@ -104,6 +104,7 @@ Frame {
|
|
104
104
|
}
|
105
105
|
|
106
106
|
Flow {
|
107
|
+
id: flow
|
107
108
|
Layout.alignment: Qt.AlignTop
|
108
109
|
Layout.fillWidth: true
|
109
110
|
Layout.topMargin: 3
|
@@ -121,7 +122,6 @@ Frame {
|
|
121
122
|
property bool wrap: (
|
122
123
|
(
|
123
124
|
infoBar.width - iconWidget.width - rights.width - main.spacing * 2 - infoBar.padding * 2
|
124
|
-
- (titleText.width + custom.width + 24)
|
125
125
|
)
|
126
126
|
< implicitWidth
|
127
127
|
)
|
@@ -15,36 +15,8 @@ TextArea {
|
|
15
15
|
enabled: editable
|
16
16
|
|
17
17
|
// Menu
|
18
|
-
|
18
|
+
TextInputMenu {
|
19
19
|
id: contextMenu
|
20
|
-
position: -1
|
21
|
-
Action {
|
22
|
-
icon.name: "ic_fluent_cut_20_regular"
|
23
|
-
text: qsTr("Cut")
|
24
|
-
enabled: root.selectedText.length > 0 && root.editable // 选中&可编辑
|
25
|
-
shortcut: "Ctrl+X"
|
26
|
-
onTriggered: root.cut()
|
27
|
-
}
|
28
|
-
Action {
|
29
|
-
icon.name: "ic_fluent_copy_20_regular"
|
30
|
-
text: qsTr("Copy")
|
31
|
-
enabled: root.selectedText.length > 0 // 选中内容
|
32
|
-
shortcut: "Ctrl+C"
|
33
|
-
onTriggered: root.copy()
|
34
|
-
}
|
35
|
-
Action {
|
36
|
-
icon.name: "ic_fluent_clipboard_paste_20_regular"
|
37
|
-
text: qsTr("Paste")
|
38
|
-
enabled: root.editable
|
39
|
-
shortcut: "Ctrl+V"
|
40
|
-
onTriggered: root.paste()
|
41
|
-
}
|
42
|
-
Action {
|
43
|
-
icon.name: " "
|
44
|
-
text: qsTr("Select All")
|
45
|
-
shortcut: "Ctrl+A"
|
46
|
-
onTriggered: root.selectAll()
|
47
|
-
}
|
48
20
|
}
|
49
21
|
|
50
22
|
MouseArea {
|
@@ -15,36 +15,8 @@ TextField {
|
|
15
15
|
enabled: editable
|
16
16
|
|
17
17
|
// Menu
|
18
|
-
|
18
|
+
TextInputMenu {
|
19
19
|
id: contextMenu
|
20
|
-
position: -1
|
21
|
-
Action {
|
22
|
-
icon.name: "ic_fluent_cut_20_regular"
|
23
|
-
text: qsTr("Cut")
|
24
|
-
enabled: root.selectedText.length > 0 && root.editable // 选中&可编辑
|
25
|
-
shortcut: "Ctrl+X"
|
26
|
-
onTriggered: root.cut()
|
27
|
-
}
|
28
|
-
Action {
|
29
|
-
icon.name: "ic_fluent_copy_20_regular"
|
30
|
-
text: qsTr("Copy")
|
31
|
-
enabled: root.selectedText.length > 0 // 选中内容
|
32
|
-
shortcut: "Ctrl+C"
|
33
|
-
onTriggered: root.copy()
|
34
|
-
}
|
35
|
-
Action {
|
36
|
-
icon.name: "ic_fluent_clipboard_paste_20_regular"
|
37
|
-
text: qsTr("Paste")
|
38
|
-
enabled: root.editable
|
39
|
-
shortcut: "Ctrl+V"
|
40
|
-
onTriggered: root.paste()
|
41
|
-
}
|
42
|
-
Action {
|
43
|
-
icon.name: " "
|
44
|
-
text: qsTr("Select All")
|
45
|
-
shortcut: "Ctrl+A"
|
46
|
-
onTriggered: root.selectAll()
|
47
|
-
}
|
48
20
|
}
|
49
21
|
|
50
22
|
MouseArea {
|
@@ -13,6 +13,25 @@ TextInput {
|
|
13
13
|
color: Theme.currentTheme.colors.textColor
|
14
14
|
selectionColor: Theme.currentTheme.colors.primaryColor
|
15
15
|
|
16
|
+
// Menu
|
17
|
+
TextInputMenu {
|
18
|
+
id: contextMenu
|
19
|
+
}
|
20
|
+
|
21
|
+
MouseArea {
|
22
|
+
anchors.fill: parent
|
23
|
+
acceptedButtons: Qt.RightButton
|
24
|
+
propagateComposedEvents: true
|
25
|
+
onPressed: (mouse) => {
|
26
|
+
if (mouse.button === Qt.RightButton)
|
27
|
+
contextMenu.popup(mouse.scenePosition)
|
28
|
+
mouse.accepted = false
|
29
|
+
}
|
30
|
+
|
31
|
+
// 鼠标
|
32
|
+
cursorShape: Qt.IBeamCursor
|
33
|
+
}
|
34
|
+
|
16
35
|
font.pixelSize: {
|
17
36
|
switch (typography) {
|
18
37
|
case Typography.Display: return Theme.currentTheme.typography.displaySize;
|
@@ -47,6 +47,7 @@ Text 1.0 Text/Text.qml
|
|
47
47
|
|
48
48
|
# Menus & Toolbars
|
49
49
|
Menu 1.0 MenusAndToolbars/Menu.qml
|
50
|
+
TextInputMenu 1.0 MenusAndToolbars/TextInputMenu.qml
|
50
51
|
MenuItem 1.0 MenusAndToolbars/MenuItem.qml
|
51
52
|
MenuItemGroup 1.0 MenusAndToolbars/MenuItemGroup.qml
|
52
53
|
MenuSeparator 1.0 MenusAndToolbars/MenuSeparator.qml
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -2,6 +2,7 @@ import os
|
|
2
2
|
import json
|
3
3
|
import platform
|
4
4
|
import sys
|
5
|
+
from PySide6.QtCore import QLocale
|
5
6
|
from enum import Enum
|
6
7
|
|
7
8
|
|
@@ -36,7 +37,6 @@ BASE_DIR = os.path.abspath(os.getcwd())
|
|
36
37
|
PATH = os.path.join(BASE_DIR, "RinUI/config")
|
37
38
|
RINUI_PATH = resource_path(os.path.join(rinui_core_path, "../../")) # 使用 resource_path 处理路径
|
38
39
|
DEFAULT_CONFIG = {
|
39
|
-
"language": "zh_CN",
|
40
40
|
"theme": {
|
41
41
|
"current_theme": "Auto",
|
42
42
|
},
|
@@ -62,8 +62,13 @@ class BackdropEffect(Enum):
|
|
62
62
|
Tabbed = "tabbed"
|
63
63
|
|
64
64
|
|
65
|
-
class
|
65
|
+
class ConfigManager:
|
66
66
|
def __init__(self, path, filename):
|
67
|
+
"""
|
68
|
+
Json Config Manager
|
69
|
+
:param path: json config file path
|
70
|
+
:param filename: json config file name (eg: rin_ui.json)
|
71
|
+
"""
|
67
72
|
self.path = path
|
68
73
|
self.filename = filename
|
69
74
|
self.config = {}
|
@@ -118,3 +123,7 @@ class ConfigCenter:
|
|
118
123
|
|
119
124
|
def __repr__(self):
|
120
125
|
return json.dumps(self.config, ensure_ascii=False, indent=4)
|
126
|
+
|
127
|
+
|
128
|
+
RinConfig = ConfigManager(path=PATH, filename='rin_ui.json')
|
129
|
+
RinConfig.load_config(DEFAULT_CONFIG) # 加载配置
|
@@ -1,33 +1,20 @@
|
|
1
1
|
import os
|
2
2
|
import sys
|
3
3
|
|
4
|
-
from PySide6.QtCore import QCoreApplication, QUrl
|
4
|
+
from PySide6.QtCore import QCoreApplication, QUrl, QObject
|
5
5
|
from PySide6.QtGui import QIcon
|
6
|
-
from PySide6.QtWidgets import QApplication
|
6
|
+
from PySide6.QtWidgets import QApplication
|
7
7
|
from PySide6.QtQml import QQmlApplicationEngine
|
8
|
-
from .theme import ThemeManager
|
9
|
-
from .config import BackdropEffect, is_windows, Theme, RINUI_PATH
|
10
|
-
|
11
8
|
|
12
|
-
|
13
|
-
|
14
|
-
super().__init__()
|
15
|
-
layout = QVBoxLayout()
|
16
|
-
self.setLayout(layout)
|
17
|
-
self.setWindowTitle("Test Window")
|
18
|
-
btn = QPushButton(theme_manager.current_theme)
|
19
|
-
btn.clicked.connect(
|
20
|
-
lambda: theme_manager.toggle_theme("Light" if theme_manager.current_theme == "Dark" else "Dark")
|
21
|
-
)
|
22
|
-
self.layout().addWidget(btn)
|
23
|
-
self.resize(400, 300)
|
9
|
+
from .theme import ThemeManager
|
10
|
+
from .config import BackdropEffect, is_windows, Theme, RINUI_PATH, RinConfig
|
24
11
|
|
25
12
|
|
26
13
|
class RinUIWindow:
|
27
14
|
def __init__(self, qml_path: str):
|
28
15
|
"""
|
29
|
-
|
30
|
-
:param qml_path: str, QML
|
16
|
+
Create an application window with RinUI.
|
17
|
+
:param qml_path: str, QML file path (eg = "path/to/main.qml")
|
31
18
|
"""
|
32
19
|
super().__init__()
|
33
20
|
if hasattr(self, "_initialized") and self._initialized:
|
@@ -35,29 +22,29 @@ class RinUIWindow:
|
|
35
22
|
self._initialized = True
|
36
23
|
print("✨ RinUIWindow Initializing")
|
37
24
|
|
25
|
+
# 退出清理
|
26
|
+
app_instance = QCoreApplication.instance()
|
27
|
+
if not app_instance:
|
28
|
+
raise RuntimeError("QApplication must be created before RinUIWindow.")
|
29
|
+
|
38
30
|
self.engine = QQmlApplicationEngine()
|
39
31
|
self.theme_manager = ThemeManager()
|
40
32
|
self.qml_path = qml_path
|
41
33
|
self.autoSetWindowsEffect = True
|
42
34
|
|
35
|
+
app_instance.aboutToQuit.connect(self.theme_manager.clean_up)
|
43
36
|
self._setup_application()
|
44
37
|
self.print_startup_info()
|
45
38
|
|
46
|
-
|
47
|
-
app_instance = QCoreApplication.instance()
|
48
|
-
if app_instance:
|
49
|
-
app_instance.aboutToQuit.connect(self.theme_manager.clean_up)
|
50
|
-
|
51
|
-
def _setup_application(self):
|
39
|
+
def _setup_application(self) -> None:
|
52
40
|
"""Setup"""
|
53
41
|
# RInUI 模块
|
54
|
-
|
55
|
-
print(f"UI Module Path: {rinui_import_path}")
|
42
|
+
print(f"UI Module Path: {RINUI_PATH}")
|
56
43
|
|
57
|
-
if os.path.exists(
|
58
|
-
self.engine.addImportPath(
|
44
|
+
if os.path.exists(RINUI_PATH):
|
45
|
+
self.engine.addImportPath(RINUI_PATH)
|
59
46
|
else:
|
60
|
-
raise FileNotFoundError(f"Cannot find RinUI module: {
|
47
|
+
raise FileNotFoundError(f"Cannot find RinUI module: {RINUI_PATH}")
|
61
48
|
|
62
49
|
# 主题管理器
|
63
50
|
self.engine.rootContext().setContextProperty("ThemeManager", self.theme_manager)
|
@@ -77,8 +64,8 @@ class RinUIWindow:
|
|
77
64
|
|
78
65
|
def setIcon(self, path: str) -> None:
|
79
66
|
"""
|
80
|
-
|
81
|
-
:param path: str,
|
67
|
+
Sets the icon for the application.
|
68
|
+
:param path: str, icon file path (eg = "path/to/icon.png")
|
82
69
|
:return:
|
83
70
|
"""
|
84
71
|
app_instance = QApplication.instance()
|
@@ -88,7 +75,7 @@ class RinUIWindow:
|
|
88
75
|
else:
|
89
76
|
raise RuntimeError("Cannot set icon before QApplication is created.")
|
90
77
|
|
91
|
-
def _apply_windows_effects(self):
|
78
|
+
def _apply_windows_effects(self) -> None:
|
92
79
|
"""
|
93
80
|
Apply Windows effects to the window.
|
94
81
|
:return:
|
@@ -98,7 +85,7 @@ class RinUIWindow:
|
|
98
85
|
self.theme_manager.apply_window_effects()
|
99
86
|
|
100
87
|
# func名称遵循 Qt 命名规范
|
101
|
-
def setBackdropEffect(self, effect: BackdropEffect):
|
88
|
+
def setBackdropEffect(self, effect: BackdropEffect) -> None:
|
102
89
|
"""
|
103
90
|
Sets the backdrop effect for the window. (Only available on Windows)
|
104
91
|
:param effect: BackdropEffect, type of backdrop effect(Acrylic, Mica, Tabbed, None_)
|
@@ -108,7 +95,7 @@ class RinUIWindow:
|
|
108
95
|
raise OSError("Only can set backdrop effect on Windows platform.")
|
109
96
|
self.theme_manager.apply_backdrop_effect(effect.value)
|
110
97
|
|
111
|
-
def setTheme(self, theme: Theme):
|
98
|
+
def setTheme(self, theme: Theme) -> None:
|
112
99
|
"""
|
113
100
|
Sets the theme for the window.
|
114
101
|
:param theme: Theme, type of theme(Auto, Dark, Light)
|
@@ -116,7 +103,7 @@ class RinUIWindow:
|
|
116
103
|
"""
|
117
104
|
self.theme_manager.toggle_theme(theme.value)
|
118
105
|
|
119
|
-
def __getattr__(self, name):
|
106
|
+
def __getattr__(self, name) -> QObject:
|
120
107
|
"""获取 QML 窗口属性"""
|
121
108
|
try:
|
122
109
|
root = object.__getattribute__(self, "root_window")
|
@@ -124,7 +111,7 @@ class RinUIWindow:
|
|
124
111
|
except AttributeError:
|
125
112
|
raise AttributeError(f"\"RinUIWindow\" object has no attribute '{name}'")
|
126
113
|
|
127
|
-
def print_startup_info(self):
|
114
|
+
def print_startup_info(self) -> None:
|
128
115
|
border = "=" * 40
|
129
116
|
print(f"\n{border}")
|
130
117
|
print("✨ RinUIWindow Loaded Successfully!")
|
@@ -4,7 +4,7 @@ import time
|
|
4
4
|
|
5
5
|
from PySide6.QtCore import QObject, Signal, Slot, QThread
|
6
6
|
|
7
|
-
from .config import DEFAULT_CONFIG,
|
7
|
+
from .config import DEFAULT_CONFIG, RinConfig, is_win10, is_windows, is_win11, BackdropEffect
|
8
8
|
import sys
|
9
9
|
import darkdetect
|
10
10
|
|
@@ -99,7 +99,7 @@ class ThemeManager(QObject):
|
|
99
99
|
清理资源并停止主题监听。
|
100
100
|
"""
|
101
101
|
if self.listener:
|
102
|
-
|
102
|
+
RinConfig.save_config()
|
103
103
|
print("Save config.")
|
104
104
|
self.listener.stop()
|
105
105
|
self.listener.wait() # 等待线程结束
|
@@ -129,11 +129,8 @@ class ThemeManager(QObject):
|
|
129
129
|
self.current_theme = DEFAULT_CONFIG["theme"]["current_theme"] # 当前主题
|
130
130
|
self.is_darkdetect_supported = check_darkdetect_support()
|
131
131
|
|
132
|
-
self.config = ConfigCenter(PATH, "rin_ui.json") # 配置中心
|
133
|
-
self.config.load_config(DEFAULT_CONFIG) # 加载配置
|
134
|
-
|
135
132
|
try:
|
136
|
-
self.current_theme =
|
133
|
+
self.current_theme = RinConfig["theme"]["current_theme"]
|
137
134
|
except Exception as e:
|
138
135
|
print(f"Failed to load config because of {e}, using default config")
|
139
136
|
|
@@ -154,7 +151,7 @@ class ThemeManager(QObject):
|
|
154
151
|
self.windows.append(hwnd)
|
155
152
|
print(f"Window handle set: {hwnd}")
|
156
153
|
|
157
|
-
def _handle_system_theme(self
|
154
|
+
def _handle_system_theme(self):
|
158
155
|
if self.current_theme == "Auto":
|
159
156
|
self._update_window_theme()
|
160
157
|
self.themeChanged.emit(self._actual_theme())
|
@@ -190,7 +187,7 @@ class ThemeManager(QObject):
|
|
190
187
|
elif is_win10() and effect_type == BackdropEffect.Acrylic.value:
|
191
188
|
self._apply_win10_effect(effect_type, hwnd)
|
192
189
|
|
193
|
-
|
190
|
+
RinConfig["backdrop_effect"] = effect_type
|
194
191
|
print(
|
195
192
|
f"Applied \"{effect_type.strip().capitalize()}\" effect with "
|
196
193
|
f"{platform.system() + '11' if is_win11() else '10'}"
|
@@ -202,7 +199,7 @@ class ThemeManager(QObject):
|
|
202
199
|
应用 Windows 10 背景效果
|
203
200
|
:param effect_type: str, 背景效果类型(acrylic, tabbed(actually blur)
|
204
201
|
"""
|
205
|
-
backdrop_color =
|
202
|
+
backdrop_color = RinConfig["win10_feat"]["backdrop_dark" if self.is_dark_theme() else "backdrop_light"]
|
206
203
|
|
207
204
|
accent = ACCENT_POLICY()
|
208
205
|
accent.AccentState = ACCENT_STATES[effect_type]
|
@@ -257,8 +254,8 @@ class ThemeManager(QObject):
|
|
257
254
|
ctypes.byref(ctypes.c_int(self.theme_dict[actual_theme])),
|
258
255
|
ctypes.sizeof(ctypes.c_int)
|
259
256
|
)
|
260
|
-
elif is_win10() and
|
261
|
-
self._apply_win10_effect(
|
257
|
+
elif is_win10() and RinConfig["backdrop_effect"] == BackdropEffect.Acrylic.value:
|
258
|
+
self._apply_win10_effect(RinConfig["backdrop_effect"], hwnd)
|
262
259
|
else:
|
263
260
|
print(f"Cannot apply backdrop on {platform.system()}")
|
264
261
|
|
@@ -281,7 +278,7 @@ class ThemeManager(QObject):
|
|
281
278
|
if self.current_theme != theme:
|
282
279
|
print(f"Switching to '{theme}' theme")
|
283
280
|
self.current_theme = theme
|
284
|
-
|
281
|
+
RinConfig["theme"]["current_theme"] = theme
|
285
282
|
self._update_window_theme()
|
286
283
|
self.themeChanged.emit(self._actual_theme())
|
287
284
|
|
@@ -301,18 +298,18 @@ class ThemeManager(QObject):
|
|
301
298
|
@Slot(result=str)
|
302
299
|
def get_backdrop_effect(self):
|
303
300
|
"""获取当前背景效果"""
|
304
|
-
return
|
301
|
+
return RinConfig["backdrop_effect"]
|
302
|
+
|
303
|
+
@Slot(str)
|
304
|
+
def set_theme_color(self, color):
|
305
|
+
"""设置当前主题颜色"""
|
306
|
+
RinConfig["theme_color"] = color
|
307
|
+
RinConfig.save_config()
|
305
308
|
|
306
309
|
@Slot(result=str)
|
307
310
|
def get_theme_color(self):
|
308
311
|
"""获取当前主题颜色"""
|
309
|
-
return
|
310
|
-
|
311
|
-
@Slot(result=str)
|
312
|
-
def set_theme_color(self, color):
|
313
|
-
"""设置当前主题颜色"""
|
314
|
-
self.config["theme_color"] = color
|
315
|
-
self.config.save_config()
|
312
|
+
return RinConfig["theme_color"]
|
316
313
|
|
317
314
|
@Slot(QObject, result=int)
|
318
315
|
def getWindowId(self, window):
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from PySide6.QtCore import QTranslator, QLocale
|
2
|
+
from .config import RINUI_PATH
|
3
|
+
import os
|
4
|
+
|
5
|
+
|
6
|
+
class RinUITranslator(QTranslator):
|
7
|
+
"""
|
8
|
+
RinUI i18n translator.
|
9
|
+
:param locale: QLocale, optional, default is system locale
|
10
|
+
"""
|
11
|
+
def __init__(self, locale: QLocale = QLocale.system().name(), parent=None): # follow system
|
12
|
+
super().__init__(parent)
|
13
|
+
self.load(locale or QLocale())
|
14
|
+
|
15
|
+
def load(self, locale: QLocale) -> bool:
|
16
|
+
"""
|
17
|
+
Load translation file for the given locale.
|
18
|
+
:param locale: QLocale, the locale to load (eg = QLocale(QLocale.Chinese, QLocale.China), QLocale("zh_CN"))
|
19
|
+
:return: bool
|
20
|
+
"""
|
21
|
+
print(f"🌏 Current locale: {locale.name()}")
|
22
|
+
path = os.path.join(RINUI_PATH, "RinUI", "languages", f"{locale.name()}.qm")
|
23
|
+
if not os.path.exists(path):
|
24
|
+
raise FileNotFoundError(f"Cannot find translation file: {path}")
|
25
|
+
return super().load(path)
|
@@ -0,0 +1 @@
|
|
1
|
+
<�d��!�`���
|