重构布局系统并改进界面

This commit is contained in:
2025-08-03 03:57:21 +08:00
parent 445e15646b
commit 4beb42f615
5 changed files with 123 additions and 26 deletions

View File

@@ -1,16 +1,29 @@
from textual.app import App, ComposeResult from textual.app import App, ComposeResult
from textual.events import Event from textual.events import Event
from textual.widgets import Header, Footer, ListView, ListItem, Label, Static, Button from textual.widgets import Collapsible, Header, Footer, Markdown, ListView, ListItem, Label, Static, Button
from textual.containers import Container, Horizontal from textual.containers import Container, Horizontal, Center
from textual.screen import Screen from textual.screen import Screen
from textual.widget import Widget
import pathlib import pathlib
from typing import Tuple, Dict from typing import Tuple, Dict
import particles as pt import particles as pt
import uuid
from functools import wraps
class Composition(): class Composition():
def __init__(self, screen: Screen, atom: Tuple[pt.Electron, pt.Nucleon, Dict]): def __init__(self, screen: Screen, reactor, atom: Tuple[pt.Electron, pt.Nucleon, Dict]):
self.screen = screen self.screen = screen
self.atom = atom self.atom = atom
from reactor import Reactor
self.reactor: Reactor = reactor
self.reg = dict()
def regid(self, id_):
self.reg[id_] = id_ + str(uuid.uuid4())
return self.reg[id_]
def getid(self, id_):
if id_ not in self.reg.keys():
return "None"
return self.reg[id_]
def compose(self): def compose(self):
yield Label("示例标签", id="testlabel") yield Label("示例标签", id="testlabel")
yield Button("示例按钮", id="testbtn") yield Button("示例按钮", id="testbtn")
@@ -23,18 +36,50 @@ class Placeholder(Composition):
self.screen = screen self.screen = screen
def compose(self): def compose(self):
yield Label("示例标签", id="testlabel") yield Label("示例标签", id="testlabel")
yield Button("示例按钮", id="testbtn") yield Button("示例按钮", id="testbtn", classes="choice")
def handler(self, event): def handler(self, event):
print(event.button.id) print(event.button.id)
self.screen.query_one("#testlabel", Label).update("hi") self.screen.query_one("#testlabel", Label).update("hi")
class Recognition(Composition): class Recognition(Composition):
def __init__(self, screen: Screen, atom: Tuple[pt.Electron, pt.Nucleon, Dict]): def __init__(self, screen: Screen, reactor, atom: Tuple[pt.Electron, pt.Nucleon, Dict]):
super().__init__(screen, atom) super().__init__(screen, reactor, atom)
def compose(self):
with Center():
yield Static(f"[dim]{self.atom[1]['translation']}[/]")
yield Label(f"")
with Center():
yield Label(f"[b][b]{self.atom[1]['content']}[/][/]", id=self.regid("sentence")) # 致敬传奇去重串 uuid
#with Collapsible(title="附加信息", collapsed=True):
for i in self.atom[2]["testdata"]["additional_inf"]:
if self.atom[1][i]:
print(type(self.atom[1][i]))
print(self.atom[1][i])
if isinstance(self.atom[1][i], list):
for j in self.atom[1][i]:
print(999)
yield Markdown(f"### {self.atom[2]["keydata"][i]}: {j}")
continue
if isinstance(self.atom[1][i], Dict):
t = ""
for j, k in self.atom[1][i].items():
t += f"> **{j}**: {k} \n"
yield Markdown(t, id=self.regid("tran"))
with Center():
yield Button("我已知晓", id=self.regid("ok"))
def handler(self, event):
if event.button.id == self.getid("ok"):
print(1)
""""""#assessment = self.reactor.report(self.reactor.current_atom, -1)
return 0
class BasicEvaluation(Composition):
def __init__(self, screen: Screen, reactor, atom: Tuple[pt.Electron, pt.Nucleon, Dict]):
super().__init__(screen, reactor, atom)
def compose(self): def compose(self):
yield Label(self.atom[1]["content"], id="sentence") yield Label(self.atom[1]["content"], id="sentence")
for i in self.atom[2]["testdata"]["additional_inf"]: for i in self.atom[2]["testdata"]["additional_inf"]:
yield Label("[" + self.atom[2]["keydata"][i] + "] " + str(self.atom[1][i]), id=f"label_{i}") yield Label(f"{self.atom[2]["keydata"][i]}: {self.atom[1][i]}", id=f"label_{i}")
yield Button("我已知晓", id="ok") yield Button("我已知晓", id="ok")
def handler(self, event): def handler(self, event):
if event.button.id == "ok": if event.button.id == "ok":
@@ -42,7 +87,7 @@ class Recognition(Composition):
class FillBlank(Composition): class FillBlank(Composition):
def __init__(self, screen: Screen, atom: Tuple[pt.Electron, pt.Nucleon, Dict]): def __init__(self, screen: Screen, atom: Tuple[pt.Electron, pt.Nucleon, Dict]):
super().__init__(screen, atom) """"""#super().__init__(screen, atom)
def compose(self): def compose(self):
yield Label(self.atom[1]["content"], id="sentence") yield Label(self.atom[1]["content"], id="sentence")
for i in self.atom[2]["testdata"]["additional_inf"]: for i in self.atom[2]["testdata"]["additional_inf"]:
@@ -57,7 +102,8 @@ registry = {
"sample": Composition, "sample": Composition,
"recognition": Recognition, "recognition": Recognition,
"fill_blank_test": FillBlank, "fill_blank_test": FillBlank,
"draw_card_test": Composition, "draw_card_test": BasicEvaluation,
"basic_evaluation": BasicEvaluation,
} }
@@ -66,7 +112,7 @@ registry = {
class TestScreen(Screen): class TestScreen(Screen):
def __init__(self): def __init__(self):
super().__init__(name=None, id=None, classes=None) super().__init__(name=None, id=None, classes=None)
self.comp = Recognition(self, pt.Atom.advanced_placeholder()) self.comp = Recognition(self, None, pt.Atom.advanced_placeholder())
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
yield Header(show_clock=True) yield Header(show_clock=True)
yield from self.comp.compose() yield from self.comp.compose()

54
main.py
View File

@@ -48,10 +48,12 @@ class MemScreen(Screen):
self.stage += self.reactor.set_round_templated(self.stage) self.stage += self.reactor.set_round_templated(self.stage)
#print(self.reactor.procession) #print(self.reactor.procession)
self.reactor.forward() self.reactor.forward()
self.compo:compo.Composition = compo.Placeholder(self) #self.compo:compo.Composition = compo.Placeholder(self)
self.compo = next(self.reactor.current_appar)
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
self.compo = next(self.reactor.current_appar) print(self.compo)
yield Header(show_clock=True) yield Header(show_clock=True)
with Container(id="main_container"): with Container(id="main_container"):
yield from self.compo.compose() yield from self.compo.compose()
@@ -67,7 +69,7 @@ class MemScreen(Screen):
pass pass
def on_button_pressed(self, event): def on_button_pressed(self, event):
self.compo.handler(event) ret = self.compo.handler(event)
"""feedback_label = self.query_one("#feedback", Static) """feedback_label = self.query_one("#feedback", Static)
if type(event) == str: if type(event) == str:
btnid = event btnid = event
@@ -76,7 +78,51 @@ class MemScreen(Screen):
btnid = str(btnid) btnid = str(btnid)
quality = int(btnid.replace('q', '')) quality = int(btnid.replace('q', ''))
assessment = self.reactor.report(self.reactor.current_atom, quality) assessment = self.reactor.report(self.reactor.current_atom, quality)
if assessment == 1: """
# 遵循 perror 返回值规则
if ret == 0: # 成功
try:
self.compo = next(self.reactor.current_appar)
self.refresh_ui()
except StopIteration:
nxt = self.reactor.forward(1)
print(2)
self.compo = next(self.reactor.current_appar)
print(self.compo)
#print("next", nxt, self.reactor.current_atom)
if nxt == -1:
if self.reactor.round_set == 0:
if self.stage == 4:
if config.get("save"):
self.reactor.save()
#self._show_finished_screen("今日目标已完成")
else:
self.reactor.set_round_templated(self.stage)
self.reactor.forward(1)
#self._update_ui()
self.stage += 1
return
return
else:
self.refresh_ui()
return
if ret == 1: # 不允许前进
self.refresh_ui()
return
def refresh_ui(self):
area = self.query_one("#main_container")
self.call_later(self.recompose)
#print(area.children)
#for child in list(area.children):
# child.remove() # 致敬传奇组件树 DOM
#print(1,list(self.compo.compose()))
#area.mount(*list(self.compo.compose()))
def report(self, quality):
assessment = self.reactor.report(self.reactor.current_atom, quality)
return assessment
"""if assessment == 1:
# 需要复习 # 需要复习
feedback_label.update(f"评分为 {quality}, 已经加入至复习, 请重复记忆") feedback_label.update(f"评分为 {quality}, 已经加入至复习, 请重复记忆")
else: else:

View File

@@ -7,7 +7,7 @@ translation = "语句翻译"
# 测试项目元数据 # 测试项目元数据
["testdata"] ["testdata"]
# 记忆时显示的额外信息 # 记忆时显示的额外信息
additional_inf = ["translation", "note"] additional_inf = ["translation","keyword_note", "note"]
# 填空测试 # 填空测试
fill_blank_test = ["translation"] fill_blank_test = ["translation"]
# 选择题测试 # 选择题测试

View File

@@ -4,10 +4,10 @@ import pathlib
import auxiliary as aux import auxiliary as aux
import compositions as comps import compositions as comps
import random import random
#from pprint import pprint as print # debug
class Apparatus(): class Apparatus():
"""反应器对象, 决策一个原子的不同记忆方式, 并反馈到布局""" """反应器对象, 决策一个原子的不同记忆方式, 并反馈到布局"""
def __init__(self, screen, atom): def __init__(self, screen, reactor, atom):
self.electron: pt.Electron = atom[0] self.electron: pt.Electron = atom[0]
self.nucleon: pt.Nucleon = atom[1] self.nucleon: pt.Nucleon = atom[1]
self.positron: dict = atom[2] self.positron: dict = atom[2]
@@ -15,12 +15,12 @@ class Apparatus():
self.procession: typing.List[comps.Composition] = list() self.procession: typing.List[comps.Composition] = list()
if self.positron["is_new_activation"] == 1: if self.positron["is_new_activation"] == 1:
self.positron["is_new_activation"] = 0 self.positron["is_new_activation"] = 0
self.procession.append(comps.registry["recognition"](screen, atom)) self.procession.append(comps.registry["recognition"](screen, reactor, atom))
return return
for i in self.positron["testdata"].keys(): for i in self.positron["testdata"].keys():
if i == "additional_inf": if i == "additional_inf":
continue continue
self.procession.append(comps.registry[i](screen, atom)) self.procession.append(comps.registry[i](screen, reactor, atom))
# self.procession.reverse() # self.procession.reverse()
random.shuffle(self.procession) random.shuffle(self.procession)
@@ -76,6 +76,7 @@ class Reactor():
self.current_atom: typing.Tuple[pt.Electron, pt.Nucleon, dict] self.current_atom: typing.Tuple[pt.Electron, pt.Nucleon, dict]
self.round_set = 0 self.round_set = 0
self.current_atom = pt.Atom.placeholder() self.current_atom = pt.Atom.placeholder()
#print(self.atoms_new)
def set_round(self, title, procession): def set_round(self, title, procession):
self.round_set = 1 self.round_set = 1
@@ -90,11 +91,10 @@ class Reactor():
2: "新记忆模式", 2: "新记忆模式",
3: "总复习模式" 3: "总复习模式"
} }
processions = { processions = {
1: self.atoms_review, 1: self.atoms_review,
2: self.atoms_new, 2: self.atoms_new,
3: list(set(self.atoms_new + self.atoms_review)) 3: (self.atoms_new + self.atoms_review)
} }
ret = 1 ret = 1
if stage == 1 and len(processions[1]) == 0: if stage == 1 and len(processions[1]) == 0:
@@ -104,6 +104,12 @@ class Reactor():
return ret return ret
def forward(self, step = 1): def forward(self, step = 1):
"""
返回值规则:
1: 重定向至 failed
-1: 此轮已完成
0: 下一个记忆单元
"""
if self.index + step >= len(self.procession): if self.index + step >= len(self.procession):
if len(self.failed) > 0: if len(self.failed) > 0:
self.procession = self.failed self.procession = self.failed
@@ -118,7 +124,7 @@ class Reactor():
return -1 # 此轮已完成 return -1 # 此轮已完成
self.index += step self.index += step
self.current_atom = self.procession[self.index] self.current_atom = self.procession[self.index]
self.current_appar = Apparatus(self.screen, self.current_atom).iterator() self.current_appar = Apparatus(self.screen, self, self.current_atom).iterator()
return 0 return 0
def save(self): def save(self):

View File

@@ -1,11 +1,10 @@
Screen { Screen {
align: center middle; align: center middle;
} }
#main_container { #main_container {
align: center middle; align: center middle;
width: 80%; width: 95%;
height: auto; height: auto;
border: thick $primary-lighten-2; border: thick $primary-lighten-2;
padding: 2; padding: 2;
@@ -52,4 +51,4 @@ Button {
margin-bottom: 0; margin-bottom: 0;
align-horizontal: center; align-horizontal: center;
width: 40%; width: 40%;
} }