|
| 1 | +""" |
| 2 | +开发者命令行 |
| 3 | +""" |
| 4 | +import os |
| 5 | +import sys |
| 6 | +from typing import IO, Any |
| 7 | +from libs import * |
| 8 | +from cmd import Cmd |
| 9 | +from keyword import kwlist |
| 10 | + |
| 11 | +__name__ = "开发者命令行" |
| 12 | +__author__ = "此程序开发者" |
| 13 | +__version__ = "1.1.0" |
| 14 | + |
| 15 | +public = {"info": "这是一个公共字典,可以在其中存储变量"} |
| 16 | + |
| 17 | +class DebuggerCmd(Cmd): |
| 18 | + intro = "欢迎使用开发者命令行\n" |
| 19 | + prompt = "debug -> " |
| 20 | + |
| 21 | + def __init__(self, completekey: str = "tab", stdin: IO[str] | None = None, stdout: IO[str] | None = None) -> None: |
| 22 | + super().__init__(completekey, stdin, stdout) |
| 23 | + |
| 24 | + def cmdloop(self, intro: Any | None = None) -> None: |
| 25 | + if not calculator.debug: |
| 26 | + QMessageBox.warning(calculator, __name__, "非调试模式无法启动") |
| 27 | + return |
| 28 | + os.system("title Debugger Cmd") |
| 29 | + return super().cmdloop(intro) |
| 30 | + |
| 31 | + def default(self, line: str) -> None: |
| 32 | + os.system(line) |
| 33 | + |
| 34 | + def do_exit(self, *ignoerd): |
| 35 | + """ |
| 36 | + 退出。 |
| 37 | + """ |
| 38 | + sys.exit(0) |
| 39 | + |
| 40 | + def do_exec(self, args: str): |
| 41 | + """ |
| 42 | + 运行代码。 |
| 43 | +
|
| 44 | + 用法:exec [[-l command] | -i] |
| 45 | +
|
| 46 | + -l command 运行单行代码。 |
| 47 | + -i 启动多行输入模式,运行多段代码。 |
| 48 | +
|
| 49 | + 多行输入模式命令: [#run] [#rewrite line] [#show] [#exit] |
| 50 | +
|
| 51 | + #run 运行输入的代码。 |
| 52 | + #rewrite line 重写第line行的代码。 |
| 53 | + #show 展示所有代码,可以在使用#rewrite命令后确认代码是否准确。 |
| 54 | + #exit 退出多行输入模式(不运行)。 |
| 55 | + """ |
| 56 | + args = args.split(" ") |
| 57 | + command = """""" |
| 58 | + if args[0] == "-l": |
| 59 | + for i in args[1:]: |
| 60 | + command += i + " " |
| 61 | + try: |
| 62 | + exec(command) |
| 63 | + except Exception as e: |
| 64 | + print("\nError: %s"%type(e)) |
| 65 | + print(e) |
| 66 | + for i in e.args[1:]: |
| 67 | + print(i) |
| 68 | + print() |
| 69 | + elif args[0] == "-i": |
| 70 | + commands = [] |
| 71 | + line = 0 |
| 72 | + while True: |
| 73 | + cmd = input("Line%s: "%line) |
| 74 | + if cmd == "#run": |
| 75 | + break |
| 76 | + elif cmd.startswith("#rewrite"): |
| 77 | + cmd = cmd.split(" ") |
| 78 | + if not cmd[1].isdigit(): |
| 79 | + print("%s不是行数。"%cmd[1]) |
| 80 | + continue |
| 81 | + if not len(commands) > int(cmd[1]): |
| 82 | + print("没有行%s。"%cmd[1]) |
| 83 | + continue |
| 84 | + rewrite = input("Line%s[rewrite]: "%cmd[1]) |
| 85 | + commands[int(cmd[1])] = rewrite + "\n" |
| 86 | + elif cmd == "#show": |
| 87 | + print() |
| 88 | + for i in range(len(commands)): |
| 89 | + print("%s: %s"%(i, commands[i]), end="") |
| 90 | + print() |
| 91 | + elif cmd == "#exit": |
| 92 | + return |
| 93 | + else: |
| 94 | + commands.append(cmd + "\n") |
| 95 | + line += 1 |
| 96 | + for i in commands: |
| 97 | + command += i |
| 98 | + try: |
| 99 | + exec(command) |
| 100 | + except Exception as e: |
| 101 | + print("\nError: %s\n"%type(e)) |
| 102 | + print(e) |
| 103 | + for i in e.args[1:]: |
| 104 | + print(i) |
| 105 | + print() |
| 106 | + else: |
| 107 | + print("无效参数%s。"%args[0]) |
| 108 | + |
| 109 | + def get_widget_names(self, widget): |
| 110 | + names = [] |
| 111 | + for child in widget.children(): |
| 112 | + names.append("calculator.ui." + child.objectName()) |
| 113 | + if isinstance(child, QWidget): |
| 114 | + names.extend(self.get_widget_names(child)) |
| 115 | + return names |
| 116 | + |
| 117 | + def get_class_functions(self, _class): |
| 118 | + functions = [] |
| 119 | + for i in dir(_class): |
| 120 | + if not i.startswith("_"): |
| 121 | + functions.append("calculator." + i) |
| 122 | + return functions |
| 123 | + |
| 124 | + def complete_exec(self, text: str, line: str, begidx: int, endidx: int): |
| 125 | + if line.startswith("exec -l"): |
| 126 | + widgets = self.get_widget_names(calculator) |
| 127 | + functions = self.get_class_functions(calculator) |
| 128 | + complete = widgets + functions |
| 129 | + return [i for i in complete if i.lower().startswith(text)] |
| 130 | + if line.startswith("exec"): |
| 131 | + return ["-l", "-i"] |
| 132 | + |
| 133 | +debuggerCmd = DebuggerCmd() |
| 134 | + |
| 135 | +start_debugger_cmd_action = QAction("启动开发者命令行", calculator.ui.functions_menu) |
| 136 | +start_debugger_cmd_action.triggered.connect(lambda: debuggerCmd.cmdloop()) |
| 137 | + |
| 138 | +calculator.ui.functions_menu.addAction(start_debugger_cmd_action) |
0 commit comments