Welcome to Code Forum!

Join a community that supports you and your coding journey from day one. We strive to be a friendly, supportive community that empowers everyone to be better developers. By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.

    GIF shows where to locate </> in the thread and or post editor toolbar.
    To learn more about how to use our BBCode feature, review our "How to post your code into threads" here.

    Thank you, Code Forum.

Yet another simple basic tkinter calculator

menator01

Gold Coder
Can use either button or keyboard. esc will clear and either return key will calculate. Very few bug checks. So may run into one here and there.

Python:
import tkinter as tk
from decimal import Decimal

class Window(tk.Tk):
    ''' Class creates the display window '''
    def __init__(self):
        super().__init__()
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)
        self.resizable(False, False)
        self.title('Tkinter Basic Calculator')

        # Create a textvariable for entry manipulation
        self.var = tk.StringVar()
        self.entry = tk.Entry(self, textvariable=self.var, font=(None, 12))
        self.entry.grid(column=0, row=0, sticky='we', padx=5, pady=3)
        self.entry.insert('end', '0')

        # Sert focus on the entry widget
        self.entry.focus()

        # Create container for buttons
        btn_container = tk.Frame(self)
        btn_container.grid(column=0, row=1, sticky='news')
        for i in range(3):
            btn_container.grid_columnconfigure(i, weight=3, uniform='button')

        # Create the dgits for button text
        digits = [i for i in range(1, 10)]

        # Empty list to hold buttons and some variables for columns and rows
        buttons = []
        i = 0
        col, row = 0, 0

        # 1x1 image
        pixel = tk.PhotoImage(width=1, height=1)

        # Keep a reference of image
        pixel.backup = pixel # Note button will not work without this

        # Create the buttons
        for button in digits:
            buttons.append(tk.Button(btn_container, text=button, width=74, height=15))
            buttons[i]['image'] = pixel
            buttons[i]['compound'] = 'left'
            buttons[i]['cursor'] = 'hand2'
            buttons[i]['command'] = lambda btn=buttons[i]['text']: self.pressed(btn)
            buttons[i].grid(column=col, row=row, padx=2, pady=2)
            
            # Increatment for each loop through     
            i += 1

            # Set columns and rows
            if col >= 2:
                row += 1
                col = 0
            else:
                col += 1
        
        # Create the zeo button
        zero = tk.Button(btn_container, text='0', image=pixel, cursor='hand2', compound='center')
        zero.grid(column=0, row=3, sticky='we', padx=2, pady=2)
        zero.configure(command=lambda val='0': self.pressed(val))
        
        # Button to clear tthe label text
        clear_btn = tk.Button(btn_container, text='Clear', width=74, height=15, compound='center', command=self.clear)
        clear_btn.grid(column=0, columnspan=4, row=4, sticky='new', padx=2, pady=2)
        clear_btn.configure(cursor='hand2', bg='tomato', activebackground='red', fg='white', activeforeground='white',
        image=pixel, font=(None, 12, 'bold'))

        # Create the decimal/period button
        self.period = tk.Button(btn_container, text='.', anchor='s', width=74, height=15, image=pixel, compound='center')
        self.period.grid(column=1, row=3, sticky='we', padx=2, pady=2, ipady=1)
        self.period.configure(font=(None, 24), command=lambda val='.': self.pressed(val), cursor='hand2')

        # Create the equal button
        self.eq_btn = tk.Button(btn_container, text='=', width=74, height=15, image=pixel, compound='center')
        self.eq_btn.grid(column=2, row=3, sticky='we', padx=2, pady=2)
        self.eq_btn.configure(font=(None, 24), command=lambda: self.calculate(), cursor='hand2')

        # Create list of symbols
        symb = ['x','/','+','-']

        # Empty list to hold symbols buttons
        symbols = []
        
        for i in range(len(symb)):
            button = tk.Button(btn_container, text=symb[i], cursor='hand2')
            symbols.append(button)
            symbols[i]['command'] = lambda symbol=button.cget('text'): self.pressed(symbol)
            symbols[i].grid(column=3, row=i, sticky='we', padx=2, pady=2)
            symbols[i].configure(font=(None, 18), width=74, height=15, image=pixel, compound='center')

        # Bind some buttons
        self.bind('<Return>', self.calculate)
        self.bind('<KP_Enter>', self.calculate)
        self.bind('<Escape>', self.clear)

        # Using trace to manipulate the the entry field
        self.var.trace('w', self.change)

        # Check for valid input
        valid = self.register(self.valid)
        self.entry.configure(validate='key', validatecommand=(valid, '%S'))

    def valid(self, arg):
        ''' Method for validating characters insert. We only want numbers
            or calculation symbols '''
        if arg == 'x':
            return True
        elif arg.isalpha() or arg == '=':
            return False
        else:
            return True

    def change(self, var, mode, index):
        ''' Method will replace * with x for the multiply symbol '''
        var = self.var.get()
        var = var.replace('*', 'x')

        # If there is a leading zero replace with entry
        if self.var.get()[:-1] == '0' and len(var) ==2:
            var = self.var.get()[1:]

        self.entry.delete(0, 'end')
        self.entry.insert('end', var)

    # method for the buttons
    def pressed(self, btn):
        ''' Method places pressed button keys into the entry field '''
        self.entry.insert('end', btn)

    def calculate(self, event=None):
        ''' Method for calaculting results '''
        values = self.entry.get()

        # If x in the calculation replace with *
        if 'x' in values:
            values = values.replace('x', '*')
        result = eval(values)

        # If the results is a float and has only zero on the right side, normalize
        if isinstance(result, float):
            result = Decimal(result).normalize()
        else:
            result = result

        # Clear entry field and insert results
        self.entry.delete(0, 'end')
        self.entry.insert('end', result)
        
    # Clear the entry field
    def clear(self, event=None):
        self.entry.delete(0, 'end')
        self.entry.insert('end', '0')


