|
@@ -1,3 +1,83 @@
|
|
# textual
|
|
# textual
|
|
|
|
|
|
-命令行GUI
|
|
|
|
|
|
+命令行GUI
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+## Usage
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+import shutil
|
|
|
|
+from textual import on
|
|
|
|
+from textual.app import ComposeResult, App
|
|
|
|
+from textual.widgets import Footer, Header, Button, SelectionList
|
|
|
|
+from textual.widgets.selection_list import Selection
|
|
|
|
+from textual.screen import ModalScreen
|
|
|
|
+
|
|
|
|
+# 操作系统命令已硬编码
|
|
|
|
+OS_COMMANDS = {
|
|
|
|
+ "LSHW": ["lshw", "-json", "-sanitize", "-notime", "-quiet"],
|
|
|
|
+ "LSCPU": ["lscpu", "--all", "--extended", "--json"],
|
|
|
|
+ "LSMEM": ["lsmem", "--json", "--all", "--output-all"],
|
|
|
|
+ "NUMASTAT": ["numastat", "-z"]
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+class LogScreen(ModalScreen):
|
|
|
|
+ # ... 省略了完整的独立屏幕的代码,下文将进行解释
|
|
|
|
+
|
|
|
|
+ def __init__(self, name=None, ident=None, classes=None, selections=None):
|
|
|
|
+ super().__init__(name, ident, classes)
|
|
|
|
+ pass
|
|
|
|
+
|
|
|
|
+class OsApp(App):
|
|
|
|
+ BINDINGS = [
|
|
|
|
+ ("q", "quit_app", "Quit"),
|
|
|
|
+ ]
|
|
|
|
+ CSS_PATH = "os_app.tcss"
|
|
|
|
+ ENABLE_COMMAND_PALETTE = False # 不需要命令面板
|
|
|
|
+
|
|
|
|
+ def action_quit_app(self):
|
|
|
|
+ self.exit(0)
|
|
|
|
+
|
|
|
|
+ def compose(self) -> ComposeResult:
|
|
|
|
+ # 创建一个命令列表,假定有效命令在 PATH 变量上
|
|
|
|
+ selections = [
|
|
|
|
+ Selection(name.title(), ' '.join(cmd), True)
|
|
|
|
+ for name, cmd in OS_COMMANDS.items()
|
|
|
|
+ if shutil.which(cmd[0].strip())
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ yield Header(show_clock=False)
|
|
|
|
+ sel_list = SelectionList(*selections, id='cmds')
|
|
|
|
+ sel_list.tooltip = "Select one more more command to execute"
|
|
|
|
+ yield sel_list
|
|
|
|
+ yield Button(f"Execute {len(selections)} commands", id="exec", variant="primary")
|
|
|
|
+ yield Footer()
|
|
|
|
+
|
|
|
|
+ @on(SelectionList.SelectedChanged)
|
|
|
|
+ def on_selection(self, event: SelectionList.SelectedChanged) -> None:
|
|
|
|
+ button = self.query_one("#exec", Button)
|
|
|
|
+ selections = len(event.selection_list.selected)
|
|
|
|
+ if selections:
|
|
|
|
+ button.disabled = False
|
|
|
|
+ else:
|
|
|
|
+ button.disabled = True
|
|
|
|
+ button.label = f"Execute {selections} commands"
|
|
|
|
+
|
|
|
|
+ @on(Button.Pressed)
|
|
|
|
+ def on_button_click(self):
|
|
|
|
+ selection_list = self.query_one('#cmds', SelectionList)
|
|
|
|
+ selections = selection_list.selected
|
|
|
|
+ log_screen = LogScreen(selections=selections)
|
|
|
|
+ self.push_screen(log_screen)
|
|
|
|
+
|
|
|
|
+def main():
|
|
|
|
+ app = OsApp()
|
|
|
|
+ app.title = f"Output of multiple well known UNIX commands".title()
|
|
|
|
+ app.sub_title = f" {len(OS_COMMANDS)} commands available"
|
|
|
|
+ app.run()
|
|
|
|
+
|
|
|
|
+if __name__ == "__main__":
|
|
|
|
+ main()
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+```
|