重构布局系统并改进界面
This commit is contained in:
@@ -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
54
main.py
@@ -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:
|
||||||
|
@@ -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"]
|
||||||
# 选择题测试
|
# 选择题测试
|
||||||
|
20
reactor.py
20
reactor.py
@@ -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):
|
||||||
|
@@ -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%;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user