Python可视化训练
一实验目的
1.使学生综合运用图形用户界面设计的概念;
2.使学生熟悉使用中间面板,组成层次复杂的GUI界面;
3.使学生掌握Python图形绘制和图像处理步骤与方法;
4.使学生掌握Python可视化处理的步骤、方法与编程;
二实验环境及实验准备
1.所需硬件环境为微机;
2.所需软件环境为Python 3.X等;
3.掌握Python下界面容器与基本组件的基本知识与应用;
4.掌握Python下事件处理模型;
5.掌握Python下图形绘制的方法;
三实验内容
(一)、设计实现电子算盘,并完成测试
【题目描述】
给小朋友设计一个电子算盘。要求绘制电子算盘界面,设计并实现打珠算过程(界面参考如下图示)。
界面右侧要求以图形绘制的方式绘制自画像,注意不能是图像文件显示的形式。
【源代码程序】(鼠标左击上移,右击下移)
from tkinter import * tk = Tk() tk.title("电子算盘") # 窗口名称 tank = Canvas(tk, width=1000, height=600, bg='ivory') # 创建画板 tank.pack() # 显示画板 tank.create_rectangle(30, 30, 520, 190, width=3) # 左上侧方框 tank.create_rectangle(30, 190, 520, 570, width=3) # 左下侧方框 tank.create_oval(900, 400, 620, 120, fill='yellow') tank.create_oval(800, 200, 850, 250, fill='black', tags='left') tank.create_oval(670, 200, 720, 250, fill='black', tags='right') tank.create_line(695, 320, 825, 320, width=5, tags='mouth') backround_image = PhotoImage(file="orange2.png") # 上珠图片 backround_image2 = PhotoImage(file="yellow2.png") # 下珠图片 button = Button() button1 = [button for i in range(5)] # 5个上珠 button2 = [[button for i in range(5)] for i in range(4)] # 四行,每行五个下珠 num = [[0 for i in range(5)] for i in range(4)] # 五个下珠分别对应的数值 num2 = [0 for i in range(5)] # 五个上珠分别对应的数值 def getNum(num, num2): # 计算算盘总和 sum_ = 0 for i in num: for j in i: sum_ += j for i in num2: sum_ += i return sum_ def button_click_back(events): # 鼠标右击点击事件触发 widget = events.widget for i in range(5): if widget == button1[i]: button1[i].place(x=40 + 100 * i, y=50 + 70 * 1) num2[i] = 0 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) for i in range(4): for j in range(5): if widget == button2[i][j]: if i == 3: button2[3][j].place(x=40 + 100 * j, y=210 + 70 * (i + 1)) num[3][j] = 0 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) if i == 2: button2[2][j].place(x=40 + 100 * j, y=210 + 70 * (i + 1)) button2[3][j].place(x=40 + 100 * j, y=210 + 70 * (i + 2)) num[2][j] = 0 num[3][j] = 0 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) if i == 1: button2[1][j].place(x=40 + 100 * j, y=210 + 70 * (i + 1)) button2[2][j].place(x=40 + 100 * j, y=210 + 70 * (i + 2)) button2[3][j].place(x=40 + 100 * j, y=210 + 70 * (i + 3)) num[1][j] = 0 num[2][j] = 0 num[3][j] = 0 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) if i == 0: button2[0][j].place(x=40 + 100 * j, y=210 + 70 * (i + 1)) button2[1][j].place(x=40 + 100 * j, y=210 + 70 * (i + 2)) button2[2][j].place(x=40 + 100 * j, y=210 + 70 * (i + 3)) button2[3][j].place(x=40 + 100 * j, y=210 + 70 * (i + 4)) num[0][j] = 0 num[1][j] = 0 num[2][j] = 0 num[3][j] = 0 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) def button_click(events): # 鼠标左击点击事件触发 widget = events.widget for i in range(5): if widget == button1[i]: button1[i].place(x=40 + 100 * i, y=50 + 70 * 0) num2[i] = 10 ** (4 - i) * 5 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) for i in range(4): for j in range(5): if widget == button2[i][j]: if i == 3: button2[0][j].place(x=40 + 100 * j, y=210 + 70 * (i - 3)) button2[1][j].place(x=40 + 100 * j, y=210 + 70 * (i - 2)) button2[2][j].place(x=40 + 100 * j, y=210 + 70 * (i - 1)) button2[3][j].place(x=40 + 100 * j, y=210 + 70 * (i)) num[0][j] = 10 ** (4 - j) * 1 num[1][j] = 10 ** (4 - j) * 1 num[2][j] = 10 ** (4 - j) * 1 num[3][j] = 10 ** (4 - j) * 1 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) if i == 2: button2[0][j].place(x=40 + 100 * j, y=210) button2[1][j].place(x=40 + 100 * j, y=210 + 70 * 1) button2[2][j].place(x=40 + 100 * j, y=210 + 70 * 2) num[0][j] = 10 ** (4 - j) * 1 num[1][j] = 10 ** (4 - j) * 1 num[2][j] = 10 ** (4 - j) * 1 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) if i == 1: button2[0][j].place(x=40 + 100 * j, y=210) button2[1][j].place(x=40 + 100 * j, y=210 + 70 * 1) num[0][j] = 10 ** (4 - j) * 1 num[1][j] = 10 ** (4 - j) * 1 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) else: button2[i][j].place(x=40 + 100 * j, y=210 + 70 * i) num[0][j] = 10 ** (4 - j) * 1 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) for i in range(5): # 生成5个上珠 button1[i] = Button(tk, image=backround_image) button1[i].bind("<Button-1>", button_click) button1[i].bind("<Button-3>", button_click_back) button1[i]["bg"] = "ivory" button1[i]["border"] = "0" button1[i].place(x=40 + 100 * i, y=50 + 70) for i in range(4): # 四行,每行生成5个下珠 for j in range(5): button2[i][j] = Button(tk, image=backround_image2) button2[i][j].bind("<Button-1>", button_click) button2[i][j].bind("<Button-3>", button_click_back) button2[i][j]["bg"] = "ivory" button2[i][j]["border"] = "0" button2[i][j].place(x=40 + 100 * j, y=210 + 70 * (i + 1)) tk.mainloop()第一题源代码
【运行测试】
(二)、以(一)中的电子算盘为基础,设计并实现珠算测试器,并完成测试。
【题目描述】
给小朋友设计一个珠算测试器,要求能够完成珠算加减法的测试。具体的要求功能如下:
(1) 用户启动测试,输入用户名后系统随机生成特定数目的加减法测试题;
(2) 要求测试使用表盘式或数字时秒表进行界面计时显示(参考如上图示);
(3) 对于每道测试题目,要求用户使用电子算盘完成珠算过程,当按下确认键时,将珠算结果与正确答案比对,并在界面上显示总题数、已答题数和已做对题数;
(4) 当测试完成,界面显示本次测试情况(包括用户名、测试题目及答题明细、对错情况、测试用时和测试成绩)
【源代码程序】
from random import randint from tkinter import * import tkinter.messagebox as msgbox tk = Tk() tk.title("电子算盘") # 窗口名称 tank = Canvas(tk, width=1000, height=600, bg='ivory') # 创建画板 tank.pack() # 显示画板 tank.create_rectangle(30, 30, 520, 190, width=3) # 左上侧方框 tank.create_rectangle(30, 190, 520, 570, width=3) # 左下侧方框 # tank.create_oval(900, 400, 620, 120, fill='yellow') # tank.create_oval(800, 200, 850, 250, fill='black', tags='left') # tank.create_oval(670, 200, 720, 250, fill='black', tags='right') # tank.create_line(695, 320, 825, 320, width=5, tags='mouth') backround_image = PhotoImage(file="orange2.png") # 上珠图片 backround_image2 = PhotoImage(file="yellow2.png") # 下珠图片 button = Button() button1 = [button for i in range(5)] # 5个上珠 button2 = [[button for i in range(5)] for i in range(4)] # 四行,每行五个下珠 num = [[0 for i in range(5)] for i in range(4)] # 五个下珠分别对应的数值 num2 = [0 for i in range(5)] # 五个上珠分别对应的数值 counter = 0 sure = Button() # 确定按钮 st = Button() # 启动检测按钮 equation = Label() # 算式 answer = Label(width=50, height=7) # 答题情况 name = Entry() # 用户名输入 true_result = Label(width=50, height=4) # 上一题的正确答案 digit = Label(tk, bg='yellow', fg='blue', height=5, width=25, font='宋体 10 bold') # 计时器 true = 0 # 已做对题数 false = 0 # 做错题数 score = 0 # 题目得分 result = 0 # 每道题的正确答案 topic = "" # 题目 def run_counter(digit, second): # 计时器 def counting(): global counter if second == 1: counter += 1 else: counter += 0 digit.config(text="计时器:" + str(counter)) digit.after(1000, counting) counting() def getNum(num, num2): # 计算算盘总和 sum_ = 0 for i in num: for j in i: sum_ += j for i in num2: sum_ += i return sum_ def suanshi(): # 生成随机加减法测试题 answer = 0 operator = "" num1 = 0 num2 = 0 p = randint(1, 2) if p == 1: while True: num1 = randint(0, 99999) num2 = randint(0, 99999) if num1 + num2 <= 99999: break answer = num1 + num2 operator = "+" elif p == 2: while True: num1 = randint(0, 99999) num2 = randint(0, 99999) if num1 - num2 > 0: break answer = num1 - num2 operator = "-" equation = str(num1) + operator + str(num2) return equation, answer def button_click_back(events): # 鼠标右击点击事件触发 widget = events.widget for i in range(5): if widget == button1[i]: button1[i].place(x=40 + 100 * i, y=50 + 70 * 1) num2[i] = 0 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) for i in range(4): for j in range(5): if widget == button2[i][j]: if i == 3: button2[3][j].place(x=40 + 100 * j, y=210 + 70 * (i + 1)) num[3][j] = 0 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) if i == 2: button2[2][j].place(x=40 + 100 * j, y=210 + 70 * (i + 1)) button2[3][j].place(x=40 + 100 * j, y=210 + 70 * (i + 2)) num[2][j] = 0 num[3][j] = 0 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) if i == 1: button2[1][j].place(x=40 + 100 * j, y=210 + 70 * (i + 1)) button2[2][j].place(x=40 + 100 * j, y=210 + 70 * (i + 2)) button2[3][j].place(x=40 + 100 * j, y=210 + 70 * (i + 3)) num[1][j] = 0 num[2][j] = 0 num[3][j] = 0 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) if i == 0: button2[0][j].place(x=40 + 100 * j, y=210 + 70 * (i + 1)) button2[1][j].place(x=40 + 100 * j, y=210 + 70 * (i + 2)) button2[2][j].place(x=40 + 100 * j, y=210 + 70 * (i + 3)) button2[3][j].place(x=40 + 100 * j, y=210 + 70 * (i + 4)) num[0][j] = 0 num[1][j] = 0 num[2][j] = 0 num[3][j] = 0 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) def button_click(events): # 鼠标左击点击事件触发 widget = events.widget for i in range(5): if widget == button1[i]: button1[i].place(x=40 + 100 * i, y=50 + 70 * 0) num2[i] = 10 ** (4 - i) * 5 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) for i in range(4): for j in range(5): if widget == button2[i][j]: if i == 3: button2[0][j].place(x=40 + 100 * j, y=210 + 70 * (i - 3)) button2[1][j].place(x=40 + 100 * j, y=210 + 70 * (i - 2)) button2[2][j].place(x=40 + 100 * j, y=210 + 70 * (i - 1)) button2[3][j].place(x=40 + 100 * j, y=210 + 70 * (i)) num[0][j] = 10 ** (4 - j) * 1 num[1][j] = 10 ** (4 - j) * 1 num[2][j] = 10 ** (4 - j) * 1 num[3][j] = 10 ** (4 - j) * 1 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) if i == 2: button2[0][j].place(x=40 + 100 * j, y=210) button2[1][j].place(x=40 + 100 * j, y=210 + 70 * 1) button2[2][j].place(x=40 + 100 * j, y=210 + 70 * 2) num[0][j] = 10 ** (4 - j) * 1 num[1][j] = 10 ** (4 - j) * 1 num[2][j] = 10 ** (4 - j) * 1 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) if i == 1: button2[0][j].place(x=40 + 100 * j, y=210) button2[1][j].place(x=40 + 100 * j, y=210 + 70 * 1) num[0][j] = 10 ** (4 - j) * 1 num[1][j] = 10 ** (4 - j) * 1 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) else: button2[i][j].place(x=40 + 100 * j, y=210 + 70 * i) num[0][j] = 10 ** (4 - j) * 1 label = Label(tk, text="当前数字:" + str(getNum(num, num2)), width=30, height=4) label.place(x=780, y=30) def start(): global name global equation global sure global result global digit global topic st.place_forget() digit.place(x=540, y=30) run_counter(digit, 1) Label(tk, text="用户名", bg="ivory").place(x=540, y=150) name = Entry(tk, show='', font=('Arial', 14)) name.place(x=580, y=150) p = suanshi() topic = p[0] result = p[1] equation = Label(tk, text=topic, width=40, height=4) equation.place(x=540, y=200) sure = Button(text="确定", command=judge, width=10, height=3) sure.place(x=850, y=200) def judge(): # 判断结果 global true global false global score global topic global result global true_result if true + false == 5: msgbox.showinfo('温馨提示', '恭喜您已做完所有题目!!!') answer["text"] = "用户名:" + name.get() + "\n已答题数:" + str(true + false) + "\n做对题数:" + str(true) + "\n做错题数:" \ + str(false) + "\n测试时长:" + str(counter) + "s" + "\n测试成绩:" + str(score) + "\n答题完毕!!!" answer.place(x=540, y=400) else: print(getNum(num, num2), result) if getNum(num, num2) == result: true += 1 score += 20 else: false += 1 answer["text"] = "总题数:5\n已答题数:" + str(true + false) + "\n已做对题数:" + str(true) + "\n做错题数:" + str( false) + "\n得分:" + str( score) answer.place(x=540, y=400) p = suanshi() true_result["text"] = "上一题题目:" + topic + "\n上一题正确答案:" + str(result) equation["text"] = p[0] result = p[1] equation.place(x=540, y=200) true_result.place(x=540, y=300) for i in range(5): # 生成5个上珠 button1[i] = Button(tk, image=backround_image) button1[i].bind("<Button-1>", button_click) button1[i].bind("<Button-3>", button_click_back) button1[i]["bg"] = "ivory" button1[i]["border"] = "0" button1[i].place(x=40 + 100 * i, y=50 + 70) for i in range(4): # 四行,每行生成5个下珠 for j in range(5): button2[i][j] = Button(tk, image=backround_image2) button2[i][j].bind("<Button-1>", button_click) button2[i][j].bind("<Button-3>", button_click_back) button2[i][j]["bg"] = "ivory" button2[i][j]["border"] = "0" button2[i][j].place(x=40 + 100 * j, y=210 + 70 * (i + 1)) st = Button(text="启动测试", command=start, width=50, height=10) st.place(x=600, y=100) tk.mainloop()
【运行测试】