增补博客 第五篇 python 电子算盘
【题目描述】设计一个电子算盘。要求绘制电子算盘界面,设计并实现打珠算过程(界面参考如下图示)。
界面右侧要求以图形绘制的方式绘制自画像,注意不能是图像文件显示的形式。

图 电子算盘参考界面示意
【练习要求】请给出源代码程序和运行测试结果,源代码程序要求添加必要的注释。
from tkinter import *
def get_empty(canvas, below_oval, chushi):
empty = [[0 for j in range(5)] for i in range(4)]
for i in range(4):
for j in range(5):
if canvas.coords(below_oval[i][j]) != chushi[i][j]:
empty[i][j] = 1
print(empty)
return empty
def handler_adaptor(handler, **kwds):
return lambda event, handler=handler, kwds=kwds: handler(event, **kwds)
def handler_adaptor2(handler, **kwds):
return lambda event, handler=handler, kwds=kwds: handler(event, **kwds)
def initWindow(canvas, below_oval, chushi):
rect = canvas.create_rectangle(25, 40, 450, 400, width=3) # 算盘边框
x0, y0, x1, y1 = 0, 0, 0, 0
for i in range(5): # 生成串算珠的线
line_shu = canvas.create_line(70 + x0, 40 + y0, 70 + x1, 400 + y1, width=3)
x0 += 80
x1 += 80
line_fenge = canvas.create_line(25, 100, 450, 100, width=3) # 生成上下珠的分割线
x0, y0, x1, y1 = 0, 0, 0, 0
for i in range(5): # 生成5个上珠
top_oval[i] = canvas.create_oval(40 + x0, 60 + y0, 100 + x1, 90 + y1, fill='orange', tags=f"top{i}")
x0 += 80
x1 += 80
x0, y0, x1, y1 = 0, 0, 0, 0
for i in range(4): # 生成4*5个下珠
for j in range(5):
below_oval[i][j] = canvas.create_oval(40 + x0, 160 + y0, 100 + x1, 190 + y1, fill='yellow',
tags=f"below{i}{j}")
chushi[i][j] = canvas.coords(below_oval[i][j])
x0 += 80
x1 += 80
x0 = 0
x1 = 0
y0 += 60
y1 += 60
print(chushi)
num = [[0 for i in range(5)] for j in range(4)] # 五个下珠分别对应的数值
num2 = [0 for i in range(5)] # 五个上珠分别对应的数值
#哆啦A梦
# 画圆脸
canvas.create_oval((525, 70, 675, 220), fill='blue')
# 画圆脸
canvas.create_oval((540, 100, 660, 220), fill='white')
# 画椭圆
canvas.create_oval((600, 80, 630, 120), fill='white')
# 画椭圆
canvas.create_oval((570, 80, 600, 120), fill='white')
# 画椭圆眼睛
canvas.create_oval((603, 92, 615, 108), fill='black')
# 画椭圆眼睛
canvas.create_oval((585, 92, 597, 108), fill='black')
# 画椭圆眼睛
canvas.create_oval((606, 95, 612, 105), fill='white')
# 画椭圆眼睛
canvas.create_oval((588, 95, 594, 105), fill='white')
# 画圆鼻子
canvas.create_oval((593, 115, 607, 130), fill='red')
# 嘴
canvas.create_arc((540, 60, 660, 180), style='arc', start=240, extent=60) # 画弧线
canvas.create_line(600, 130, 600, 180, fill="black") # 竖线
# 胡须
canvas.create_line(615, 150, 645, 150, fill="black") # 横线
canvas.create_line(555, 150, 585, 150, fill="black") # 横线
canvas.create_line(558, 127, 585, 137, fill="black")
canvas.create_line(615, 137, 642, 127, fill="black")
canvas.create_line(558, 170, 585, 163, fill="black")
canvas.create_line(615, 163, 642, 168, fill="black")
# 身体
canvas.create_rectangle(550, 200, 650, 285, fill="blue") # 身体正前方
canvas.create_arc((560, 190, 640, 270), style='chord', start=135, extent=270, fill='white') # 画弧线
canvas.create_line((550, 200, 650, 200), fill="red", width=10, capstyle='round') # 圆滑轮廓线
canvas.create_arc((585, 270, 615, 300), style='chord', start=0, extent=180, fill='white') # 画弧线
canvas.create_line(585, 285, 615, 285, fill="white")
# 画脚
# 画椭圆
canvas.create_oval((540, 275, 590, 295), fill='white') # 左脚
canvas.create_oval((610, 275, 660, 295), fill='white') # 右脚
# 画手
canvas.create_polygon([550, 205, 550, 235, 520, 250, 520, 235], outline="black", fill="blue") # 手臂多边形
canvas.create_polygon([650, 205, 650, 235, 680, 250, 680, 235], outline="black", fill="blue")
canvas.create_oval((510, 230, 535, 255), fill='white') # 左圆形手掌
canvas.create_oval((665, 230, 690, 255), fill='white') # 右圆形手掌
# 画铃铛
canvas.create_oval((590, 200, 610, 220), fill='yellow') # 铃铛中心圆
canvas.create_line((591, 210, 609, 210), fill="black", width=5, capstyle='round') # 圆滑轮廓线
canvas.create_line((592, 210, 608, 210), fill="yellow", width=3, capstyle='round') # 圆滑轮廓线
canvas.create_oval((598, 213, 602, 217), fill='red') # 中心小红点
canvas.create_line(600, 218, 600, 220, fill="black")
# 画口袋
canvas.create_arc((570, 200, 630, 260), style='chord', start=180, extent=180, fill='white') # 画弧线
def bind(canvas, top_oval, below_oval, handler_adaptor, handler_adaptor2):
def handler(event, fun, row, col):
"""下珠上划"""
content = fun # 这个就是被点击的算珠id
empty = get_empty(canvas, below_oval, chushi)
if row == 0:
if float(canvas.coords(content)[1]) - 40 >= 100:
canvas.move(content, 0, -40)
else:
if empty[row - 1][col] == 1:
if float(canvas.coords(content)[1]) - 40 >= 100 + 60 * (row): # Adjusted boundary condition
canvas.move(content, 0, -40)
def handler2(event, fun, row):
"""上珠上划"""
content = fun # 这个就是被点击的算珠id
if float(canvas.coords(content)[1]) - 20 >= 40:
canvas.move(content, 0, -20)
def handler3(event, fun, row, col):
"""下珠下划"""
content = fun # 这个就是被点击的算珠id
empty = get_empty(canvas, below_oval, chushi)
if row == 3:
if float(canvas.coords(content)[1]) + 40 <= 400:
canvas.move(content, 0, 40)
else:
if empty[row][col] == 1: # 修正条件判断错误,使用 row + 1
canvas.move(content, 0, 40)
def handler4(event, fun, row):
"""上珠下划"""
content = fun # 这个就是被点击的算珠id
if float(canvas.coords(content)[1]) + 20 <= 100:
canvas.move(content, 0, 20)
for i in range(5):
canvas.tag_bind(top_oval[i], "<Button-1>", handler_adaptor2(handler2, fun=top_oval[i], row=i))
canvas.tag_bind(top_oval[i], "<Button-3>", handler_adaptor2(handler4, fun=top_oval[i], row=i))
for i in range(4):
for j in range(5):
canvas.tag_bind(below_oval[i][j], "<Button-1>",
handler_adaptor(handler, fun=below_oval[i][j], row=i, col=j))
canvas.tag_bind(below_oval[i][j], "<Button-3>",
handler_adaptor(handler3, fun=below_oval[i][j], row=i, col=j))
if __name__ == "__main__":
window = Tk()
window.title("电子算盘")
window.geometry("800x500")
canvas = Canvas(window, width="800", height="500", bg="white")
canvas.pack()
top_oval = [None for i in range(5)] # 定义列表存储5个上珠
below_oval = [[None for i in range(5)] for i in range(4)] # 定义列表存储4*5个下珠
chushi = [[0 for j in range(5)] for i in range(4)] # 所有下珠的初始坐标
initWindow(canvas, below_oval, chushi)
bind(canvas, top_oval, below_oval, handler_adaptor, handler_adaptor2)
window.mainloop()
增补博客 第五篇 python 电子算盘的更多相关文章
- 一鼓作气 博客--第五篇 note5
一.迭代器 二.装饰器 三.生成器 1.生成列表的方式有几种 2.把列表每个数都加1 2.1 data =[1,2,3] for i in map(lambda x:x+1,data):print(i ...
- Scrum 冲刺博客第五篇
一.当天站立式会议照片一张 二.每个人的工作 (有work item 的ID),并将其记录在码云项目管理中 昨天已完成的工作 实现题目的生成并将其显示到页面上,设置了背景音乐 今天计划完成的工作 判断 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(五)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- [转]有哪些值得关注的技术博客(Java篇)
有哪些值得关注的技术博客(Java篇) 大部分程序员在自学的道路上不知道走了多少坑,这个视频那个网站搞得自己晕头转向.对我个人来说我平常在学习的过程中喜欢看一些教程式的博客.这些博客的特点: 1. ...
- # Do—Now——团队冲刺博客_总结篇
Do-Now--团队冲刺博客_总结篇 目录 博客链接 作者 1. 第一篇(领航篇) @仇夏 2. 第二篇 @侯泽洋 3. 第三篇 @仇夏 4. 第四篇 @周亚杰 5. 第五篇 @唐才铭 6. 第六篇 ...
- JavaScript 系列博客(五)
JavaScript 系列博客(五) 前言 本篇博客学习 js 选择器来控制 css 和 html.使用事件(钩子函数)来处理事件完成后完成指定功能以及js 事件控制页面内容. js 选择器 在学习 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - 终结篇之发布项目
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 年度十佳 DevOps 博客文章(前篇)
如果说 15 年你还没有将 DevOps 真正应用起来,16 年再不实践也未免太落伍了.国内 ITOM 领军企业 OneAPM 工程师为您翻译整理了,2015 年十佳 DevOps 文章,究竟是不是深 ...
- 为了确认是您本人在申请搬家,请在原博客发表一 篇标题为《将博客搬至CSDN》的文章,并将文章地址填写在上方的"搬家通知地址"中
为了确认是您本人在申请搬家,请在原博客发表一 篇标题为<将博客搬至CSDN>的文章,并将文章地址填写在上方的"搬家通知地址"中
- thinkphp5项目--个人博客(五)
thinkphp5项目--个人博客(五) 项目地址 fry404006308/personalBlog: personalBloghttps://github.com/fry404006308/per ...
随机推荐
- 重磅发布 | Serverless 应用中心:Serverless 应用全生命周期管理平台
简介:Serverless 应用中心,是阿里云 Serverless 应用全生命周期管理平台.通过 Serverless 应用中心,用户在部署应用之前无需进行额外的克隆.构建.打包和发布操作,即可快 ...
- Flink 1.12 资源管理新特性回顾
简介: 介绍 Flink 1.12 资源管理的一些特性,包括内存管理.资源调度.扩展资源框架. 本文由社区志愿者陈政羽整理,Apache Flink Committer.阿里巴巴技术专家宋辛童,Apa ...
- [Cryptocurrency] (XMR) Monero GUI 连接远程节点 操作方式
Monero 官网下载的钱包,在 高级设置 的节点里支持 "本地节点" 和 "远程节点". 本地节点就是同步区块链数据到本地电脑,安全性高,占用空间大. 远程节 ...
- Asp-Net-Core开发笔记:进一步实现非侵入性审计日志功能
前言 上次说了利用 AOP 思想实现了审计日志功能,不过有同学反馈还是无法实现完全无侵入,于是我又重构了一版新的. 回顾一下:Asp-Net-Core开发笔记:实现动态审计日志功能 现在已经可以实现对 ...
- Mybatis逆向工程的2种方法,一键高效快速生成Pojo、Mapper、XML,摆脱大量重复开发
一.写在开头 最近一直在更新<Java成长计划>这个专栏,主要是Java全流程学习的一个记录,目前已经更新到Java并发多线程部分,后续会继续更新:而今天准备开设一个全新的专栏 <E ...
- Steam中将XBox手柄默认布局改为任天堂手柄布局的方法
1. 在Steam菜单栏找到"查看",选择大屏幕模式. 2. 进入大屏幕模式后,在菜单界面找到"设置". 3. 在设置界面找到"控制器",选 ...
- elasticsearch 6.2.4和elasticsearch-head环境搭建 使用docker-compose方式
elasticsearch 6.2.4和elasticsearch-head测试环境搭建 使用docker-compose方式 一 背景说明 对于新手来说搭建一个elasticsearch的测试环境稍 ...
- 后台生成单个Word文档
在实际项目开发中经常会遇到一种场景,客户希望点击页面上的生成文件按钮,执行程序动态填充数据到Word模板,直接在后台生成Word文档,而无需显示Word文档.目前网上有一些针对此需求的方案,但每个方案 ...
- webapi创建WCF WebService+WCF WebService远程服务调用
首先需要引入soapcore包 这个包提供了所需的类和soap终结点中间件. 引入这个这个包之后,我们需要定义提供的服务. 这里我写了一个用于查询省份面积的服务. 省份信息服务 /// <sum ...
- 【超详细】宝塔面板安装WordPress程序图文教程
宝塔面板是目前广受用户喜爱的服务器控制面板之一,自己也在用,确实很方便,很多用户的网站都是基于宝塔面板搭建,今天简单介绍下宝塔面板是如何安装WordPress的,方便新手用户快速部署.也方便自己以后查 ...