可用性改动

This commit is contained in:
2025-07-23 13:55:24 +08:00
parent ac1d8cbf8b
commit d8feb829b1
25 changed files with 1723 additions and 65 deletions

88
main.py
View File

@@ -1,12 +1,19 @@
from textual.app import App, ComposeResult
from textual.widgets import Header, Footer, ListView, ListItem, Label, Static, Button
from textual.containers import Container
from textual.containers import Container, Horizontal
from textual.screen import Screen
import particles as parti
import particles as pt
from reactor import Reactor
import pathlib
import threading
import edge_tts as tts
from playsound import playsound
from textual.logging import TextualHandler
ver = '0.2.1'
debug = TextualHandler(stderr=True)
class MemScreen(Screen):
BINDINGS = [
("d", "toggle_dark", "改变色调"),
@@ -28,19 +35,21 @@ class MemScreen(Screen):
btn = dict()
def __init__(
self,
atoms_file: str = 'test_atoms.json',
tasked_num: int = 8, # 记忆最小单元数目
nucleon_file: pt.AtomicFile,
electron_file: pt.AtomicFile,
tasked_num: int
):
super().__init__(name=None, id=None, classes=None)
self.memobj = MemObject(atoms_file=atoms_file, tasked_num=tasked_num)
self.memobj.next_round()
self.memobj.update_runtime(1)
self.reactor = Reactor(nucleon_file, electron_file, tasked_num)
self.stage = 1
self.stage += self.reactor.set_round_templated(self.stage)
def compose(self) -> ComposeResult:
yield Header(show_clock=True)
with Container(id="main_container"):
yield Label("", id="round_label")
yield Label(self.reactor.round_title, id="round_title")
yield Label("记住了吗?", id="question")
yield Static(self.memobj.runtime['current_atom'].content, id="sentence")
yield Static(self.reactor.current_atom[1].content, id="sentence")
yield Static("", id="feedback") # 用于显示反馈
yield Label(self._get_progress_text(), id="progress")
with Container(id="button_container"):
@@ -57,30 +66,22 @@ class MemScreen(Screen):
def _get_progress_text(self):
return f"{self.memobj.runtime['left'] + 1}/{self.memobj.runtime['total']}"
def _get_round_text(self):
t = {
'A': "复习模式",
'B': "建立新记忆",
'C': "总复习"
}
return "当前模式: " + t[self.memobj.runtime['stage']]
return f"{len(self.reactor.procession) - self.reactor.index}/{len(self.reactor.procession)}"
def on_mount(self):
# 首次挂载时调用
self._update_ui()
def _update_ui(self):
self.query_one("#round_label", Label).update(self._get_round_text())
self.query_one("#sentence", Static).update(self.memobj.runtime['current_atom'].content)
self.query_one("#round_title", Label).update(self.reactor.round_title)
self.query_one("#sentence", Static).update(self.reactor.current_atom[1].content)
self.query_one("#progress", Label).update(self._get_progress_text())
self.query_one("#feedback", Static).update("") # 清除任何之前的反馈消息
def _show_finished_screen(self, message):
self.query_one("#question", Label).update(message)
self.query_one("#sentence", Static).update("已经完成记忆任务")
self.query_one("#round_label").display = False
self.query_one("#round_title").display = False
self.query_one("#progress").display = False
for i in range(6):
self.query_one(f"#q{i}", Button).display = False
@@ -93,21 +94,20 @@ class MemScreen(Screen):
btnid = event.button.id
btnid = str(btnid)
quality = int(btnid.replace('q', ''))
assessment = self.memobj.report(self.memobj.runtime['current_atom'], quality)
assessment = self.reactor.report(self.reactor.current_atom, quality)
if assessment == 1:
# 需要复习
feedback_label.update(f"评分为 {quality}, 已经加入至复习, 请重复记忆")
else:
ret = self.memobj.update_runtime(1)
if ret == 1:
self.memobj.switch_to_extra_review()
self.memobj.update_runtime(1)
elif ret == 2:
self.memobj.next_round()
self.memobj.update_runtime(1)
elif ret == 3:
self.memobj.save()
self._show_finished_screen("今日目标已完成")
ret = self.reactor.forward(1)
if ret == -1:
if self.reactor.round_set == 0:
if self.stage == 3:
# NOTE # self.reactor.save()
self._show_finished_screen("今日目标已完成")
else:
self.stage += 1
self.reactor.set_round_templated(self.stage)
return
#feedback_label.update("") # 清除反馈消息
self._update_ui()
@@ -116,10 +116,10 @@ class MemScreen(Screen):
def action_play_voice(self):
def play():
cache = Path(f"./cache/voice/{self.memobj.runtime['current_atom'].content}.wav")
cache = pathlib.Path(f"./cache/voice/{self.reactor.current_atom[1].content}.wav")
if not cache.exists():
communicate = tts.Communicate(self.memobj.runtime['current_atom'].content, "zh-CN-YunjianNeural")
communicate.save_sync(f"./cache/voice/{self.memobj.runtime['current_atom'].content}.wav")
communicate = tts.Communicate(self.reactor.current_atom[1].content, "zh-CN-YunjianNeural")
communicate.save_sync(f"./cache/voice/{self.reactor.current_atom[1].content}.wav")
playsound(str(cache))
threading.Thread(target=play).start()
@@ -136,7 +136,7 @@ class PreparationScreen(Screen):
("escape", "quit_app", "退出")
]
def __init__(self, nucleon_file: parti.AtomicFile, electron_file: parti.AtomicFile) -> None:
def __init__(self, nucleon_file: pt.AtomicFile, electron_file: pt.AtomicFile) -> None:
super().__init__(name=None, id=None, classes=None)
self.nucleon_file = nucleon_file
self.electron_file = electron_file
@@ -161,12 +161,12 @@ class PreparationScreen(Screen):
def on_button_pressed(self, event: Button.Pressed) -> None:
pass
#if event.button.id == "start_memorizing_button":
# #init_file(Path(self.atom_file).name)
# newscr = proc.MemScreen(Path(self.atom_file).name)
# self.app.push_screen(
# newscr
# )
if event.button.id == "start_memorizing_button":
#init_file(Path(self.atom_file).name)
newscr = MemScreen(self.nucleon_file, self.electron_file, 8)
self.app.push_screen(
newscr
)
#if event.button.id == "edit_metadata_button":
# init_file(Path(self.atom_file).name)
# os.system("reset;nano ./data/" + str(Path(self.atom_file).name.replace(".txt", "_atoms.json")))
@@ -205,13 +205,13 @@ class FileSelectorScreen(Screen):
return
selected_filename = str(selected_label.renderable)
nucleon_file = parti.AtomicFile(pathlib.Path("./nucleon") / selected_filename, "nucleon")
nucleon_file = pt.AtomicFile(pathlib.Path("./nucleon") / selected_filename, "nucleon")
electron_file_path = pathlib.Path("./electron") / selected_filename
if electron_file_path.exists():
pass
else:
electron_file_path.touch()
electron_file = parti.AtomicFile(pathlib.Path("./electron") / selected_filename, "electron")
electron_file = pt.AtomicFile(pathlib.Path("./electron") / selected_filename, "electron")
# self.notify(f"已选择: {selected_filename}", timeout=2)
self.app.push_screen(PreparationScreen(nucleon_file, electron_file))