Window().mainloop()
 
Last edited:
Can use either button or keyboard. esc will clear and either return key will calculate. Very few bug checks. So may run into one here and there.

Python:
import tkinter as tk
from decimal import Decimal

class Window(tk.Tk):
    ''' Class creates the display window '''
    def __init__(self):
        super().__init__()
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)
        self.resizable(False, False)
        self.title('Tkinter Basic Calculator')

        # Create a textvariable for entry manipulation
        self.var = tk.StringVar()
        self.entry = tk.Entry(self, textvariable=self.var, font=(None, 12))
        self.entry.grid(column=0, row=0, sticky='we', padx=5, pady=3)
        self.entry.insert('end', '0')

        # Sert focus on the entry widget
        self.entry.focus()

        # Create container for buttons
        btn_container = tk.Frame(self)
        btn_container.grid(column=0, row=1, sticky='news')
        for i in range(3):
            btn_container.grid_columnconfigure(i, weight=3, uniform='button')

        # Create the dgits for button text
        digits = [i for i in range(1, 10)]

        # Empty list to hold buttons and some variables for columns and rows
        buttons = []
        i = 0
        col, row = 0, 0

        # 1x1 image
        pixel = tk.PhotoImage(width=1, height=1)

        # Keep a reference of image
        pixel.backup = pixel # Note button will not work without this

        # Create the buttons
        for button in digits:
            buttons.append(tk.Button(btn_container, text=button, width=74, height=15))
            buttons[i]['image'] = pixel
            buttons[i]['compound'] = 'left'
            buttons[i]['cursor'] = 'hand2'
            buttons[i]['command'] = lambda btn=buttons[i]['text']: self.pressed(btn)
            buttons[i].grid(column=col, row=row, padx=2, pady=2)
           
            # Increatment for each loop through    
            i += 1

            # Set columns and rows
            if col >= 2:
                row += 1
                col = 0
            else:
                col += 1
       
        # Create the zeo button
        zero = tk.Button(btn_container, text='0', image=pixel, cursor='hand2', compound='center')
        zero.grid(column=0, row=3, sticky='we', padx=2, pady=2)
        zero.configure(command=lambda val='0': self.pressed(val))
       
        # Button to clear tthe label text
        clear_btn = tk.Button(btn_container, text='Clear', width=74, height=15, compound='center', command=self.clear)
        clear_btn.grid(column=0, columnspan=4, row=4, sticky='new', padx=2, pady=2)
        clear_btn.configure(cursor='hand2', bg='tomato', activebackground='red', fg='white', activeforeground='white',
        image=pixel, font=(None, 12, 'bold'))

        # Create the decimal/period button
        self.period = tk.Button(btn_container, text='.', anchor='s', width=74, height=15, image=pixel, compound='center')
        self.period.grid(column=1, row=3, sticky='we', padx=2, pady=2, ipady=1)
        self.period.configure(font=(None, 24), command=lambda val='.': self.pressed(val), cursor='hand2')

        # Create the equal button
        self.eq_btn = tk.Button(btn_container, text='=', width=74, height=15, image=pixel, compound='center')
        self.eq_btn.grid(column=2, row=3, sticky='we', padx=2, pady=2)
        self.eq_btn.configure(font=(None, 24), command=lambda: self.calculate(), cursor='hand2')

        # Create list of symbols
        symb = ['x','/','+','-']

        # Empty list to hold symbols buttons
        symbols = []
       
        for i in range(len(symb)):
            button = tk.Button(btn_container, text=symb[i], cursor='hand2')
            symbols.append(button)
            symbols[i]['command'] = lambda symbol=button.cget('text'): self.pressed(symbol)
            symbols[i].grid(column=3, row=i, sticky='we', padx=2, pady=2)
            symbols[i].configure(font=(None, 18), width=74, height=15, image=pixel, compound='center')

        # Bind some buttons
        self.bind('<Return>', self.calculate)
        self.bind('<KP_Enter>', self.calculate)
        self.bind('<Escape>', self.clear)

        # Using trace to manipulate the the entry field
        self.var.trace('w', self.change)

        # Check for valid input
        valid = self.register(self.valid)
        self.entry.configure(validate='key', validatecommand=(valid, '%S'))

    def valid(self, arg):
        ''' Method for validating characters insert. We only want numbers
            or calculation symbols '''
        if arg == 'x':
            return True
        elif arg.isalpha() or arg == '=':
            return False
        else:
            return True

    def change(self, var, mode, index):
        ''' Method will replace * with x for the multiply symbol '''
        var = self.var.get()
        var = var.replace('*', 'x')

        # If there is a leading zero replace with entry
        if self.var.get()[:-1] == '0' and len(var) ==2:
            var = self.var.get()[1:]

        self.entry.delete(0, 'end')
        self.entry.insert('end', var)

    # method for the buttons
    def pressed(self, btn):
        ''' Method places pressed button keys into the entry field '''
        self.entry.insert('end', btn)

    def calculate(self, event=None):
        ''' Method for calaculting results '''
        values = self.entry.get()

        # If x in the calculation replace with *
        if 'x' in values:
            values = values.replace('x', '*')
        result = eval(values)

        # If the results is a float and has only zero on the right side, normalize
        if isinstance(result, float):
            result = Decimal(result).normalize()
        else:
            result = result

        # Clear entry field and insert results
        self.entry.delete(0, 'end')
        self.entry.insert('end', result)
       
    # Clear the entry field
    def clear(self, event=None):
        self.entry.delete(0, 'end')
        self.entry.insert('end', '0')


Window().mainloop()
unspectacular but nice 🙂
 
Back
Top Bottom