更新前的思路:
1、增加番茄时间功能,由于app设计不能退出,所有每学习25分钟休息5分钟就需要孩子自己退出app,再重新打开app,我看能不能设计学习一开始就记录学习的时间,记录一个番茄时间的过程,等到25分钟时就提示小孩退出app重新打开(或者将所有变量清0,从新计算!),打开app时记录时间,这个时间要写入数据表fq表(番茄表),每一次按键即启动bt函数时,就分析当前按按钮时间是否在fq表中最新的时间(用id自增倒序排列)后25分钟内,如果是程序继续,如果不是就让所有按键按不了,并在input提醒小孩退出(或者恢复到开始选择年级的界面),通常这个时候小孩会休息完回来,那么他从新开始程序就要生成一个fq表中的新id和记录新的时间。
每次答题后要记录小孩的学习情况到fq表中,那么这个表需要记录什么呢,一个是答题数目,一个是答题内容和方式(按目前分为有声答题,无声答题,听写),还有答题的内容。考虑到孩子选择的多样性,他可能在答题的过程中退出程序,再重新选定答题内容,那么就需要比较多的列来记录。例外,退出程序后再进入程序,记录再进入时间,如果这个时间在25分钟内那么就在最后一个fq表的id上记录上面这些信息。有声年级、有声题数、有声每题平均速度;无声年级、无声题数、无声每题速度;听写年级、听写题数、听写每题平均速度。所有的平均速度按总用时,除以答题答对题数。
结果显示:在label中显示“本次番茄时间,无声n,x题,m秒,有声n,x题,m秒,听写n等等”。
上面是以前写的,一天我又有新的想法,每个番茄时间就应该只能做一样任务,那么上面的fq表就设置方式,1为无声,2为有声,3为听写,题数、平均秒数,再加一列为状态列,1为启动,0为未启动。为什么要设置状态列,因为我这个app不会有退出,退出后从16格选25格要重新打开app,所有应该有做题时候(做对题)就可以把状态列设置为1,一开始设置为0,当为1时,退出app后再进入就会被锁定,不给app启用所有按键,并提醒小孩退出app,很多东西就是要化繁为简。label也设置在侧边显示,显示最近22多个番茄任务的完成状态。
更新的一些代码:
前面的思路在实践过程中有所改变,一个番茄时间内可以做不同的学习,也都有记录,番茄工作时间结束,就会播放音乐,继续学习也可以,但会卡,按一次屏幕休息1秒,并在上面提示休息。音乐刚好5分钟,结束后就能再学习,再学习记录新的番茄时间。
resources_folder = Path(__file__).joinpath("../resources/").resolve()
db_filepath = resources_folder.joinpath("cy.db")
db_filepath0 = r'D:\bee\qwrz2\src\qwrz2\resources\qwrznew.db'
#测试参数1为手机,0为电脑,2为boox平板
sjcs = 1
if sjcs == 1:
sj_file = '/data/data/com.qwcy.qwcy/cy0621.db'
if Path(sj_file).exists():
db_filepath = sj_file
else:
shutil.copy(db_filepath, sj_file)
db_filepath = sj_file
db_filepath0 = '/storage/emulated/0/Pictures/qwrznew.db'
db_filepath0这个数据库是千纬认字的数据库,fq表也是在里面,多个app共用一个数据库,这个在android10以下才能用吧,高版本的安卓不知道怎办。
conn0 = sqlite3.connect(db_filepath0, timeout=10, check_same_thread=False)
c = conn0.cursor()
cursor = c.execute("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='fq'")
row = cursor.fetchone()
have_fq = row[0]
if have_fq ==0:
c.execute('''CREATE TABLE fq (
fid INTEGER PRIMARY KEY AUTOINCREMENT,
fs INTEGER,
sj TEXT,
ts INTEGER,
cuo INTEGER,
ys INTEGER,
zt INTEGER,
nr TEXT);
''')
conn0.commit()
c.close()
conn0.close()
fq表的结构如上。
一些显示番茄时间学习情况、增加番茄时间题数,错误题数,确定番茄时间状态的函数:
def fq_qk():
if globals()['cixu'] == 1:
conn = sqlite3.connect(db_filepath0, timeout=10, check_same_thread=False)
c = conn.cursor()
query_str = 'select fs,sj,ts,cuo,nr from fq where zt = 1 order by fid desc limit 0,28;'
cursor = c.execute(query_str)
rows = cursor.fetchall()
stext3 = ""
for row in rows:
sj0=datetime.datetime.strptime(row[1], "%Y-%m-%d %H:%M:%S")
sj=str(sj0.hour).zfill(2)+":"+str(sj0.minute).zfill(2)
if row[0]==1:
fs='无声'
elif row[0]==2:
fs='有声'
elif row[0]==3:
fs='听写'
elif row[0]==4:
fs='口算'
elif row[0]==5:
fs='成语'
elif row[0]==6:
fs='英语'
stext3 = stext3 + f'{sj} {row[4]}{fs}{row[2]}({row[3]})题\n'
c.close()
conn.close()
globals()['fqqk']=stext3
else:
stext3 = globals()['fqqk']
return stext3
def get_fqbsj(fs):
fsb = 0
conn = sqlite3.connect(db_filepath0, timeout=10, check_same_thread=False)
c = conn.cursor()
query_str = 'select fs,sj,zt from fq order by fid desc;'
cursor = c.execute(query_str,)
row = cursor.fetchone()
if row:
fqbsj = row[1]
fsb = row[0]
zt = row[2]
else:
dqsj = datetime.datetime.now() #当前时间
dqsjc = dqsj.strftime("%Y-%m-%d %H:%M:%S")
query_str = 'INSERT INTO fq (fs,sj,ts,cuo,ys,zt) VALUES (?,?,0,0,0,0);'
c.execute(query_str,(fs,dqsjc,))
conn.commit()
fqbsj = dqsjc
zt = 0
if fsb != fs:
query_str = 'INSERT INTO fq (fs,sj,ts,cuo,ys,zt) VALUES (?,?,0,0,0,0);'
c.execute(query_str,(fs,fqbsj,))
conn.commit()
zt = 0
c.close()
conn.close()
return fqbsj,zt
def get_newfqbsj(fs):
conn = sqlite3.connect(db_filepath0, timeout=10, check_same_thread=False)
c = conn.cursor()
dqsj = datetime.datetime.now() #当前时间
dqsjc = dqsj.strftime("%Y-%m-%d %H:%M:%S")
query_str = 'INSERT INTO fq (fs,sj,ts,cuo,ys,zt) VALUES (?,?,0,0,0,0);'
c.execute(query_str,(fs,dqsjc,))
conn.commit()
fqbsj = dqsjc
zt = 0
c.close()
conn.close()
return fqbsj,zt
def upt_fqbsj(fqbsj,fs,njt):
conn = sqlite3.connect(db_filepath0, timeout=10, check_same_thread=False)
c = conn.cursor()
query_sql = "update fq set zt = 1 ,nr = ? where fs = ? and sj = ?"
c.execute(query_sql, (njt,fs,fqbsj,))
conn.commit()
c.close()
conn.close()
def up_fqbsj(fqbsj,fs,ts,cuo):
conn = sqlite3.connect(db_filepath0, timeout=10, check_same_thread=False)
c = conn.cursor()
query_sql = "update fq set ts = ts + ?, cuo = cuo + ? where fs = ? and sj = ?"
c.execute(query_sql, (ts,cuo,fs,fqbsj,))
conn.commit()
c.close()
conn.close()
globals()['syt'] = 0
globals()['stopyyt'] = 0
设置2个全局变量
fs=5
fqbsj,zt = get_fqbsj(fs) #获取这个fs下的番茄时间
fqbsj0 = datetime.datetime.strptime(fqbsj, "%Y-%m-%d %H:%M:%S")
dqsj = datetime.datetime.now() #当前时间
globals()['timec'] = (dqsj - fqbsj0).total_seconds()
# print(globals()['timec'])
if globals()['timec'] >= 1800:
fqbsj,zt=get_newfqbsj(fs) #时间超过30分钟,插入新的番茄时间
globals()['stop'] = 0
globals()['stopyyt'] = 1500
names['ts_' + str(globals()['syt'])] = Timer(1500, stopyy)#25分钟后播放音乐,提示休息
names['ts_' + str(globals()['syt'])].setDaemon(True)
names['ts_' + str(globals()['syt'])].start()
elif globals()['timec'] < 1800 and globals()['timec'] >=1500:
#休息时间
globals()['stop'] = 1
else:
#工作时间
if 'ts_' + str(globals()['syt']) in names and int(globals()['stopyyt']-(1500-globals()['timec'])) > 60 and globals()['stopyyt'] > 60:
names['ts_' + str(globals()['syt'])].cancel()
globals()['syt'] = globals()['syt'] + 1
names['ts_' + str(globals()['syt'])] = Timer(int(1500-globals()['timec']), stopyy)#X分钟后播放音乐,提示休息
names['ts_' + str(globals()['syt'])].setDaemon(True)
names['ts_' + str(globals()['syt'])].start()
globals()['stopyyt'] = int(1500-globals()['timec'])
if 'ts_' + str(globals()['syt']) not in names:
names['ts_' + str(globals()['syt'])] = Timer(int(1500-globals()['timec']), stopyy)#25分钟后播放音乐,提示休息
names['ts_' + str(globals()['syt'])].setDaemon(True)
names['ts_' + str(globals()['syt'])].start()
globals()['stopyyt'] = int(1500-globals()['timec'])
globals()['stop'] = 0
#*******番茄时间到*******
if globals()['stop'] == 1:
c_input.value = '休息!' + c_input.value
c_label.text=c_label.text+'\n'+'休息5分钟时间到\n等音乐结束即5分钟后可以继续或换其他学习'
for i in range(1,25):
setattr(names['button_' + str(i)],"enabled",False)
sleep(1)
for i in range(1,25):
setattr(names['button_' + str(i)],"enabled",True)
#*******番茄时间到*******
#******************************番茄时间控制程序段**************************************
上面是核心代码,继续采用timer播放音乐。这个代码我改了一天,测试了又测试,在电脑上可以,到手机上就不行。一开始用多线程打开一个需要等待1000多秒才播放音乐的函数,在手机平板上就失效,不知道为什么,安卓不喜欢等待太久的线程,会自动把它关闭吗?但用timer,也是差不多道理,要等1000多秒才去启动函数,有时候也会失灵,为此在每次按屏幕按键时,不断取消和生成新的timer,这样确保能够启动休息5分钟播放音乐的程序。
def stopyy():
stream = miniaudio.stream_file(str(resources_folder.joinpath('4480.mp3')))
with miniaudio.PlaybackDevice() as device:
device.start(stream)
sleep(300)
这个音乐原来是4分多钟的,我把它拉长到5分钟,本来要用软件,但发现都要收费之类,能用python还是用python。
from pydub import AudioSegment
import os
# 加载现有的MP3文件
original_song = AudioSegment.from_file("448.mp3", format="mp3")
# 设置需要加长的时长(以毫秒为单位)
desired_length = 293000 # 例如,加长到10秒
# 如果原歌曲长度小于目标长度,则重复播放直到达到目标长度
if len(original_song) < desired_length:
while len(original_song) < desired_length:
original_song += original_song
# 修改音乐长度到目标长度
extended_song = original_song[:desired_length]
# 导出加长后的音乐
extended_song.export("4480.mp3", format="mp3")
使用pydub要下载一个ffmepg文件。
这是界面,用这个番茄时间可以记录孩子每个25分钟内的学习情况,有效监控孩子的学习,给未能在孩子身边督促孩子学习的家长来说,是一件很有意义的事。