1+ # 导入所需模块
2+ from io_ import input_ , output_ # 导入input_和output_模块
3+ import score # 导入score模块
4+ import info # 导入info模块
5+ import run # 导入run模块
6+ import load # 导入load模块
7+ import add_book # 导入add_book模块
8+ import flet as ft # 导入flet模块,并命名为ft
9+ from flet import * # 导入flet模块中的所有内容
10+ from uwords import uload # 导入uload函数
11+ import sys # 导入sys模块
12+ import json
13+ from lang import lang # 导入语言包模块
14+ import sys # 导入sys模块
15+ import os # 导入os模块
16+
17+ assert sys .version_info >= (3 , 10 ) # 断言Python版本不低于3.10
18+ i = 0 # 定义计数器变量i
19+
20+ # 定义main函数
21+ def main (page : ft .page ): # 定义名为main的函数,接收一个名为page的ft.page类型参数
22+ """
23+ 主函数,接收一个名为page的ft.page类型参数
24+ """
25+ with open ('config.json' , 'r' ) as f : # 打开配置文件
26+ config = json .load (f ) # 读取配置文件
27+
28+ # 定义view_pop函数
29+ def view_pop (view ): # 定义名为view_pop的函数,用于页面返回
30+ page .views .pop () # 弹出页面视图栈顶元素
31+ top_view = page .views [- 1 ] # 获取页面视图栈顶元素
32+ page .go (top_view .route ) # 页面跳转至栈顶元素的路由
33+
34+ # 设置页面标题
35+ page .title = "affelchen"
36+
37+ # 添加触觉反馈组件
38+ hf = ft .HapticFeedback ()
39+ page .overlay .append (hf ) # 将触觉反馈组件添加到页面覆盖层
40+ pb = ft .ProgressBar (width = 250 )
41+ # 定义ftc_onclick函数
42+ iv = 1
43+ def ftc_onclick (e ):
44+ """
45+ "ftc control"的点击事件处理函数
46+ """
47+ nonlocal iv
48+ nonlocal i # 使用nonlocal声明i为非局部变量
49+ hf .heavy_impact () # 产生重型触觉反馈
50+ bookname = dd .value
51+ book_words = load .load ("book_" + bookname )
52+ try :
53+ if binput .value == book_words [list (book_words )[i - 1 ]]:
54+ score .add_ (1 ) # 增加分数
55+ answer = True
56+ else :
57+ print ("wrong answer" ) # 打印错误信息
58+ answer = False
59+ except :
60+ ftctext .value = lang ("Score: " ) + score .get_ () # 显示分数
61+ pb .value = 1
62+
63+ if i < len (book_words ):
64+ if iv == 0 :
65+ ftctext .value = list (book_words )[i ]
66+ iv = 1
67+ pro1 = len (list (book_words ))
68+ pro = i / pro1 # 计算进度百分比
69+ print (pro )
70+ pb .value = pro
71+
72+ elif iv == 1 :
73+ if answer :
74+ ftctext .value = lang ("Correct!" )
75+
76+ else :
77+ ftctext .value = lang ("Wrong!" ) + "\n " + lang ("Correct answer:" ) + "\n " + book_words [list (book_words )[i - 1 ]]
78+ iv = 0
79+ i += 1 # 增加计数器
80+ elif i == len (book_words ):
81+ if iv == 0 :
82+ ftctext .value = lang ("Score: " ) + score .get_ () # 显示分数
83+ pb .value = 1
84+
85+ elif iv == 1 :
86+ if answer :
87+ ftctext .value = lang ("Correct!" )
88+
89+ else :
90+ ftctext .value = lang ("Wrong!" ) + "\n " + lang ("Correct answer:" ) + "\n " + book_words [list (book_words )[i - 1 ]]
91+ iv = 0
92+ i += 1 # 增加计数器
93+ else :
94+ ftctext .value = lang ("Score: " ) + score .get_ () # 显示分数
95+ print (ftc .content ) # 打印ftc的内容
96+ print (len (list (book_words )))
97+ print (i )
98+ page .update () # 更新页面
99+
100+ # 定义start函数
101+ def start (e ):
102+ """
103+ start_button的点击事件处理函数
104+ """
105+ hf .medium_impact () # 产生中型触觉反馈
106+ page .route = "/learn" # 设置页面路由为"/learn"
107+ page .update () # 更新页面
108+ def settings (e ):
109+ """
110+ start_button的点击事件处理函数
111+ """
112+ hf .medium_impact () # 产生中型触觉反馈
113+ page .route = "/settings" # 设置页面路由为"/learn"
114+ page .update ()
115+
116+
117+
118+ # 定义dropdown_changed函数
119+ def dropdown_changed (e ):
120+ """
121+ 下拉菜单的选择变化处理函数
122+ """
123+ nonlocal i # 使用nonlocal声明i为非局部变量
124+ i = 0 # 重置计数器
125+ bookname = dd .value
126+ book_words = load .load ("book_" + bookname )
127+ ftctext .value = list (book_words )[i ] # 设置ftctext的值为bookname
128+ i += 1 # 增加计数器
129+ page .update () # 更新页面
130+ print (bookname ) # 打印bookname
131+
132+ # 创建下拉菜单组件
133+ dd = ft .Dropdown (
134+ label = lang ("Book" ),
135+ hint_text = lang ("Choose Book from List:" ),
136+ on_change = dropdown_changed ,
137+ options = []
138+ )
139+ dd2 = ft .Dropdown (
140+ label = lang ("Language" ),
141+ hint_text = config ["lang" ],
142+ options = []
143+ )
144+ with open ('lang/lang.json' , 'r' ) as langf : # 打开语言配置文件
145+ langs = json .loads (langf .read ()) # 读取语言配置文件
146+ for i in range (len (langs )):
147+ dd2 .options .append (ft .dropdown .Option (langs [i ]))
148+
149+ # 创建信息卡片组件
150+ infocard = ft .Card (
151+ content = ft .Container (
152+ content = ft .Column (
153+ [
154+ ft .ListTile (
155+ leading = ft .Icon (ft .icons .ARTICLE_OUTLINED ),
156+ title = ft .Text ("affelchen GUI v.0.0.1" ),
157+ subtitle = ft .Text (
158+ lang ("Developed by hengheng\n Copyright Cherry Service 2024" )
159+ ),
160+ ),
161+ ],
162+ )
163+ )
164+ )
165+ settingscard = ft .Card (
166+ content = ft .Container (
167+ content = ft .Column (
168+ [
169+ ft .ListTile (
170+ leading = ft .Icon (ft .icons .SETTINGS_OUTLINED ),
171+ title = ft .Text (lang ("Settings" )),
172+ subtitle = ft .ElevatedButton (lang ("Go to Settings" ), icon = ft .icons .START_ROUNDED , on_click = settings )
173+ ),
174+
175+ ],
176+ )
177+ )
178+ )
179+
180+ print (score .get_ ()) # 打印当前分数
181+
182+ # 定义刷新函数
183+ def refresh (e ):
184+ """
185+ 刷新分数的函数
186+ """
187+ hf .medium_impact () # 产生中型触觉反馈
188+ scorecard .content .content .controls [0 ].title .value = lang ("Score: " ) + score .get_ () # 设置分数卡片的标题为当前分数
189+ page .update () # 更新页面
190+
191+ scorecard = ft .Card (
192+ content = ft .Container (
193+ content = ft .Column (
194+ [
195+ ft .ListTile (
196+ leading = ft .Icon (ft .icons .SCOREBOARD_OUTLINED ),
197+ title = ft .Text (lang ("Score: " ) + score .get_ ()),
198+ subtitle = ft .ElevatedButton ("Refresh" , icon = ft .icons .REFRESH_ROUNDED , on_click = refresh )
199+ )
200+ ],
201+ )
202+ )
203+ )
204+ def close_banner (e ):
205+ page .banner .open = False
206+ page .update ()
207+ def show_banner_click ():
208+ page .banner .open = True
209+ page .update ()
210+ page .banner = ft .Banner (
211+ bgcolor = ft .colors .AMBER_100 ,
212+ leading = ft .Icon (ft .icons .WARNING_AMBER_ROUNDED , color = ft .colors .AMBER , size = 40 ),
213+ content = ft .Text (
214+ lang ("Oops, there were some errors while trying to read the booklist. Pleas Check the server_repo in Settings." )
215+ ),
216+ actions = [
217+ ft .TextButton (lang ("Go to Settings" ), on_click = settings ),
218+ ft .TextButton (lang ("Ignore" ), on_click = close_banner ),
219+ ],
220+ )
221+ # 从文件加载书单列表
222+ opts = load .load ("book_listl" )
223+ if opts != None : # 如果文件存在,则读取文件内容:
224+ for i in range (len (opts )):
225+ print (opts [i ]) # 打印每个书单列表项
226+ dd .options .append (ft .dropdown .Option (opts [i ])) # 将每个书单列表项添加到下拉菜单选项中
227+ else :
228+ show_banner_click () # 显示错误提示
229+
230+
231+ # 创建书单卡片组件
232+ bookcard = ft .Card (
233+ content = ft .Container (
234+ content = ft .Column (
235+ [
236+ ft .ListTile (
237+ leading = ft .Icon (ft .icons .BOOK_OUTLINED ),
238+ title = ft .Text (lang ("Please Choose a Book from List:" )),
239+ subtitle = ft .Text (" " ),
240+ ),
241+ dd # 添加下拉菜单组件
242+ ],
243+ )
244+ )
245+ )
246+
247+ # 创建带有开始按钮的卡片组件
248+ startcard = ft .Card (
249+ content = ft .Container (
250+ content = ft .Column (
251+ [
252+ ft .ListTile (
253+ leading = ft .Icon (ft .icons .INPUT_ROUNDED ),
254+ title = ft .Text (lang ("Press Button to Start:" )),
255+ subtitle = ft .ElevatedButton (lang ("Start" ),icon = ft .icons .START_ROUNDED , on_click = start )
256+ )
257+ ],
258+ )
259+ )
260+ )
261+
262+ col = ft .Column ([infocard , settingscard , scorecard , bookcard , startcard ], spacing = 10 ,scroll = ft .ScrollMode .ALWAYS ,) # 组合卡片组件并设置间距
263+ ftctext = ft .Text (theme_style = ft .TextThemeStyle .HEADLINE_LARGE ) # 创建文本组件
264+ ftc = ft .Container ( # 创建"ftc control"用于learn页面上的卡片UI
265+ content = ftctext ,
266+ alignment = ft .alignment .center , # 设置对齐方式
267+ bgcolor = ft .colors .INDIGO_300 , # 设置背景颜色
268+ width = 250 , # 设置宽度
269+ height = 400 , # 设置高度
270+ border_radius = 10 , # 设置边框半径
271+ ink = True , # 启用墨水效果
272+ on_click = ftc_onclick # 设置点击事件处理函数
273+ )
274+
275+ binput = ft .TextField (label = lang ("input" )) # 创建文本字段
276+
277+ # 定义route_change函数
278+ def route_change (e , ftc = ftc , col = col ):
279+ """
280+ 包括"learn"和"settings"页面UI的切换
281+ """
282+ print ("Route change:" , e .route ) # 打印路由变化信息
283+ page .views .clear () # 清空页面视图栈
284+ page .views .append (
285+ ft .View (
286+ "/" ,
287+ [col ],
288+ vertical_alignment = ft .MainAxisAlignment .CENTER
289+ )
290+ )
291+ def bback (e ): # 定义名为bback的函数
292+ hf .medium_impact () # 产生中型触觉反馈
293+ page .go ("/" ) # 返回主页面
294+ if page .route == "/learn" :
295+ page .views .append (
296+ View (
297+ "/learn" ,
298+ [
299+ ft .Row ([ft .FloatingActionButton (icon = ft .icons .ARROW_BACK_ROUNDED , on_click = bback ), pb ], spacing = 5 ),
300+ ftc ,
301+ binput
302+ ],
303+ vertical_alignment = ft .MainAxisAlignment .SPACE_AROUND ,
304+ horizontal_alignment = ft .CrossAxisAlignment .CENTER
305+ )
306+ )
307+ def close_dlg (e ):
308+ dlg .open = False
309+ page .update ()
310+ dlg = ft .AlertDialog (
311+ modal = True ,
312+ title = ft .Text (lang ("Settings Saved" )),
313+ content = ft .Text (lang ("Please restart the app to apply the changes." )),
314+ actions = [
315+ ft .TextButton (lang ("Ignore" ), on_click = close_dlg ),
316+ ],
317+ actions_alignment = ft .MainAxisAlignment .END ,
318+ on_dismiss = lambda e : print ("Modal dialog dismissed!" ),
319+ )
320+ def save_url (e ): # 定义名为save_url的函数
321+ hf .medium_impact () # 产生中型触觉反馈
322+ server_url = sutf .value # 获取输入框的值
323+ print (server_url ) # 打印输入框的值
324+ page .banner .open = False
325+ page .update () # 更新页面
326+ bback ("e" )
327+ opts = load .load ("book_listl" )
328+ if opts != None : # 如果文件存在,则读取文件内容:
329+ for i in range (len (opts )):
330+ print (opts [i ]) # 打印每个书单列表项
331+ dd .options .append (ft .dropdown .Option (opts [i ])) # 将每个书单列表项添加到下拉菜单选项中
332+ page .update () # 更新页面
333+ else :
334+ show_banner_click () # 显示错误提示
335+ if dd2 .value != None : # 如果下拉菜单有值,则更新语言配置
336+ config ["lang" ] = dd2 .value # 更新语言配置
337+ if server_url != "" : # 如果输入框有值,则更新服务器配置
338+ config ["server_url" ] = server_url # 更新服务器配置
339+ with open ('config.json' , 'w' ) as f : # 打开配置文件:
340+ json .dump (config , f ) # 写入配置文件
341+ page .dialog = dlg
342+ dlg .open = True
343+ page .update ()
344+
345+ sutf = ft .TextField (label = lang ("book_repo" ), autocorrect = False , hint_text = config ["server_url" ])
346+ if page .route == "/settings" :
347+ page .views .append (
348+ View (
349+ "/settings" ,
350+ [
351+ ft .Row ([ft .FloatingActionButton (icon = ft .icons .ARROW_BACK_ROUNDED , on_click = bback )], spacing = 5 ),
352+ sutf ,
353+ dd2 ,
354+ ft .ElevatedButton (lang ("Save" ), on_click = save_url )
355+ ],
356+
357+ )
358+ )
359+ page .update () # 更新页面
360+
361+ page .on_route_change = route_change # 设置页面路由变化处理函数
362+ page .on_view_pop = view_pop # 设置页面返回处理函数
363+ page .go (page .route )
364+ page .update ()
365+
366+ ft .app (target = main ) # 将main函数作为目标函数传递给ft.app
0 commit comments