python可视化练习一
(一)、设计实现电子算盘,并完成测试
【题目描述】
给小朋友设计一个电子算盘。要求绘制电子算盘界面,设计并实现打珠算过程(界面参考如下图示)。
界面右侧要求以图形绘制的方式绘制自画像,注意不能是图像文件显示的形式。
【源代码程序】
from tkinter import *
def initWindow():
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)] # 五个上珠分别对应的数值
canvas.create_oval(750, 370, 470, 90, fill='yellow')
canvas.create_oval(500, 170, 560, 200, fill='black')
canvas.create_oval(650, 170, 710, 200, fill='black')
canvas.create_arc(500, 200, 700, 300, start=-150, extent=120, style=ARC, width=3)
def get_empty():
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 bind():
def handler_adaptor(handler, fun, row, col):
"""事件处理函数的适配器,相当于中介,可以帮助tag_bind函数传递参数"""
return lambda event, handler=handler, fun=fun, col=col, row=row: handler(event=event, fun=fun, row=row, col=col)
def handler_adaptor2(handler2, fun, row):
"""事件处理函数的适配器,相当于中介,可以帮助tag_bind函数传递参数"""
return lambda event, handler2=handler2, fun=fun, row=row: handler2(event=event, fun=fun, row=row)
def handler(event, fun, row, col):
"""下珠上划"""
content = fun # 这个就是被点击的算珠id
empty = get_empty()
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 >= 110 + 10 * (row + 1):
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()
if row == 3:
if float(canvas.coords(content)[1]) + 40 <= 350:
canvas.move(content, 0, 40)
else:
if empty[row][col] == 1:
canvas.move(content, 0, 40)
def handler4(event, fun, row):
"""上珠下划"""
content = fun # 这个就是被点击的算珠id
if float(canvas.coords(content)[1]) + 20 <= 60:
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 = [int for i in range(5)] # 定义列表存储5个上珠
below_oval = [[int 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()
bind()
window.mainloop()