python秒表代码_斌哥教你自制千分秒表(键盘控制)

本文详细讲解了如何使用Python的turtle库,结合time模块,创建一个既能用空格键控制开始/暂停,又能用回车键清零的秒表。通过实例演示了如何绘制秒表界面,处理键盘事件,以及核心代码的设计和优化。适合学习事件驱动编程和turtle库应用。
摘要由CSDN通过智能技术生成

上节课我们绘制了用鼠标控制的千分秒表,还指出了一个隐藏的bug及其解决方案。今天我们来绘制使用键盘控制的千分秒表,请大家比较它与上节课代码的区别。

话不多说,上代码。

素材准备:

不需要任何素材,只需直接引用Python内置模块turtle和time即可。  

项目目标:

利用time.perf_counter()记录程序运行时间,使用海龟绘图画出时间信息,从而实现秒表计时功能:

1. 绘制秒表显示框;

2. 实现用空格键控制“开始/暂停”功能;

3. 实现用回车键控制“清除”功能。

894e8ac95e9159da753fb8399158a8d1.png

项目实施过程:

一、主函数代码说明。

1. 创建画笔和屏幕:

import turtle as ttimport timett.TurtleScreen._RUNNING = True  # 启动绘图,在IDE中运行加这句可避免报错time_pen, text_pen = tt.Pen(), tt.Pen()tt.hideturtle() #隐藏画笔time_pen.hideturtle() #隐藏画笔text_pen.hideturtle() #隐藏画笔game = tt.Screen()screen_w, screen_h = 600, 400game.setup(screen_w, screen_h)tt.tracer(0)

注释:主画笔tt用来绘制方框等不需擦除的图形,分别使用time_pen和text_pen来绘制时间和提示信息。

2. 绘制各功能键和秒表显示框:

#w, h, (x0, y0)分别存储了图片单位格子(像素)宽、高和左上角坐标w, h, x0, y0 = 30, 40, -200, 150draw_info(x0+w*5.5, y0+h*0.3, "按空格交替开始和暂停,按回车归零", 20, "black", tt)draw_square(x0+w*3, y0, w*5, h, "black",tt)draw_info(x0+w*5.5, y0-h*5/6, "00:00:00", 18, "red", time_pen)

3. 定义全局变量:

num = 0   #用来统计暂停次数,以便输出每次计时信息total_times = 0 #用来统计前几轮计时总时长 pass_time = 0   #用来统计本轮计时时长start_flag = False #标记秒表是否处于计时状态,False表示处于停止状态clear_flag = False #标记是否按下了“清除”按钮,False表示没有按下start_time = time.perf_counter() #设置计时起始时间为当前时间

4. 设置键盘触发函数,并监听屏幕,以便接收键盘事件:

tt.onkeypress(enter, "Return")tt.onkeypress(space, "space")tt.listen() # 监听

5. 死循环,让秒表开始工作,并随时响应按键事件,同时需要刷新每一帧画面:

while True:    if not start_flag: #秒表处于停止状态        start_time = time.perf_counter() #设置计时起始时间为当前时间    else:              #秒表处于计时状态        pass_time = time.perf_counter() - start_time #计算本轮计时时长        hour = (total_times + pass_time) // 3600        minute = ((total_times + pass_time) - hour * 3600) // 60        second = (total_times + pass_time) % 60        show_time = f'{hour:02.0f}:{minute:02.0f}:{second:.3f}'        time_pen.clear()        draw_info(x0+w*5.5, y0-h*5/6, show_time, 18, "red", time_pen)    if clear_flag:    #点击“清除”按钮        time_pen.clear()        draw_info(x0+w*5.5, y0-h*5/6, "00:00:00", 18, "red", time_pen)    tt.update()  #刷新每一帧画面      tt.done()

注释:若秒表处于停止状态,则时刻更新起始时间start_time为当前时间,否则保持起始时间不变,根据当前时间计算本轮计时时长,并将计时时长显示到方框中。刷新每一帧画面,用新时间取代旧时间。

二、绘制各功能键和显示文本

1. 根据输入的坐标,使用指定画笔显示文本信息:

'''函数功能:根据输入的坐标,显示文本信息函数名:draw_info(x, y, text, size, color, mypen)参数表:x, y -- 文本信息位置;       text -- 文本信息内容;       size, color -- 文本信息字体和颜色;       mypen -- 当前画笔对象。返回值:没有返回值。'''def draw_info(x, y, text, size, color, mypen):    mypen.penup()    mypen.goto(x, y)    mypen.pendown()    mypen.color(color)    mypen.write(text, align="center", font=("黑体", size, "normal"))

