1. 程式人生 > 其它 >python-tkinter實現電子算盤

python-tkinter實現電子算盤

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()

【執行測試