QingNiao/main.py
2025-07-08 00:48:24 +08:00

122 lines
4.7 KiB
Python

import os
from pathlib import Path
import memoria
from textual.app import App, ComposeResult
from textual.widgets import Header, Footer, ListView, ListItem, Label, Static, Button
from textual.containers import Container
from textual.screen import Screen
ver = 0.01
# --- MemApp 学习屏幕 ---
class MemAppLearningScreen(Screen):
BINDINGS = [
("q", "go_back", "返回"),
("escape", "quit_app", "退出")
]
def __init__(self, file_to_learn: str, history_file: str, name: str | None = None, id: str | None = None, classes: str | None = None) -> None:
super().__init__(name=name, id=id, classes=classes)
self.file_to_learn = file_to_learn
self.history_file = history_file
def compose(self) -> ComposeResult:
yield Header()
with Container(id="learning_screen_container"):
yield Label(f"正在学习文件: [b]{Path(self.file_to_learn).name}[/b]", classes="learning-info")
yield Label(f"历史文件: [b]{Path(self.history_file).name}[/b]", classes="learning-info")
yield Label("\n[i]点击 '开始记忆' 进入学习模式.[/i]", classes="placeholder-message")
yield Static("\n按 [b]Q[/b] 返回;按 [b]ESC[/b] 退出.", classes="instructions")
yield Button("开始记忆", id="start_memorizing_button", variant="primary", classes="start-button")
yield Static(f"\n以下是全文:\n", classes="read-info")
with open(self.file_to_learn, 'r', encoding='UTF-8') as f:
for i in f.readlines():
yield Static(' ' + i, classes="read-info")
yield Footer()
def action_go_back(self):
self.app.pop_screen()
def action_quit_app(self):
self.app.exit()
def on_button_pressed(self, event: Button.Pressed) -> None:
if event.button.id == "start_memorizing_button":
self.app.push_screen(
memoria.MemScreen(
file_to_learn=self.file_to_learn,
history_file=self.history_file
)
)
# --- 文件选择屏幕 ---
class FileSelectionScreen(Screen):
global ver
def compose(self) -> ComposeResult:
yield Header()
yield Container(
Label(f'欢迎使用 "青鸟" 辅助记忆软件, 版本 {ver}', classes="title-label"),
Label("选择要学习的文件:", classes="title-label"),
ListView(id="file-list", classes="file-list-view")
)
yield Footer()
def on_mount(self) -> None:
Path("./history").mkdir(parents=True, exist_ok=True)
Path("./library").mkdir(parents=True, exist_ok=True)
file_list_widget = self.query_one("#file-list", ListView)
library_path = Path("./library")
txt_files = sorted([f.name for f in library_path.iterdir() if f.suffix == ".txt"])
if txt_files:
for filename in txt_files:
file_list_widget.append(ListItem(Label(filename)))
else:
file_list_widget.append(ListItem(Static("在 ./library/ 中未找到任何 .txt 文件。请放置文件后重启应用。")))
file_list_widget.disabled = True
def on_list_view_selected(self, event: ListView.Selected) -> None:
if not isinstance(event.item, ListItem):
self.notify("无法选择此项。", severity="error")
return
selected_label = event.item.query_one(Label)
if "未找到任何 .txt 文件" in str(selected_label.renderable):
self.notify("请先在 `./library/` 目录中放置 .txt 文件。", severity="warning")
return
selected_filename = str(selected_label.renderable)
file_to_learn_path = Path("./library") / selected_filename
history_file_name = f"{Path(selected_filename).stem}_history.json"
history_file_path = Path("./history") / history_file_name
self.notify(f"已选择: {selected_filename}", timeout=2)
self.app.push_screen(MemAppLearningScreen(
file_to_learn=str(file_to_learn_path),
history_file=str(history_file_path)
))
def action_quit_app(self) -> None:
self.app.exit()
# --- 主 Textual 应用类 ---
class MemAppLauncher(App):
CSS_PATH = "styles.css"
TITLE = '青鸟 辅助记忆程序'
BINDINGS = [("escape", "quit", "退出"), ("d", "toggle_dark", "改变色调")]
SCREENS = {
"file_selection_screen": FileSelectionScreen,
}
def on_mount(self) -> None:
self.action_toggle_dark()
self.push_screen("file_selection_screen")
if __name__ == "__main__":
css_path = Path("styles_dashboard.css")
app = MemAppLauncher()
app.run()