pyscreeps-arena 0.5.3.2__tar.gz → 0.5.4a0__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.
Files changed (26) hide show
  1. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/PKG-INFO +2 -1
  2. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena/__init__.py +18 -0
  3. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena/compiler.py +175 -8
  4. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena/core/const.py +1 -1
  5. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena/localization.py +6 -0
  6. pyscreeps_arena-0.5.4a0/pyscreeps_arena/project.7z +0 -0
  7. pyscreeps_arena-0.5.4a0/pyscreeps_arena/ui/P2PY.py +105 -0
  8. pyscreeps_arena-0.5.4a0/pyscreeps_arena/ui/__init__.py +10 -0
  9. pyscreeps_arena-0.5.4a0/pyscreeps_arena/ui/project_ui.py +213 -0
  10. pyscreeps_arena-0.5.4a0/pyscreeps_arena/ui/rs_icon.py +28 -0
  11. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena.egg-info/PKG-INFO +2 -1
  12. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena.egg-info/SOURCES.txt +5 -1
  13. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena.egg-info/entry_points.txt +1 -0
  14. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena.egg-info/requires.txt +1 -0
  15. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/setup.py +3 -1
  16. pyscreeps_arena-0.5.3.2/pyscreeps_arena/project.7z +0 -0
  17. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena/build.py +0 -0
  18. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena/core/__init__.py +0 -0
  19. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena/core/basic.py +0 -0
  20. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena/core/config.py +0 -0
  21. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena/core/core.py +0 -0
  22. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena/core/main.py +0 -0
  23. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena/core/utils.py +0 -0
  24. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena.egg-info/dependency_links.txt +0 -0
  25. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/pyscreeps_arena.egg-info/top_level.txt +0 -0
  26. {pyscreeps_arena-0.5.3.2 → pyscreeps_arena-0.5.4a0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscreeps-arena
3
- Version: 0.5.3.2
3
+ Version: 0.5.4a0
4
4
  Summary: Python api|interface to play game: Screeps: Arena.
5
5
  Author-email: 2229066748@qq.com
6
6
  Maintainer: Eagle'sBaby
@@ -16,6 +16,7 @@ Requires-Dist: colorama
16
16
  Requires-Dist: py7zr
17
17
  Requires-Dist: chardet
18
18
  Requires-Dist: Transcrypt==3.9.1
19
+ Requires-Dist: PyQt6
19
20
  Requires-Dist: mkdocs
20
21
  Requires-Dist: mkdocstrings[python]
21
22
  Requires-Dist: mkdocs-material
@@ -24,6 +24,24 @@ def CMD_NewProject():
24
24
  extract_7z(os.path.join(this_path, 'project.7z'), project_path)
25
25
  print("Project created at", project_path)
26
26
 
27
+ def CMD_OpenUI():
28
+ """
29
+ cmd:
30
+ psaui
31
+
32
+ * 打开UI界面
33
+
34
+ Returns:
35
+
36
+ """
37
+ try:
38
+ from pyscreeps_arena.ui.project_ui import run_project_creator
39
+ run_project_creator()
40
+ except ImportError as e:
41
+ print(f"错误: 无法导入UI模块 - {e}")
42
+ print("请确保已安装PyQt6: pip install PyQt6")
43
+ except Exception as e:
44
+ print(f"错误: 打开UI界面失败 - {e}")
27
45
 
28
46
  def extract_7z(file_path, output_dir):
29
47
  with py7zr.SevenZipFile(file_path, mode='r') as archive:
@@ -16,6 +16,27 @@ python_version_info = sys.version_info
16
16
  python_version_info = f"{python_version_info.major}.{python_version_info.minor}.{python_version_info.micro}"
17
17
 
18
18
 
19
+ def replace_src_prefix(file_list):
20
+ """
21
+ 将列表中以'./src.'开头的字符串替换为'./'
22
+
23
+ 参数:
24
+ file_list: 字符串列表
25
+
26
+ 返回:
27
+ 替换后的新列表
28
+ """
29
+ _ = []
30
+
31
+ for item in file_list:
32
+ if isinstance(item, str) and item.startswith('./src.'):
33
+ _new = item.replace('./src.', './', 1)
34
+ if _new in file_list:
35
+ continue
36
+ _.append(item)
37
+
38
+ return _
39
+
19
40
  # def InsertPragmaBefore(content:str) -> str:
20
41
  # """
21
42
  # 在content的开头插入__pragma__('noalias', 'undefined')等内容 |
@@ -85,7 +106,7 @@ export var loop = function () {
85
106
  }
86
107
  step (know);
87
108
  timeLine = get.cpu_us();
88
- sch.handle();
109
+ if (get._SCH_FLAG) sch.handle();
89
110
  stepCost = get.cpu_us() - timeLine;
90
111
  std.show_usage ();
91
112
  print("knowCost:", knowCost, "monitorCost:", monitorCost, "stepCost:", stepCost);
@@ -318,6 +339,102 @@ class Compiler_Utils(Compiler_Const):
318
339
 
319
340
  return '\n'.join(result) # 将处理后的所有代码行连接成一个字符串,并返回最终结果 | join all processed lines into a string and return
320
341
 
342
+ def expand_folder_imports(self, fpath: str, project_path: str = None):
343
+ """
344
+ 扩展文件夹导入语句:将 `from folder import *` 替换为 `from folder.module import *`
345
+ 仅在文件夹没有 __init__.py 时执行此操作
346
+
347
+ :param fpath: 要处理的文件路径
348
+ :param project_path: 项目根路径,用于解析相对导入,默认为 None(使用文件所在目录)
349
+ """
350
+ if not os.path.exists(fpath):
351
+ return
352
+
353
+ content = self.auto_read(fpath)
354
+ lines = content.split('\n')
355
+ new_lines = []
356
+ changed = False
357
+
358
+ for line in lines:
359
+ m = self.PY_IMPORT_PAT.match(line)
360
+ if not m:
361
+ new_lines.append(line)
362
+ continue
363
+
364
+ original_target = m.group(1)
365
+ target = original_target
366
+ target_path = project_path or os.path.dirname(fpath)
367
+
368
+ # 处理相对路径(向前定位)
369
+ if target.startswith('.'):
370
+ target_path = os.path.dirname(fpath)
371
+ count = 0
372
+ for c in target:
373
+ if c == '.':
374
+ count += 1
375
+ else:
376
+ break
377
+
378
+ # 向上移动目录
379
+ if count > 1:
380
+ for _ in range(count - 1):
381
+ target_path = os.path.dirname(target_path)
382
+
383
+ # 移除开头的点
384
+ target = target[count:]
385
+
386
+ # 如果 target 为空,跳过
387
+ if not target:
388
+ new_lines.append(line)
389
+ continue
390
+
391
+ # 向后定位,构建完整路径
392
+ temp_target = target
393
+ while (_idx := temp_target.find('.')) != -1:
394
+ part = temp_target[:_idx]
395
+ target_path = os.path.join(target_path, part)
396
+ temp_target = temp_target[_idx + 1:]
397
+
398
+ # 最终的文件夹路径
399
+ final_dir_path = os.path.join(target_path, temp_target) if temp_target else target_path
400
+
401
+ # 检查是否是文件夹且没有 __init__.py
402
+ if os.path.isdir(final_dir_path):
403
+ init_path = os.path.join(final_dir_path, '__init__.py')
404
+ if not os.path.exists(init_path):
405
+ # 找到所有 .py 文件(排除 __init__.py)| 如果包含子目录,产生一个警告
406
+ # try:
407
+ # py_files = [f for f in os.listdir(final_dir_path) if f.endswith('.py') and f != '__init__.py']
408
+ # except (FileNotFoundError, PermissionError):
409
+ py_files = []
410
+ for item in os.listdir(final_dir_path):
411
+ _path = os.path.join(final_dir_path, item)
412
+ if os.path.isfile(_path) and item.endswith('.py') and item != '__init__.py':
413
+ py_files.append(item)
414
+ elif os.path.isdir(_path):
415
+ rel = os.path.relpath(final_dir_path, project_path)
416
+ core.warn(f'Compiler.expand_folder_imports', core.lformat(LOC_DIR_UNDER_NONINIT_DIR, [item, rel]), end='', head='\n', ln=config.language )
417
+
418
+
419
+ # 为每个 .py 文件生成导入语句
420
+ if py_files:
421
+ for py_file in py_files:
422
+ module_name = py_file[:-3]
423
+ new_import = f"from {original_target}.{module_name} import *"
424
+ new_lines.append(new_import)
425
+ changed = True
426
+ continue
427
+
428
+ # 保留原行
429
+ new_lines.append(line)
430
+
431
+ # 如果文件有修改,写回
432
+ if changed:
433
+ new_content = '\n'.join(new_lines)
434
+ with open(fpath, 'w', encoding='utf-8') as f:
435
+ f.write(new_content)
436
+
437
+
321
438
  def find_chain_import(self, fpath: str, search_dirs: list[str], project_path: str = None, records: dict[str, None] = None) -> list[str]:
322
439
  r"""
323
440
  查找文件中的所有import语句,并返回所有import的文件路径 | find all import statements in a file and return the paths of all imported files
@@ -468,15 +585,63 @@ class Compiler_Utils(Compiler_Const):
468
585
  return jsimps
469
586
 
470
587
  # ---------- 自定义函数 ---------- #
588
+
471
589
  @staticmethod
472
- def stage_recursive_replace(content:str) -> str:
473
- r"""
474
- 替换'@recursive'为'@recursive(<fname>)', 其中<fname>为被装饰器标记的函数名 |
475
- Replace '@recursive' with '@recursive(<fname>)', where <fname> is the name of the decorated function.
590
+ def stage_recursive_replace(content: str) -> str:
591
+ """
592
+ 移除 '@recursive' 装饰器行,并在文末添加对应的 _recursiveLogin 调用。
476
593
 
477
- @\s*recursive\s+def\s+([^\s\(]+)
594
+ 对于类方法: _recursiveLogin("ClassName", "method_name")
595
+ 对于普通函数: _recursiveLogin("", "function_name")
478
596
  """
479
- return re.sub(r'@\s*recursive(\s+def\s+)([^\s\(]+)', r'@recursive("\2")\1\2', content)
597
+ calls_to_add = []
598
+ deletions = []
599
+
600
+ # 1. 收集所有类定义的位置和缩进
601
+ class_pattern = re.compile(r'^(\s*)class\s+(\w+)', re.MULTILINE)
602
+ classes = [(m.start(), len(m.group(1)), m.group(2))
603
+ for m in class_pattern.finditer(content)]
604
+
605
+ # 2. 查找所有 @recursive 装饰器
606
+ decorator_pattern = re.compile(r'^\s*@\s*recursive\s*$\n?', re.MULTILINE)
607
+
608
+ for dec_match in decorator_pattern.finditer(content):
609
+ dec_end = dec_match.end()
610
+
611
+ # 查找接下来的函数定义(跳过可能的空行)
612
+ after_decorator = content[dec_end:]
613
+ func_match = re.search(r'^(\s*)def\s+([^\s\(]+)', after_decorator, re.MULTILINE)
614
+
615
+ if not func_match:
616
+ continue
617
+
618
+ func_indent_len = len(func_match.group(1))
619
+ func_name = func_match.group(2)
620
+
621
+ # 3. 确定类名:查找装饰器前最近的、缩进小于函数缩进的类
622
+ class_name = ""
623
+ for cls_pos, cls_indent_len, cls_name in reversed(classes):
624
+ if cls_pos < dec_match.start() and func_indent_len > cls_indent_len:
625
+ class_name = cls_name
626
+ break
627
+
628
+ # 4. 记录删除位置和调用信息
629
+ deletions.append((dec_match.start(), dec_end))
630
+ calls_to_add.append(f'_recursiveLogin("{class_name}", "{func_name}")')
631
+
632
+ # 5. 应用删除(倒序避免位置偏移)
633
+ if not deletions:
634
+ return content
635
+
636
+ result = content
637
+ for start, end in sorted(deletions, key=lambda x: x[0], reverse=True):
638
+ result = result[:start] + result[end:]
639
+
640
+ # 6. 在文末添加调用
641
+ if calls_to_add:
642
+ result = '\n'.join(calls_to_add) + '\n' + result
643
+
644
+ return result
480
645
 
481
646
  @staticmethod
482
647
  def process_mate_code(code):
@@ -626,6 +791,8 @@ class Compiler(CompilerBase):
626
791
  if m and (not m.group(2) or m.group(2)[0] != '*'):
627
792
  core.error('Compiler.pre_compile', core.lformat(LOC_IMPORT_STAR2_ERROR, [m.group(1), m.group(2), m.group(1)]), head='\n', ln=config.language)
628
793
 
794
+ self.expand_folder_imports(fpath, self.build_dir)
795
+
629
796
  # -------------------------------- EXPAND IMPORT * -------------------------------- #
630
797
  _imports = self.find_chain_import(self.target_py, [os.path.dirname(self.src_dir), self.src_dir])
631
798
  _js_imports = self.relist_pyimports_to_jsimports(self.build_dir, _imports)
@@ -978,7 +1145,7 @@ class Compiler(CompilerBase):
978
1145
  self.transcrypt_cmd()
979
1146
  imports, modules = self.analyze_rebuild_main_js(defs, jimps)
980
1147
  self.find_add_pure_js_files(sorts, modules)
981
- total_js = imports + "\n" + self.generate_total_js(modules, imps, sorts, self.FILE_STRONG_REPLACE, reps)
1148
+ total_js = imports + "\n" + self.generate_total_js(replace_src_prefix(modules), imps, sorts, self.FILE_STRONG_REPLACE, reps)
982
1149
 
983
1150
  core.lprint(WAIT, LOC_EXPORTING_TOTAL_MAIN_JS, end="", ln=config.language)
984
1151
 
@@ -9,7 +9,7 @@
9
9
  #
10
10
  import re
11
11
 
12
- VERSION = "0.5.3.2"
12
+ VERSION = "0.5.4.0"
13
13
  AUTHOR = "●ω<🤍♪"
14
14
  STEAM_ID = "1029562896"
15
15
  GITHUB_NAME = "EagleBaby"
@@ -135,6 +135,12 @@ LOC_NOT_SUPPORT_PYFILE_INIT = {
135
135
  'cn': '不支持 __init__.py!请删除它(初始化文件)并使用 from directory.xxx import xxxx 代替之。',
136
136
  }
137
137
 
138
+ # V0.5.4
139
+ LOC_DIR_UNDER_NONINIT_DIR = {
140
+ 'en': "Directory [{}] is located under [{}] without __init__.py, therefore it is ignored.",
141
+ 'cn': "目录 [{}] 位于 `无__init__.py`的目录[{}]下,因此被忽略。",
142
+ }
143
+
138
144
  if __name__ == '__main__':
139
145
  lprint(TEMPLATE)
140
146
 
@@ -0,0 +1,105 @@
1
+ # png_to_py.py - 将PNG图片转换为Python模块
2
+ import base64
3
+ import sys
4
+ from pathlib import Path
5
+
6
+
7
+ def png_to_py(png_path, py_path=None, var_name=None):
8
+ """
9
+ 将PNG图片转换为Python模块文件
10
+
11
+ :param png_path: PNG图片路径
12
+ :param py_path: 输出的.py文件路径(默认为图片同名.py)
13
+ :param var_name: 变量名(默认为文件名的大写形式)
14
+
15
+ :raises: FileNotFoundError: 若PNG文件不存在
16
+ :warns: 若文件不是PNG格式,将输出警告
17
+
18
+ :usage:
19
+ # 基本用法
20
+ png_to_py('icon.png')
21
+ # 指定输出路径和变量名
22
+ png_to_py('logo.png', 'resources/logo.py', 'LOGO_ICON')
23
+ """
24
+ png_file = Path(png_path)
25
+
26
+ if not png_file.exists():
27
+ raise FileNotFoundError(f"文件 '{png_path}' 不存在")
28
+
29
+ if png_file.suffix.lower() != '.png':
30
+ print(f"[警告] 文件 '{png_path}' 不是PNG格式")
31
+ return False
32
+
33
+ # 自动生成输出路径
34
+ if py_path is None:
35
+ py_path = png_file.with_suffix('.py')
36
+ else:
37
+ py_path = Path(py_path)
38
+
39
+ # 自动生成变量名
40
+ if var_name is None:
41
+ var_name = png_file.stem.replace('-', '_').replace(' ', '_').upper()
42
+
43
+ try:
44
+ # 读取PNG文件并转换为base64
45
+ with open(png_file, 'rb') as f:
46
+ png_data = f.read()
47
+ base64_data = base64.b64encode(png_data).decode('utf-8')
48
+
49
+ print(f"[DEBUG] 读取PNG文件: {len(png_data)} 字节") # 调试输出:查看文件大小
50
+ print(f"[DEBUG] Base64编码长度: {len(base64_data)} 字符") # 调试输出:查看编码长度
51
+
52
+ # 生成Python代码
53
+ py_content = f'''# -*- coding: utf-8 -*-
54
+ """
55
+ PyQt6资源模块: {png_file.name}
56
+ 由 png_to_py.py 自动生成
57
+ """
58
+
59
+ {var_name} = b"""
60
+ {base64_data}
61
+ """
62
+
63
+ def get_pixmap():
64
+ """返回QPixmap对象"""
65
+ from PyQt6.QtGui import QPixmap
66
+ from PyQt6.QtCore import QByteArray
67
+ pixmap = QPixmap()
68
+ pixmap.loadFromData(QByteArray({var_name}))
69
+ return pixmap
70
+
71
+ def get_icon():
72
+ """返回QIcon对象"""
73
+ from PyQt6.QtGui import QIcon
74
+ icon = QIcon(get_pixmap())
75
+ return icon
76
+
77
+ if __name__ == '__main__':
78
+ print(f"资源模块 {var_name} 已生成")
79
+ print(f"图片大小: {len(png_data)} 字节")
80
+ print(f"Base64长度: {len(base64_data)} 字符")
81
+ '''
82
+
83
+ # 写入Python文件
84
+ with open(py_path, 'w', encoding='utf-8') as f:
85
+ f.write(py_content)
86
+
87
+ print(f"✓ 成功: {png_path} -> {py_path}")
88
+ print(f" 变量名: {var_name}")
89
+ return True
90
+
91
+ except Exception as e:
92
+ print(f"错误: 转换失败 - {e}")
93
+ return False
94
+
95
+
96
+ if __name__ == '__main__':
97
+ # 命令行使用示例
98
+ if len(sys.argv) < 2:
99
+ print("用法: python png_to_py.py <图片路径> [输出路径]")
100
+ print("示例: python png_to_py.py logo.png")
101
+ print(" python png_to_py.py icon.png resources/icon.py")
102
+ else:
103
+ png_path = sys.argv[1]
104
+ py_path = sys.argv[2] if len(sys.argv) > 2 else None
105
+ png_to_py(png_path, py_path)
@@ -0,0 +1,10 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ PyScreeps Arena UI模块
4
+ """
5
+
6
+ from .rs_icon import get_icon, get_pixmap
7
+ from .project_ui import ProjectCreatorUI, run_project_creator
8
+ from .P2PY import png_to_py
9
+
10
+ __all__ = ['get_icon', 'get_pixmap', 'ProjectCreatorUI', 'run_project_creator', 'png_to_py']
@@ -0,0 +1,213 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ 项目创建UI界面
4
+ """
5
+ import sys
6
+ import os
7
+ from pathlib import Path
8
+ from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
9
+ QHBoxLayout, QLabel, QLineEdit, QPushButton,
10
+ QFileDialog, QMessageBox)
11
+ from PyQt6.QtCore import Qt
12
+ from PyQt6.QtGui import QFont
13
+ from pyscreeps_arena.core import const
14
+ from pyscreeps_arena.ui.rs_icon import get_icon
15
+
16
+
17
+ class ProjectCreatorUI(QMainWindow):
18
+ def __init__(self):
19
+ super().__init__()
20
+ self._proj_name = ""
21
+ self._proj_path = ""
22
+ self._init_ui()
23
+
24
+ def _init_ui(self):
25
+ """初始化UI界面"""
26
+ self.setWindowTitle("PyScreeps Arena - 项目创建器")
27
+ self.setWindowIcon(get_icon())
28
+ self.setFixedSize(500, 350)
29
+
30
+ # 主窗口部件
31
+ central_widget = QWidget()
32
+ self.setCentralWidget(central_widget)
33
+ layout = QVBoxLayout(central_widget)
34
+ layout.setSpacing(15)
35
+ layout.setContentsMargins(30, 30, 30, 30)
36
+
37
+ # 标题
38
+ title = QLabel("PyScreeps Arena")
39
+ title.setAlignment(Qt.AlignmentFlag.AlignCenter)
40
+ title_font = QFont()
41
+ title_font.setPointSize(18)
42
+ title_font.setBold(True)
43
+ title.setFont(title_font)
44
+ layout.addWidget(title)
45
+
46
+ # 项目信息
47
+ info_widget = QWidget()
48
+ info_layout = QVBoxLayout(info_widget)
49
+ info_layout.setSpacing(8)
50
+
51
+ # 版本信息
52
+ version_label = QLabel(f"版本: {const.VERSION}")
53
+ version_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
54
+ info_layout.addWidget(version_label)
55
+
56
+ # 作者信息
57
+ author_label = QLabel(f"作者: {const.AUTHOR}")
58
+ author_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
59
+ info_layout.addWidget(author_label)
60
+
61
+ # GitHub信息
62
+ github_label = QLabel(f"GitHub: {const.GITHUB_NAME}")
63
+ github_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
64
+ info_layout.addWidget(github_label)
65
+
66
+ layout.addWidget(info_widget)
67
+
68
+ # 分隔线
69
+ separator = QLabel("─" * 50)
70
+ separator.setAlignment(Qt.AlignmentFlag.AlignCenter)
71
+ separator.setStyleSheet("color: #ccc;")
72
+ layout.addWidget(separator)
73
+
74
+ # 项目输入区域
75
+ input_widget = QWidget()
76
+ input_layout = QVBoxLayout(input_widget)
77
+ input_layout.setSpacing(12)
78
+
79
+ # 项目名称输入
80
+ name_layout = QHBoxLayout()
81
+ name_label = QLabel("项目名称:")
82
+ name_label.setFixedWidth(80)
83
+ self._name_input = QLineEdit()
84
+ self._name_input.setPlaceholderText("输入项目名称...")
85
+ self._name_input.textChanged.connect(self._on_name_changed)
86
+ name_layout.addWidget(name_label)
87
+ name_layout.addWidget(self._name_input)
88
+ input_layout.addLayout(name_layout)
89
+
90
+ # 项目路径输入
91
+ path_layout = QHBoxLayout()
92
+ path_label = QLabel("保存位置:")
93
+ path_label.setFixedWidth(80)
94
+ self._path_input = QLineEdit()
95
+ self._path_input.setPlaceholderText("选择项目保存位置...")
96
+ self._path_input.setReadOnly(True)
97
+ # 默认桌面路径
98
+ desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
99
+ if os.path.exists(desktop_path):
100
+ self._path_input.setText(desktop_path)
101
+ self._proj_path = desktop_path
102
+ path_layout.addWidget(path_label)
103
+ path_layout.addWidget(self._path_input)
104
+
105
+ # 浏览按钮
106
+ browse_btn = QPushButton("浏览...")
107
+ browse_btn.setFixedWidth(60)
108
+ browse_btn.clicked.connect(self._browse_path)
109
+ path_layout.addWidget(browse_btn)
110
+
111
+ input_layout.addLayout(path_layout)
112
+ layout.addWidget(input_widget)
113
+
114
+ # 按钮区域
115
+ button_layout = QHBoxLayout()
116
+ button_layout.addStretch()
117
+
118
+ # 创建按钮
119
+ self._create_btn = QPushButton("创建项目")
120
+ self._create_btn.setFixedSize(100, 35)
121
+ self._create_btn.clicked.connect(self._create_project)
122
+ self._create_btn.setEnabled(False)
123
+ button_layout.addWidget(self._create_btn)
124
+
125
+ # 取消按钮
126
+ cancel_btn = QPushButton("取消")
127
+ cancel_btn.setFixedSize(80, 35)
128
+ cancel_btn.clicked.connect(self.close)
129
+ button_layout.addWidget(cancel_btn)
130
+
131
+ layout.addLayout(button_layout)
132
+ layout.addStretch()
133
+
134
+ def _on_name_changed(self, text):
135
+ """项目名称改变时的处理"""
136
+ self._proj_name = text.strip()
137
+ self._create_btn.setEnabled(bool(self._proj_name and self._proj_path))
138
+
139
+ def _browse_path(self):
140
+ """浏览选择路径"""
141
+ current_path = self._path_input.text() or os.path.expanduser("~")
142
+ path = QFileDialog.getExistingDirectory(
143
+ self, "选择项目保存位置", current_path
144
+ )
145
+ if path:
146
+ self._path_input.setText(path)
147
+ self._proj_path = path
148
+ self._create_btn.setEnabled(bool(self._proj_name and self._proj_path))
149
+
150
+ def _create_project(self):
151
+ """创建项目"""
152
+ if not self._proj_name or not self._proj_path:
153
+ return
154
+
155
+ # 构建完整路径
156
+ full_path = os.path.join(self._proj_path, self._proj_name)
157
+
158
+ # 检查路径是否已存在
159
+ if os.path.exists(full_path):
160
+ reply = QMessageBox.question(
161
+ self, "路径已存在",
162
+ f"路径 '{full_path}' 已存在。\n是否继续?",
163
+ QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
164
+ )
165
+ if reply != QMessageBox.StandardButton.Yes:
166
+ return
167
+
168
+ try:
169
+ # 创建项目
170
+ self._extract_project_template(full_path)
171
+
172
+ QMessageBox.information(
173
+ self, "成功",
174
+ f"项目 '{self._proj_name}' 创建成功!\n路径: {full_path}"
175
+ )
176
+ self.close()
177
+
178
+ except Exception as e:
179
+ QMessageBox.critical(
180
+ self, "错误",
181
+ f"项目创建失败:\n{str(e)}"
182
+ )
183
+
184
+ def _extract_project_template(self, target_path):
185
+ """提取项目模板"""
186
+ # 获取当前包路径
187
+ this_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
188
+ project_7z_path = os.path.join(this_path, 'project.7z')
189
+
190
+ if not os.path.exists(project_7z_path):
191
+ raise FileNotFoundError(f"项目模板文件不存在: {project_7z_path}")
192
+
193
+ # 创建目标目录
194
+ os.makedirs(target_path, exist_ok=True)
195
+
196
+ # 解压项目模板
197
+ import py7zr
198
+ with py7zr.SevenZipFile(project_7z_path, mode='r') as archive:
199
+ archive.extractall(path=target_path)
200
+
201
+ print(f"[DEBUG] 项目模板已解压到: {target_path}") # 调试输出
202
+
203
+
204
+ def run_project_creator():
205
+ """运行项目创建器UI"""
206
+ app = QApplication(sys.argv)
207
+ window = ProjectCreatorUI()
208
+ window.show()
209
+ sys.exit(app.exec())
210
+
211
+
212
+ if __name__ == '__main__':
213
+ run_project_creator()
@@ -0,0 +1,28 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ PyQt6资源模块: icon.png
4
+ 由 png_to_py.py 自动生成
5
+ """
6
+
7
+ ICON = b"""
8
+ iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAA57GlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzggNzkuMTU5ODI0LCAyMDE2LzA5LzE0LTAxOjA5OjAxICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNyAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMjUtMTEtMjFUMjM6MDE6MjUrMDg6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1ldGFkYXRhRGF0ZT4yMDI1LTExLTIxVDIzOjAxOjI1KzA4OjAwPC94bXA6TWV0YWRhdGFEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAyNS0xMS0yMVQyMzowMToyNSswODowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6NTJmOTM2Y2QtOTY1MC01YjQ0LTgzMjMtYjBjMjgwZDM0MGI3PC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwaG90b3Nob3A6ZWQzNTEwMjMtYzZlYS0xMWYwLTk2YjktZmM2NTg2ZGU4Mzc1PC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6MGU2N2I1ZTItOTllOS1jMTQyLWIxYjYtMWUwNWY4MzAyYjdiPC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjBlNjdiNWUyLTk5ZTktYzE0Mi1iMWI2LTFlMDVmODMwMmI3Yjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAyNS0xMS0yMVQyMzowMToyNSswODowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo1MmY5MzZjZC05NjUwLTViNDQtODMyMy1iMGMyODBkMzQwYjc8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMjUtMTEtMjFUMjM6MDE6MjUrMDg6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE3IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3BuZzwvZGM6Zm9ybWF0PgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4zPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjcyMDAwMC8xMDAwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT42NTUzNTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MjA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+MjA8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Pud2StQAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAABA5JREFUeNpklE2IntUVx3/n3Hufed+Zd74yZjLR+DUxfqXFYkIaiC0iLa22W923IAi6UFy4DbhxqQiiCF2Jq27daWlRoU2VptVSqE1CwaSTxGTCzLwfz3PvPaeLZ8SF564unPPnnv/985Mnf/X01c8/O7cemoSZISIYBg4iAiKAAaAGASHXChGEiLujqtQu+4mTpy7J+qG7fW44pMtdL5YLTZwjW0ZjwEpFXTEJaDS8GOaGSINbi6ZetEkN7XTaqaZIO5sBgDuaIsUMV6hUNKX9V1bMKh4KISlQ0RTBHYB2NkNjbBQgNQ0AVg3LBY8gZkiXwQtVHQkVq457gxn9PRes9nakpgEBBcht2/vljsYAVlkIyuaB21hURcQBZThcZ7R4D9gC7tL3uiMi5LbtfXYcjRE8kCRgWhCMO0cbvHlmgxVSP+RCl4Y8cuZ1RmsP4aa4VTTO4RQkCeAotWFQoMiEEg26JY6PVvn9zze5d2mZLEO8dNQyI6YJw+U1Hn3qdVbXjoILQQrUitRF3EEdY9xMmK8jyANOH668+7NjLM9X3jl/iWvjbSQlUlQmO9e58Nn7LISDHH/8bVY2TjMrhRhWcL0FAmFltHTWo5EL3H9wyLs//SF3xBGv/uUib1z8hqWlJZoDPybOH8Xr1+z974/kXFk79guOHDzD5e1P6cZbSBVUh4SF5dWznhc4dajhncce5sj8gNe++A+/+9dlsMrwwGkee+It1h/4Nd9c/JhJ2eXG9fPE2YTVo7/knkNPcP3aF3TtFdwykf1yviszQxAkCDl3eB9RVApmjjD4Nn7fK7lj414vTYe1DQ8cHPHe48c5rENe+8cl3rjwNcvNEF3+EZQhs/Ffkb0b3PWDF7jr9MuEW1f406e/pb3+FVodjfOE4eL6WdeWoS9wbWz8/cZVfnLnCk9tLuGTMecu7zGZXsKn/2Zqxuax53nwzPO0u1f42yevsLN1nrmwiMkMF0cFZaGbZxL2IM04dzXw7IdfcXNXeO7R+zi8dABKIefEcHQ7myd/w7jb5cs/vMitrT8ziJFSbyG2Ag5K6JhFiD5PLArNDl/ubfPMRxf4794u5DGSGkIIlJxpd67y+QcvcXP7nyBO9Qgh4GEXEZCNI0fdckFTxHLpCSMwXyu3L6+yPZtys+1AlSatkQbLjHe3QHYQ36fRt7Mp9oJBA6UWvFr/nSmiGF4yhAgSESpWAVUwQ6NjnYMIEpQYItUqEYfcdUhQNGjf4IIBnhqSJmpXcIQQwTwDipeApj5PTq+hMaBWis8NBvsh6gEbKuj+ybMZggCKSkSq4iZAwnLZZyXMDQb92idOnrrcTqeuqj3OUyRHo9aKmyGDOUooEDO1tsQQUBXQ72itqrTTKSdOntr6/wB5xwkK8omfuAAAAABJRU5ErkJggg==
9
+ """
10
+
11
+ def get_pixmap():
12
+ """返回QPixmap对象"""
13
+ from PyQt6.QtGui import QPixmap
14
+ from PyQt6.QtCore import QByteArray
15
+ pixmap = QPixmap()
16
+ pixmap.loadFromData(QByteArray(ICON))
17
+ return pixmap
18
+
19
+ def get_icon():
20
+ """返回QIcon对象"""
21
+ from PyQt6.QtGui import QIcon
22
+ icon = QIcon(get_pixmap())
23
+ return icon
24
+
25
+ if __name__ == '__main__':
26
+ print(f"资源模块 ICON 已生成")
27
+ print(f"图片大小: 16000 字节")
28
+ print(f"Base64长度: 21336 字符")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscreeps-arena
3
- Version: 0.5.3.2
3
+ Version: 0.5.4a0
4
4
  Summary: Python api|interface to play game: Screeps: Arena.
5
5
  Author-email: 2229066748@qq.com
6
6
  Maintainer: Eagle'sBaby
@@ -16,6 +16,7 @@ Requires-Dist: colorama
16
16
  Requires-Dist: py7zr
17
17
  Requires-Dist: chardet
18
18
  Requires-Dist: Transcrypt==3.9.1
19
+ Requires-Dist: PyQt6
19
20
  Requires-Dist: mkdocs
20
21
  Requires-Dist: mkdocstrings[python]
21
22
  Requires-Dist: mkdocs-material
@@ -16,4 +16,8 @@ pyscreeps_arena/core/config.py
16
16
  pyscreeps_arena/core/const.py
17
17
  pyscreeps_arena/core/core.py
18
18
  pyscreeps_arena/core/main.py
19
- pyscreeps_arena/core/utils.py
19
+ pyscreeps_arena/core/utils.py
20
+ pyscreeps_arena/ui/P2PY.py
21
+ pyscreeps_arena/ui/__init__.py
22
+ pyscreeps_arena/ui/project_ui.py
23
+ pyscreeps_arena/ui/rs_icon.py
@@ -1,3 +1,4 @@
1
1
  [console_scripts]
2
2
  arena = pyscreeps_arena:CMD_NewProject
3
+ psaui = pyscreeps_arena:CMD_OpenUI
3
4
  pyscreeps-arena = pyscreeps_arena:CMD_NewProject
@@ -3,6 +3,7 @@ colorama
3
3
  py7zr
4
4
  chardet
5
5
  Transcrypt==3.9.1
6
+ PyQt6
6
7
  mkdocs
7
8
  mkdocstrings[python]
8
9
  mkdocs-material
@@ -7,7 +7,7 @@ with open(r"T:\New_PC\Import_Project\uploads\pyscreeps-arena_upload\pyscreeps-ar
7
7
  long_description = f.read()
8
8
  setup(
9
9
  name='pyscreeps-arena',
10
- version='0.5.3.2',
10
+ version='0.5.4.a0',
11
11
  description='Python api|interface to play game: Screeps: Arena.',
12
12
  long_description=long_description,
13
13
  long_description_content_type='text/markdown',
@@ -27,6 +27,7 @@ setup(
27
27
  'console_scripts': [
28
28
  'pyscreeps-arena=pyscreeps_arena:CMD_NewProject',
29
29
  'arena=pyscreeps_arena:CMD_NewProject',
30
+ 'psaui=pyscreeps_arena:CMD_OpenUI',
30
31
  ]
31
32
  },
32
33
  keywords=['python', 'screeps:arena', 'screeps'],
@@ -37,6 +38,7 @@ setup(
37
38
  'py7zr',
38
39
  'chardet',
39
40
  'Transcrypt==3.9.1',
41
+ 'PyQt6',
40
42
  'mkdocs',
41
43
  'mkdocstrings[python]',
42
44
  'mkdocs-material',