Reputation: 9
I am using tkinter on Python 3 to make a calculator. I have the layout finished. Now I am trying to get it so that when I press a button, it is displayed in the entry box. For example, if I press the 2 button followed by the + button followed by the 3 button, I want it displayed in the entry box at the top of the program.
import tkinter
import tkinter.messagebox
class myGUI:
def __init__(self):
self.main_window = tkinter.Tk()
self.main_window.title('Calculator')
## Font
button_font = ('Verdana', 15)
entry_font = ('Verdana', 36)
## Define the frames
self.frameZero = tkinter.Frame(self.main_window)
self.frameOne = tkinter.Frame(self.main_window)
self.frameTwo = tkinter.Frame(self.main_window)
self.frameThree = tkinter.Frame(self.main_window)
self.frameFour = tkinter.Frame(self.main_window)
self.frameFive = tkinter.Frame(self.main_window)
## Define the buttons
self.my_button1 = tkinter.Button(self.frameOne, text='1', command = lambda:btnClick(my_button1), height = 3, width = 7, font = button_font)
self.my_button2 = tkinter.Button(self.frameOne, text='2', command = lambda:btnClick(my_button2), height = 3, width = 7, font = button_font)
self.my_button3 = tkinter.Button(self.frameOne, text='3', command = lambda:btnClick(my_button3), height = 3, width = 7, font = button_font)
self.my_buttonadd = tkinter.Button(self.frameOne, text='+', command = lambda:btnClick(my_buttonadd), height = 3, width = 7, font = button_font)
self.my_button4 = tkinter.Button(self.frameTwo, text='4', command = lambda:btnClick(my_button4), height = 3, width = 7, font = button_font)
self.my_button5 = tkinter.Button(self.frameTwo, text='5', command = lambda:btnClick(my_button5), height = 3, width = 7, font = button_font)
self.my_button6 = tkinter.Button(self.frameTwo, text='6', command = lambda:btnClick(my_button6), height = 3, width = 7, font = button_font)
self.my_buttonsub = tkinter.Button(self.frameTwo, text='-', command = lambda:btnClick(my_buttonsub), height = 3, width = 7, font = button_font)
self.my_button7 = tkinter.Button(self.frameThree, text='7', command = lambda:btnClick(my_button7), height = 3, width = 7, font = button_font)
self.my_button8 = tkinter.Button(self.frameThree, text='8', command = lambda:btnClick(my_button8), height = 3, width = 7, font = button_font)
self.my_button9 = tkinter.Button(self.frameThree, text='9', command = lambda:btnClick(my_button9), height = 3, width = 7, font = button_font)
self.my_buttonmult = tkinter.Button(self.frameThree, text='*', command = lambda:btnClick(my_buttonmult), height = 3, width = 7, font = button_font)
self.my_buttonC = tkinter.Button(self.frameFour, text='C', height = 3, width = 7, font = button_font)
self.my_button0 = tkinter.Button(self.frameFour, text='0', command = lambda:btnClick(my_button0), height = 3, width = 7, font = button_font)
self.my_buttonperiod = tkinter.Button(self.frameFour, text='.', command = lambda:btnClick(my_buttonperiod), height = 3, width = 7, font = button_font)
self.my_buttondiv = tkinter.Button(self.frameFour, text='/', command = lambda:btnClick(my_buttondiv), height = 3, width = 7, font = button_font)
self.my_buttoncalc = tkinter.Button(self.frameFive, text='Calculate', height = 4, width = 30, font = button_font)
## Define the entry area
self.my_entry = tkinter.Entry(self.frameZero, width = 13, font = entry_font)
## Pack the entry area
self.my_entry.pack(side = 'left')
## Pack the buttons
self.my_button1.pack(side = 'left')
self.my_button2.pack(side = 'left')
self.my_button3.pack(side = 'left')
self.my_buttonadd.pack(side = 'left')
self.my_button4.pack(side = 'left')
self.my_button5.pack(side = 'left')
self.my_button6.pack(side = 'left')
self.my_buttonsub.pack(side = 'left')
self.my_button7.pack(side = 'left')
self.my_button8.pack(side = 'left')
self.my_button9.pack(side = 'left')
self.my_buttonmult.pack(side = 'left')
self.my_buttonC.pack(side = 'left')
self.my_button0.pack(side = 'left')
self.my_buttonperiod.pack(side = 'left')
self.my_buttondiv.pack(side = 'left')
self.my_buttoncalc.pack(side = 'left')
## Pack the frames
self.frameZero.pack()
self.frameOne.pack()
self.frameTwo.pack()
self.frameThree.pack()
self.frameFour.pack()
self.frameFive.pack()
## Click button function
def btnClick(numbers):
global operator
operator=operator + str(numbers)
my_entry = self.set(operator)
tkinter.mainloop()
my_gui = myGUI()
Upvotes: 1
Views: 40
Reputation: 5774
You need to implement a tk.StringVar()
that can store the value at the top of the calculator screen. The main methods to know are .get()
and .set()
for this variable, that's how you access the value (.get()
) or update it (.set()
). You have to link this to the entry with the textvariable
argument. Once you get that set up, I changed the inputs to your btnClick()
function to all be strings. Once you have the string you want (for example "12+5") you can use python's built in eval()
function to compute the result! Note, this method is not safe in that users may execute arbitrary code with it (hack your program) depending on how you implement it! A working version of your code looks like:
import tkinter
import tkinter.messagebox
class myGUI:
def __init__(self):
self.main_window = tkinter.Tk()
self.main_window.title('Calculator')
## Font
button_font = ('Verdana', 15)
entry_font = ('Verdana', 36)
## Define the frames
self.frameZero = tkinter.Frame(self.main_window)
self.frameOne = tkinter.Frame(self.main_window)
self.frameTwo = tkinter.Frame(self.main_window)
self.frameThree = tkinter.Frame(self.main_window)
self.frameFour = tkinter.Frame(self.main_window)
self.frameFive = tkinter.Frame(self.main_window)
## Define the entry area
self.entry_variable = tkinter.StringVar()
self.my_entry = tkinter.Entry(self.frameZero, textvariable=self.entry_variable, width=13, font=entry_font)
## Define the buttons
self.my_button1 = tkinter.Button(self.frameOne, text='1', command = lambda:btnClick("1"), height = 3, width = 7, font = button_font)
self.my_button2 = tkinter.Button(self.frameOne, text='2', command = lambda:btnClick("2"), height = 3, width = 7, font = button_font)
self.my_button3 = tkinter.Button(self.frameOne, text='3', command = lambda:btnClick("3"), height = 3, width = 7, font = button_font)
self.my_buttonadd = tkinter.Button(self.frameOne, text='+', command = lambda:btnClick("+"), height = 3, width = 7, font = button_font)
self.my_button4 = tkinter.Button(self.frameTwo, text='4', command = lambda:btnClick("4"), height = 3, width = 7, font = button_font)
self.my_button5 = tkinter.Button(self.frameTwo, text='5', command = lambda:btnClick("5"), height = 3, width = 7, font = button_font)
self.my_button6 = tkinter.Button(self.frameTwo, text='6', command = lambda:btnClick("6"), height = 3, width = 7, font = button_font)
self.my_buttonsub = tkinter.Button(self.frameTwo, text='-', command = lambda:btnClick("-"), height = 3, width = 7, font = button_font)
self.my_button7 = tkinter.Button(self.frameThree, text='7', command = lambda:btnClick("7"), height = 3, width = 7, font = button_font)
self.my_button8 = tkinter.Button(self.frameThree, text='8', command = lambda:btnClick("8"), height = 3, width = 7, font = button_font)
self.my_button9 = tkinter.Button(self.frameThree, text='9', command = lambda:btnClick("9"), height = 3, width = 7, font = button_font)
self.my_buttonmult = tkinter.Button(self.frameThree, text='*', command = lambda:btnClick("*"), height = 3, width = 7, font = button_font)
self.my_buttonC = tkinter.Button(self.frameFour, text='C', height = 3, width = 7, font = button_font)
self.my_button0 = tkinter.Button(self.frameFour, text='0', command = lambda:btnClick("0"), height = 3, width = 7, font = button_font)
self.my_buttonperiod = tkinter.Button(self.frameFour, text='.', command = lambda:btnClick("."), height = 3, width = 7, font = button_font)
self.my_buttondiv = tkinter.Button(self.frameFour, text='/', command = lambda:btnClick("/"), height = 3, width = 7, font = button_font)
self.my_buttoncalc = tkinter.Button(self.frameFive, text='Calculate', height = 4, width = 30, font = button_font, command=self.calculate)
## Pack the entry area
self.my_entry.pack(side = 'left')
## Pack the buttons
self.my_button1.pack(side = 'left')
self.my_button2.pack(side = 'left')
self.my_button3.pack(side = 'left')
self.my_buttonadd.pack(side = 'left')
self.my_button4.pack(side = 'left')
self.my_button5.pack(side = 'left')
self.my_button6.pack(side = 'left')
self.my_buttonsub.pack(side = 'left')
self.my_button7.pack(side = 'left')
self.my_button8.pack(side = 'left')
self.my_button9.pack(side = 'left')
self.my_buttonmult.pack(side = 'left')
self.my_buttonC.pack(side = 'left')
self.my_button0.pack(side = 'left')
self.my_buttonperiod.pack(side = 'left')
self.my_buttondiv.pack(side = 'left')
self.my_buttoncalc.pack(side = 'left')
## Pack the frames
self.frameZero.pack()
self.frameOne.pack()
self.frameTwo.pack()
self.frameThree.pack()
self.frameFour.pack()
self.frameFive.pack()
## Click button function
def btnClick(number_clicked):
self.entry_variable.set("{}{}".format(self.entry_variable.get(), number_clicked))
def calculate(self):
print("{}".format(eval(str(self.entry_variable.get()))))
self.entry_variable.set("{}".format(str(eval(str(self.entry_variable.get())))))
my_gui = myGUI()
my_gui.main_window.mainloop() # this should NOT be inside your class like you had it...
Overall, I liked your frame layout, and overall design. Lambda functions were good too! Welcome to StackOverflow.
Upvotes: 1