T. Stenger
T. Stenger

Reputation: 9

How can I alter my code so that when I press a button, it is displayed in the entry box?

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

Answers (1)

Reedinationer
Reedinationer

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

Related Questions