2. 根据输入的坐标,使用指定画笔绘制方框:

'''函数功能:根据输入的坐标和大小,绘制方框并填充颜色函数名:draw_square(x, y, w, h, color, mypen)参数表:x, y -- 方框左上角坐标;        w, h -- 方框的宽和高;        color -- 填充方框的颜色;        mypen -- 绘制方框所需要的画笔返回值:没有返回值。'''def draw_square(x, y, w, h, color, mypen):    mypen.penup()    mypen.goto(x, y)    mypen.down()    mypen.seth(0)    mypen.fillcolor(color)    mypen.begin_fill()    for i in range(2):        mypen.fd(w)        mypen.right(90)        mypen.fd(h)        mypen.right(90)    mypen.end_fill()

三、根据按下的键盘名称,执行相应操作

1. 函数说明:

这是本项目的核心代码。

为了响应键盘按下事件,需要为每个按键设置无参函数。

其中按下回车键相当于用鼠标点击“清除”按钮,需要把所有数据都归零,并重新绘制时间显示屏内容。

按下空格键相当于用鼠标点击“开始/暂停”按钮。若秒表处于计时状态,则将秒表状态改成暂停,同时将本轮计时时长pass_time加入到总时长total_times中,然后在秒表下方显示本轮计时时长;若秒表处于暂停状态,则将秒表状态改成计时。

2. 自定义函数解析:

'''函数功能:键盘响应按下回车键,清除所有文字显示信息,并修改相应全局变量,准备重新计时。函数名:enter()参数表:没有参数,在调用函数时,指定了按下的键名称。返回值:没有返回值。'''def enter():    global start_flag, clear_flag, total_times, num    start_flag, clear_flag = False, True    total_times, num = 0, 0    text_pen.clear()'''函数功能:键盘响应按下空格键,交替实现“开始”和“暂停”功能,并修改相应全局变量。函数名:space()参数表:没有参数,在调用函数时,指定了按下的键名称。返回值:没有返回值。'''  def space():      global start_flag, clear_flag, total_times, num    if start_flag:  #秒表处于计时状态        total_times += pass_time        num += 1        hour = pass_time // 3600        minute = (pass_time - hour * 3600) // 60        second = pass_time % 60        show_time = f'第{num}轮:{hour:02.0f}:{minute:02.0f}:{second:.3f}'        draw_info(x0+w*5.5, y0-h*(1+num*0.8), show_time, 16, "black", text_pen)    start_flag, clear_flag = not start_flag, False

课后思考

1. 鼠标响应事件和键盘响应事件有什么区别?为什么键盘响应事件中需要加tt.listen()语句,而鼠标响应事件却不需要?

  2. 在上节课中,我们把监控鼠标响应事件的game.onclick(play_game)语句放在了tt.update()语句后面;这节课中我们把监控键盘响应事件的tt.listen()语句放在了while循环语句前面,这样做效果一样吗?能否把game.onclick(play_game)语句也放在while循环语句前面?

结语:

好了,到这里,就把“在线秒表”各个模块的功能和代码实现都给大家做了详细的分析了。鼠标响应和键盘响应是海龟绘图的基本操作,有必要熟练掌握。 感兴趣的老师可以分析一下“课后思考”中的问题,写出相关代码。需要改进版代码的老师可以给我留言或微信联系我。 因为本项目的数据结构和算法原理都是自己闭门造车弄出来的,难免存在不足之处,欢迎各位老师批评指正。当然,如果你是新手,需要完整的代码,那可以加入“Python算法之旅”知识星球,下载完整的源代码。

需要本文word版的,可以加入“Python算法之旅”知识星球参与讨论和下载文件,“Python算法之旅”知识星球汇集了数量众多的同好,更多有趣的话题在这里讨论,更多有用的资料在这里分享。

我们专注Python算法,感兴趣就一起来!

d975d87365efc21f9b23eef7c33fc713.png

相关优秀文章:

阅读代码和写更好的代码

最有效的学习方式

斌哥教你自制多功能单词本

斌哥教你自制象棋打谱软件

斌哥教你自制围棋打谱软件

斌哥教你自制思维导图生成器改进版

斌哥教你绘制文件夹目录树(一)

斌哥教你绘制文件夹目录树(二)

斌哥教你绘制文件夹目录树(三)

斌哥教你自制千分秒表

a18d4106eb2ba66d5bf1a4905e58daea.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值