vnpy-componentmgr 1.0.0__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.
- vnpy_componentmgr-1.0.0/.gitignore +43 -0
- vnpy_componentmgr-1.0.0/PKG-INFO +55 -0
- vnpy_componentmgr-1.0.0/README.md +31 -0
- vnpy_componentmgr-1.0.0/pyproject.toml +59 -0
- vnpy_componentmgr-1.0.0/scripts/run.py +9 -0
- vnpy_componentmgr-1.0.0/setup.cfg +4 -0
- vnpy_componentmgr-1.0.0/setup.py +19 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr/__init__.py +13 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr/componentmgr.py +179 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr/constants.py +17 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr/locale/__init__.py +11 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr/locale/build_hook.py +23 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr/locale/en/LC_MESSAGES/vnpy.po +657 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr/locale/generate_mo.bat +1 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr/locale/generate_pot.bat +1 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr/locale/vnpy.pot +629 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr/start_ui.py +17 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr/utility.py +114 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr/widgets.py +78 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr.egg-info/PKG-INFO +55 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr.egg-info/SOURCES.txt +23 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr.egg-info/dependency_links.txt +1 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr.egg-info/entry_points.txt +2 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr.egg-info/requires.txt +7 -0
- vnpy_componentmgr-1.0.0/vnpy_componentmgr.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
*.pyc
|
|
3
|
+
*.pyo
|
|
4
|
+
*.pyd
|
|
5
|
+
*.egg-info/
|
|
6
|
+
|
|
7
|
+
# Jupyter
|
|
8
|
+
.ipynb_checkpoints
|
|
9
|
+
|
|
10
|
+
# IDE
|
|
11
|
+
.vscode
|
|
12
|
+
.idea
|
|
13
|
+
*.wpr
|
|
14
|
+
*.wpu
|
|
15
|
+
.vs
|
|
16
|
+
x64
|
|
17
|
+
|
|
18
|
+
# Temp
|
|
19
|
+
build
|
|
20
|
+
dist
|
|
21
|
+
*.local
|
|
22
|
+
|
|
23
|
+
# VeighNa
|
|
24
|
+
.vntrader
|
|
25
|
+
|
|
26
|
+
# Visual Studio intermediate files
|
|
27
|
+
*.exp
|
|
28
|
+
*.iobj
|
|
29
|
+
*.ipdb
|
|
30
|
+
*.pdb
|
|
31
|
+
|
|
32
|
+
# Documents
|
|
33
|
+
_build
|
|
34
|
+
_static
|
|
35
|
+
_templates
|
|
36
|
+
|
|
37
|
+
# Misc
|
|
38
|
+
.DS_Store
|
|
39
|
+
*.mo
|
|
40
|
+
|
|
41
|
+
*.log
|
|
42
|
+
# Alpha
|
|
43
|
+
lab/
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vnpy_componentmgr
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Trade panels for traders' convenience.
|
|
5
|
+
Author-email: YQ Cui <qianyun210603@hotmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Keywords: quant,quantitative,investment,trading,algotrading
|
|
8
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
14
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
15
|
+
Classifier: Natural Language :: Chinese (Simplified)
|
|
16
|
+
Requires-Python: >=3.12
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: PySide6
|
|
19
|
+
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: ruff>=0.0.263; extra == "dev"
|
|
21
|
+
Requires-Dist: setuptools_scm>=8; extra == "dev"
|
|
22
|
+
Requires-Dist: setuptools>=64; extra == "dev"
|
|
23
|
+
Requires-Dist: wheel; extra == "dev"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
<h1 style="text-align: center;">VeighNa框架的模块管理器</h1>
|
|
27
|
+
|
|
28
|
+
***
|
|
29
|
+
|
|
30
|
+
<p style="text-align: center;">
|
|
31
|
+
<img src ="https://img.shields.io/badge/version-1.0.0-blueviolet.svg" alt=""/>
|
|
32
|
+
<img src ="https://img.shields.io/badge/platform-windows|linux-yellow.svg" alt=""/>
|
|
33
|
+
<img src ="https://img.shields.io/badge/python-3.11|3.12|3.13-blue.svg" alt=""/>
|
|
34
|
+
<img src ="https://img.shields.io/github/license/vnpy/vnpy.svg?color=orange" alt=""/>
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
## 说明
|
|
38
|
+
|
|
39
|
+
管理vnpy模块的安装/更新和加载。
|
|
40
|
+
|
|
41
|
+
## 安装
|
|
42
|
+
|
|
43
|
+
安装环境推荐基于4.3.0.5版本以上的【[**VeighNa Studio**](https://www.vnpy.com)】。
|
|
44
|
+
|
|
45
|
+
直接使用pip命令:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
pip install vnpy_componentmgr
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
或者下载源代码后,解压后在cmd中运行:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
pip install .
|
|
55
|
+
```
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
<h1 style="text-align: center;">VeighNa框架的模块管理器</h1>
|
|
3
|
+
|
|
4
|
+
***
|
|
5
|
+
|
|
6
|
+
<p style="text-align: center;">
|
|
7
|
+
<img src ="https://img.shields.io/badge/version-1.0.0-blueviolet.svg" alt=""/>
|
|
8
|
+
<img src ="https://img.shields.io/badge/platform-windows|linux-yellow.svg" alt=""/>
|
|
9
|
+
<img src ="https://img.shields.io/badge/python-3.11|3.12|3.13-blue.svg" alt=""/>
|
|
10
|
+
<img src ="https://img.shields.io/github/license/vnpy/vnpy.svg?color=orange" alt=""/>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
## 说明
|
|
14
|
+
|
|
15
|
+
管理vnpy模块的安装/更新和加载。
|
|
16
|
+
|
|
17
|
+
## 安装
|
|
18
|
+
|
|
19
|
+
安装环境推荐基于4.3.0.5版本以上的【[**VeighNa Studio**](https://www.vnpy.com)】。
|
|
20
|
+
|
|
21
|
+
直接使用pip命令:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
pip install vnpy_componentmgr
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
或者下载源代码后,解压后在cmd中运行:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
pip install .
|
|
31
|
+
```
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=64", "wheel", "setuptools_scm>=8"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "vnpy_componentmgr"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
license = "MIT"
|
|
9
|
+
authors = [{ name = "YQ Cui", email = "qianyun210603@hotmail.com" }]
|
|
10
|
+
description = "Trade panels for traders' convenience."
|
|
11
|
+
readme = { file = "README.md", content-type = "text/markdown" }
|
|
12
|
+
keywords = ["quant", "quantitative", "investment", "trading", "algotrading"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 5 - Production/Stable",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.12",
|
|
18
|
+
"Programming Language :: Python :: 3.13",
|
|
19
|
+
"Topic :: Office/Business :: Financial :: Investment",
|
|
20
|
+
"Programming Language :: Python :: Implementation :: CPython",
|
|
21
|
+
"Natural Language :: Chinese (Simplified)"]
|
|
22
|
+
requires-python = ">=3.12"
|
|
23
|
+
|
|
24
|
+
dependencies = [
|
|
25
|
+
"PySide6",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.optional-dependencies]
|
|
29
|
+
dev = [
|
|
30
|
+
"ruff>=0.0.263",
|
|
31
|
+
"setuptools_scm>=8",
|
|
32
|
+
"setuptools>=64",
|
|
33
|
+
"wheel",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.scripts]
|
|
37
|
+
vnpy_componentmgr = "vnpy_componentmgr.start_ui:run_module_manager"
|
|
38
|
+
|
|
39
|
+
[tool.setuptools]
|
|
40
|
+
include-package-data = true
|
|
41
|
+
|
|
42
|
+
[tool.setuptools_scm]
|
|
43
|
+
|
|
44
|
+
[tool.ruff]
|
|
45
|
+
target-version = "py313"
|
|
46
|
+
output-format = "full"
|
|
47
|
+
line-length = 120
|
|
48
|
+
exclude = ["*.ipynb"]
|
|
49
|
+
|
|
50
|
+
[tool.ruff.lint]
|
|
51
|
+
select = [
|
|
52
|
+
"B", # flake8-bugbear
|
|
53
|
+
"E", # pycodestyle error
|
|
54
|
+
"F", # pyflakes
|
|
55
|
+
"UP", # pyupgrade
|
|
56
|
+
"W", # pycodestyle warning
|
|
57
|
+
"PL" # pylint
|
|
58
|
+
]
|
|
59
|
+
ignore = ["UP008", "E501", "PLR0913", "I001", "PLR2004", "PLR0915", "B027", "PLR5501", "PLR0912", "PLR0911"]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from setuptools_scm.version import ScmVersion, guess_next_version
|
|
2
|
+
from setuptools import setup
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def custom_local_scheme(version: ScmVersion):
|
|
6
|
+
if version.exact:
|
|
7
|
+
return ""
|
|
8
|
+
else:
|
|
9
|
+
return "+git." + version.node[1:8] if version.node else ""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def custom_version_scheme(version: ScmVersion):
|
|
13
|
+
if version.exact:
|
|
14
|
+
return version.format_with("{tag}")
|
|
15
|
+
else:
|
|
16
|
+
return guess_next_version(version)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
setup(use_scm_version={"version_scheme": custom_version_scheme, "local_scheme": custom_local_scheme})
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# @Time : 2026/4/6 14:19
|
|
2
|
+
# @Author : YQ Tsui
|
|
3
|
+
# @File : __init__.py.py
|
|
4
|
+
# @Purpose :
|
|
5
|
+
|
|
6
|
+
import importlib.metadata as importlib_metadata
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
__version__ = importlib_metadata.version("vnpy_componentmgr")
|
|
10
|
+
except importlib_metadata.PackageNotFoundError:
|
|
11
|
+
__version__ = "dev"
|
|
12
|
+
|
|
13
|
+
__all__ = ["ComponentManagementDialog"]
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# @Time : 2026/4/6 15:07
|
|
2
|
+
# @Author : YQ Tsui
|
|
3
|
+
# @File : componentmgr.py
|
|
4
|
+
# @Purpose :
|
|
5
|
+
|
|
6
|
+
from functools import partial
|
|
7
|
+
from vnpy.trader.utility import (
|
|
8
|
+
load_json,
|
|
9
|
+
save_json,
|
|
10
|
+
)
|
|
11
|
+
from vnpy.trader.ui import QtWidgets, Qt
|
|
12
|
+
from vnpy.trader.locale import _
|
|
13
|
+
|
|
14
|
+
from . import __version__
|
|
15
|
+
from .constants import AVAILABLE_APP, AVAILABLE_GATEWAY, VNPY_URL
|
|
16
|
+
from .widgets import UpdatingProgressBar
|
|
17
|
+
from .utility import get_local_version, get_remote_version
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ComponentManagementDialog(QtWidgets.QDialog):
|
|
21
|
+
def __init__(self, parent=None) -> None:
|
|
22
|
+
""""""
|
|
23
|
+
super().__init__(parent)
|
|
24
|
+
self.row_mapping = {}
|
|
25
|
+
self.update_progress = None
|
|
26
|
+
self.selected_modules = load_json("vnpy_selectmodules.json")
|
|
27
|
+
self.init_ui()
|
|
28
|
+
|
|
29
|
+
def init_ui(self) -> None:
|
|
30
|
+
""""""
|
|
31
|
+
self.setWindowTitle(_(f"模块管理 - 选择要启用的模块和更新模块 (v{__version__})"))
|
|
32
|
+
|
|
33
|
+
self.select_module_at_start_checkbox = QtWidgets.QCheckBox(_("启动vnpy时选择模块?"))
|
|
34
|
+
self.select_module_at_start_checkbox.setChecked(self.selected_modules.get("select_at_start_up", True))
|
|
35
|
+
|
|
36
|
+
self.modules_grid = QtWidgets.QTableWidget()
|
|
37
|
+
self.modules_grid.setColumnCount(6)
|
|
38
|
+
self.modules_grid.setColumnWidth(0, 100)
|
|
39
|
+
self.modules_grid.setColumnWidth(1, 200)
|
|
40
|
+
self.modules_grid.setColumnWidth(2, 150)
|
|
41
|
+
self.modules_grid.setColumnWidth(3, 150)
|
|
42
|
+
self.modules_grid.setColumnWidth(4, 60)
|
|
43
|
+
self.modules_grid.setColumnWidth(5, 40)
|
|
44
|
+
self.modules_grid.setHorizontalHeaderLabels(
|
|
45
|
+
[_("模块"), _("Python包"), _("本地版本"), _("最新版本"), _("更新"), _("启用")]
|
|
46
|
+
)
|
|
47
|
+
self.modules_grid.setRowCount(0)
|
|
48
|
+
self.modules_grid.verticalHeader().setVisible(False)
|
|
49
|
+
self.modules_grid.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers)
|
|
50
|
+
self.modules_grid.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
|
51
|
+
button_box = QtWidgets.QDialogButtonBox()
|
|
52
|
+
ok_button = button_box.addButton(_("保存并退出"), QtWidgets.QDialogButtonBox.AcceptRole)
|
|
53
|
+
ok_button.clicked.connect(self.accept)
|
|
54
|
+
cancel_button = button_box.addButton(_("取消"), QtWidgets.QDialogButtonBox.RejectRole)
|
|
55
|
+
cancel_button.clicked.connect(self.reject)
|
|
56
|
+
self.modules_grid.setCellWidget(0, 4, button_box)
|
|
57
|
+
|
|
58
|
+
total_height = self.modules_grid.frameWidth() * 2 + self.modules_grid.horizontalHeader().height()
|
|
59
|
+
|
|
60
|
+
self._add_row(_("核心"), "vnpy", VNPY_URL, True)
|
|
61
|
+
total_height += self.modules_grid.rowHeight(0)
|
|
62
|
+
|
|
63
|
+
for appname, giturl in AVAILABLE_APP.items():
|
|
64
|
+
selected = appname in self.selected_modules.get("APPs", [])
|
|
65
|
+
self._add_row(appname, f"vnpy_{appname.lower()}", giturl, selected)
|
|
66
|
+
total_height += self.modules_grid.rowHeight(self.modules_grid.rowCount() - 1)
|
|
67
|
+
|
|
68
|
+
for gwname, giturl in AVAILABLE_GATEWAY.items():
|
|
69
|
+
selected = gwname in self.selected_modules.get("Gateways", [])
|
|
70
|
+
self._add_row(gwname, f"vnpy_{gwname.lower()}", giturl, selected)
|
|
71
|
+
total_height += self.modules_grid.rowHeight(self.modules_grid.rowCount() - 1)
|
|
72
|
+
|
|
73
|
+
self.modules_grid.setFixedSize(720, min(900, total_height + 8))
|
|
74
|
+
|
|
75
|
+
self.vbox: QtWidgets.QVBoxLayout = QtWidgets.QVBoxLayout()
|
|
76
|
+
self.vbox.addWidget(self.select_module_at_start_checkbox)
|
|
77
|
+
self.vbox.addWidget(self.modules_grid)
|
|
78
|
+
self.vbox.addWidget(button_box)
|
|
79
|
+
|
|
80
|
+
self.setLayout(self.vbox)
|
|
81
|
+
self.setFixedWidth(self.sizeHint().width())
|
|
82
|
+
|
|
83
|
+
def _add_row(self, app_or_gw_name: str, module_name: str, git_url: str, selected=False, style=None) -> None:
|
|
84
|
+
"""
|
|
85
|
+
Add a row to the modules grid.
|
|
86
|
+
"""
|
|
87
|
+
row = self.modules_grid.rowCount()
|
|
88
|
+
self.modules_grid.insertRow(row)
|
|
89
|
+
self.row_mapping[app_or_gw_name] = row
|
|
90
|
+
cell_name = QtWidgets.QTableWidgetItem(app_or_gw_name) # app or gateway name
|
|
91
|
+
self.modules_grid.setItem(row, 0, cell_name)
|
|
92
|
+
cell_module_name = QtWidgets.QTableWidgetItem(module_name) # module name
|
|
93
|
+
self.modules_grid.setItem(row, 1, cell_module_name)
|
|
94
|
+
self.row_mapping[module_name] = row
|
|
95
|
+
local_version = get_local_version(module_name)
|
|
96
|
+
|
|
97
|
+
cell_local = QtWidgets.QTableWidgetItem(local_version) # local version
|
|
98
|
+
self.modules_grid.setItem(row, 2, cell_local)
|
|
99
|
+
|
|
100
|
+
remote_version = self._get_remote_version(git_url)
|
|
101
|
+
cell_latest = QtWidgets.QTableWidgetItem(remote_version)
|
|
102
|
+
self.modules_grid.setItem(row, 3, cell_latest)
|
|
103
|
+
|
|
104
|
+
button = QtWidgets.QPushButton(_("安装") if local_version == "--" else _("更新"))
|
|
105
|
+
button.setObjectName(app_or_gw_name)
|
|
106
|
+
button.setEnabled(bool(remote_version) and remote_version not in ("--", local_version))
|
|
107
|
+
button.clicked.connect(partial(self.update_module, row_idx=row, git_url=git_url))
|
|
108
|
+
self.modules_grid.setCellWidget(row, 4, button)
|
|
109
|
+
|
|
110
|
+
cell_selected = QtWidgets.QTableWidgetItem()
|
|
111
|
+
cell_selected.setCheckState(Qt.Checked if selected else Qt.Unchecked)
|
|
112
|
+
if app_or_gw_name == _("核心"):
|
|
113
|
+
cell_selected.setFlags(~Qt.ItemIsUserCheckable & Qt.ItemIsEnabled)
|
|
114
|
+
self.modules_grid.setItem(row, 5, cell_selected)
|
|
115
|
+
|
|
116
|
+
@staticmethod
|
|
117
|
+
def _get_remote_version(url: str) -> str:
|
|
118
|
+
"""
|
|
119
|
+
Get the remote version of the module.
|
|
120
|
+
"""
|
|
121
|
+
try:
|
|
122
|
+
return get_remote_version(url)
|
|
123
|
+
except Exception:
|
|
124
|
+
return "--"
|
|
125
|
+
|
|
126
|
+
def set_button_status(self, row_num: int) -> None:
|
|
127
|
+
remote_version = self.modules_grid.item(row_num, 2).text()
|
|
128
|
+
local_version = self.modules_grid.item(row_num, 1).text()
|
|
129
|
+
if remote_version and remote_version != local_version and _("更新") not in local_version:
|
|
130
|
+
button = self.modules_grid.cellWidget(row_num, 3)
|
|
131
|
+
button.setEnabled(True)
|
|
132
|
+
|
|
133
|
+
def update_module(self, row_idx: int, git_url: str) -> None:
|
|
134
|
+
related_module_name = self.modules_grid.item(row_idx, 1).text().strip()
|
|
135
|
+
if not related_module_name:
|
|
136
|
+
QtWidgets.QMessageBox.warning(self, _("错误"), _("无法获取模块名称,无法更新"))
|
|
137
|
+
return
|
|
138
|
+
for row in range(self.modules_grid.rowCount()):
|
|
139
|
+
button = self.modules_grid.cellWidget(row, 4)
|
|
140
|
+
button.setEnabled(False)
|
|
141
|
+
self.update_progress = UpdatingProgressBar(related_module_name, git_url, self)
|
|
142
|
+
self.vbox.insertWidget(0, self.update_progress)
|
|
143
|
+
QtWidgets.QApplication.processEvents()
|
|
144
|
+
local_version = self.modules_grid.item(row_idx, 2).text().strip()
|
|
145
|
+
install_or_update = _("安装") if local_version in {"--", ""} else _("更新")
|
|
146
|
+
self.update_progress.label.setText(install_or_update)
|
|
147
|
+
self.update_progress.run_update(partial(self.on_update_completed, text=install_or_update))
|
|
148
|
+
|
|
149
|
+
def on_update_completed(self, progressor: UpdatingProgressBar, text: str) -> None:
|
|
150
|
+
cell = self.modules_grid.item(self.row_mapping[progressor.module_name], 2)
|
|
151
|
+
if progressor.error_flag:
|
|
152
|
+
QtWidgets.QMessageBox.critical(self, _(f"{text}失败"), progressor.error_reason + "\n")
|
|
153
|
+
cell.setText(_(f"{text}失败,联系管理员修复。"))
|
|
154
|
+
else:
|
|
155
|
+
cell.setText(_(f"已{text},重启vnpy生效"))
|
|
156
|
+
for row in range(self.modules_grid.rowCount()):
|
|
157
|
+
self.set_button_status(row)
|
|
158
|
+
self.vbox.removeWidget(progressor)
|
|
159
|
+
self.progressor = None
|
|
160
|
+
|
|
161
|
+
def save_selection(self):
|
|
162
|
+
select_at_start_up = self.select_module_at_start_checkbox.isChecked()
|
|
163
|
+
selected_apps = []
|
|
164
|
+
selected_gateways = []
|
|
165
|
+
for row in range(self.modules_grid.rowCount()):
|
|
166
|
+
module_name = self.modules_grid.item(row, 0).text()
|
|
167
|
+
if self.modules_grid.item(row, 5).checkState() == Qt.Checked:
|
|
168
|
+
if module_name in AVAILABLE_APP:
|
|
169
|
+
selected_apps.append(module_name)
|
|
170
|
+
elif module_name in AVAILABLE_GATEWAY:
|
|
171
|
+
selected_gateways.append(module_name)
|
|
172
|
+
self.selected_modules["select_at_start_up"] = select_at_start_up
|
|
173
|
+
self.selected_modules["APPs"] = selected_apps
|
|
174
|
+
self.selected_modules["Gateways"] = selected_gateways
|
|
175
|
+
save_json("vnpy_selectmodules.json", self.selected_modules)
|
|
176
|
+
|
|
177
|
+
def accept(self, /):
|
|
178
|
+
self.save_selection()
|
|
179
|
+
super().accept()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# @Time : 2026/4/6 14:21
|
|
2
|
+
# @Author : YQ Tsui
|
|
3
|
+
# @File : constants.py
|
|
4
|
+
# @Purpose :
|
|
5
|
+
|
|
6
|
+
VNPY_URL = "ssh://git@gitee.com/arb513330/vnpy.git"
|
|
7
|
+
|
|
8
|
+
AVAILABLE_GATEWAY = {
|
|
9
|
+
"Ctp": "ssh://git@gitee.com/arb513330/vnpy_ctp.git",
|
|
10
|
+
"Sopt": "ssh://git@gitee.com/arb513330/vnpy_sopt.git",
|
|
11
|
+
"Xt": "ssh://git@gitee.com/arb513330/vnpy_xt.git",
|
|
12
|
+
"XtRedisOrder": "ssh://git@gitee.com/arb513330/vnpy_xtredisorder.git",
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
AVAILABLE_APP = {
|
|
16
|
+
"TradePanels": "ssh://git@gitee.com/arb513330/vnpy_tradepanels.git",
|
|
17
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import gettext
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
localedir: Path = Path(__file__).parent
|
|
6
|
+
|
|
7
|
+
translations: gettext.GNUTranslations | gettext.NullTranslations = gettext.translation(
|
|
8
|
+
"vnpy", localedir=localedir, fallback=True
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
_ = translations.gettext
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
|
4
|
+
from babel.messages.mofile import write_mo
|
|
5
|
+
from babel.messages.pofile import read_po
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LocaleBuildHook(BuildHookInterface):
|
|
9
|
+
"""Custom build hook for generating .mo files."""
|
|
10
|
+
|
|
11
|
+
def initialize(self, version: str, build_data: dict) -> None:
|
|
12
|
+
"""Initialize the build hook"""
|
|
13
|
+
# Only generate mo file when building wheel
|
|
14
|
+
if "pure_python" not in build_data:
|
|
15
|
+
return
|
|
16
|
+
|
|
17
|
+
self.locale_path: Path = Path(self.root).joinpath("vnpy", "trader", "locale")
|
|
18
|
+
self.mo_path: Path = self.locale_path.joinpath("en", "LC_MESSAGES", "vnpy.mo")
|
|
19
|
+
self.po_path: Path = self.locale_path.joinpath("en", "LC_MESSAGES", "vnpy.po")
|
|
20
|
+
|
|
21
|
+
with open(self.mo_path, "wb") as mo_f:
|
|
22
|
+
with open(self.po_path, encoding="utf-8") as po_f:
|
|
23
|
+
write_mo(mo_f, read_po(po_f))
|