将数字键绑定到计算器的按钮

时间:2013-04-09 21:01:50

标签: python tkinter key-bindings

我如何继续这样做?我不喜欢按每个按钮的想法。我真的想要了解所有这一切。我得到了绑定的概念我只是不知道该怎么做。

from tkinter import *


class Calc():
    def __init__(self):
        self.total = 0
        self.current = ""
        self.new_num = True
        self.op_pending = False
        self.op = ""
        self.eq_flag = False

    def num_press(self, num):
        temp = text_box.get()
        self.eq_flag = False
        temp2 = str(num)      
        if self.new_num == True:
            self.current = temp2
            self.new_num = False
        else:
            if temp2 == '.':
                if temp2 in temp:
                    return
            self.current = temp + temp2
        text_box.delete(0, END)
        text_box.insert(0, self.current)

    def calc_total(self):
        if self.op_pending == True:
            self.do_sum()
            self.op_pending = False

    def do_sum(self):
        self.current = float(self.current)
        if self.op == "add":
            self.total += self.current
        if self.op == "minus":
            self.total -= self.current
        if self.op == "times":
            self.total *= self.current
        if self.op == "divide":
            self.total /= self.current
        text_box.delete(0, END)
        text_box.insert(0, self.total)
        self.new_num = True

    def operation(self, op):
        if self.op_pending == True:
            self.do_sum()
            self.op = op
        else:
            self.op_pending = True
            if self.eq_flag == False:
                self.total = float(text_box.get())
            else:
                self.total = self.current
            self.new_num = True
            self.op = op
            self.eq_flag = False

    def cancel(self):
        text_box.delete(0, END)
        text_box.insert(0, "0")
        self.new_num = True

    def all_cancel(self):
        self.cancel()
        self.total = 0

    def sign(self):
        self.current = -(float(text_box.get()))
        text_box.delete(0, END)
        text_box.insert(0, self.current)

class My_Btn(Button):
    def btn_cmd(self, num):
        self["command"] = lambda: sum1.num_press(num)

sum1 = Calc()
root = Tk()
calc = Frame(root)
calc.grid()

root.title("Calculator")
text_box = Entry(calc, justify=RIGHT)
text_box.grid(row = 0, column = 0, columnspan = 4, pady = 5, padx=5)
text_box.insert(0, "0")

#Buttons
numbers = "789456123"
i = 0
bttn = []
for j in range(2,5):
    for k in range(3):
        bttn.append(My_Btn(calc, text = numbers[i]))
        bttn[i].grid(row = j, column = k, pady = 5, padx=5)
        bttn[i].btn_cmd(numbers[i])
        i += 1
clear = Button(calc, text = "C", width =1, height =1)
clear["command"] = sum1.cancel
clear.grid(row = 1, column = 0, pady = 5, padx=5)

all_clear = Button(calc, text = "AC", width =1, height =1)
all_clear["command"] = sum1.all_cancel
all_clear.grid(row = 1, column = 1, pady = 5, padx=5)

bttn_div = Button(calc, text = chr(247))
bttn_div["command"] = lambda: sum1.operation("divide")
bttn_div.grid(row = 1, column = 2, pady = 5, padx=5)

bttn_mult = Button(calc, text = "x", width =1, height =1)
bttn_mult["command"] = lambda: sum1.operation("times")
bttn_mult.grid(row = 1, column = 3, pady = 5, padx=5)

minus = Button(calc, text = "-", width =1, height =1)
minus["command"] = lambda: sum1.operation("minus")
minus.grid(row = 2, column = 3, pady = 5, padx=5)

add = Button(calc, text = "+", width =1, height =1)
add["command"] = lambda: sum1.operation("add")
add.grid(row = 3, column = 3, pady = 5, padx=5)

neg= Button(calc, text = "+/-", width =1, height =1)
neg["command"] = sum1.sign
neg.grid(row = 4, column = 3, pady = 5, padx=5)

equals = Button(calc, text = "=", width =1, height =1)
equals["command"] = sum1.calc_total
equals.grid(row = 5, column = 3, pady = 5, padx=5)

point = Button(calc, text = ".", width =1, height =1)
point["command"] = lambda: sum1.num_press(".")
point.grid(row = 5, column = 2, pady = 5, padx=5)

bttn_0 = Button(calc, text = "0", width =7, height =1)
bttn_0["command"] = lambda: sum1.num_press(0)
bttn_0.grid(row=5, column = 0, columnspan = 2, pady = 5, padx=5)

2 个答案:

答案 0 :(得分:2)

我会使用Entry小部件,而不是绑定每个键。人们会犯错误。他们想要按下退格键,或者使用箭头键或鼠标将光标放在某处并编辑他们输入的内容。你不想重新发明这一切。如果你给他们一个Entry小部件,你可以免费获得所有的编辑功能,并且可以在按Enter键时解析结果。

entry.bind('<Enter>', parse)

答案 1 :(得分:1)

我认为正确的方式是unutbu建议的方式,使用Entry。 (你可以使用ttk主题,如果你想使它看起来不像普通的条目,你可以使用焦点技巧使其工作,即使用户没有点击它。)

但是,如果你希望以自己的方式做事,你可以。您的key函数可以调度到执行实际工作的函数(append_digit表示数字,backspace表示退格/删除)。然后,如果你想要按钮做同样的事情,你可以添加它们,回调分派到相同的功能。例如:

from functools import partial
from Tkinter import *

root = Tk()

def key(event):
    print "pressed", repr(event.char)
    if event.char.isdigit():
        append_digit(event.char)
    elif event.char in ('\x08', '\x7f'):
        backspace()

def callback(event):
    frame.focus_set()
    print "clicked at", event.x, event.y

frame = Frame(root, width=100, height=100)
frame.bind("<Key>", key)
frame.bind("<Button-1>", callback)
frame.pack()

current = IntVar(0)
label = Label(frame, textvariable=current)
label.pack()

def button_callback(i):
    print "clicked button {}".format(i)
    append_digit(i)

def append_digit(digit):
    current.set(current.get() * 10 + int(digit))

def backspace():
    current.set(current.get() // 10)

for i in '1234567890':
    Button(frame, text=i, command=partial(button_callback, i)).pack()
Button(frame, text='C', command=backspace).pack()

frame.focus_set()
root.mainloop()

显然你可以添加更多按键和/或按钮 - 例如,“+”键和标有“+”的按钮都会触发添加功能,或者标有“AC”的按钮会触发current.set(0)功能,或者你想要什么。并且大概你可以设计一个比长按钮更好的用户界面。这只是为了向您展示这个想法。