Skip to content Skip to sidebar Skip to footer

How Do I Properly Insert The Numbers That I Pressed On In My Calculator Into The Text Widget At The Last Index?

When I pres '100' for example, in the text box it outputs '001'. I try using -1 in the index but the same thing still happens, and I tried doing .insert(0. end, num) as well but it

Solution 1:

The index "end" represents the position just after the last character in the widget.

output.insert("end", num) 

From the official documentaton:

end - Indicates the character just after the last one in the entry's string. This is equivalent to specifying a numerical index equal to the length of the entry's string.


Solution 2:

You are working way too hard. You have to consider that your buttons are all the exact same thing, from a graphical standpoint. You could build your entire interface in just a few lines. Since every button is going to call calc, simply write conditional statements in calc to handle the various possibilities. You could build the entire functionality of a calculator in that one function.

import tkinter as tk 

window = tk.Tk()
window.title('Calculator')

#output for calculator
output = tk.Text(window, font = 'none 12 bold', height=4, width=25, wrap='word')
output.grid(row=0, column=0, columnspan=4, pady=10)

def calc(data):
    if data.isnumeric() or data == '.':
        output.insert('end', data)
    elif data in ['-', '+', '*', '/']:
        #write code for handling operators
        pass #delete this line
    elif data == '=':
        #write code for handling equals
        pass #delete this line
    elif data == 'pos':
        if output.get('1.0', '1.1') == '-':
            output.delete('1.0', '1.1') 
    elif data == 'neg':
        if output.get('1.0', '1.1') != '-':
            output.insert('1.0', '-')
    elif data in 'CE':
        if 'C' in data:
            output.delete('1.0', 'end')
        if 'E' in data:
            #clear your storage
            pass #delete this line

btn = dict(width=7, height=3)
pad = dict(padx=5, pady=5)

#all of your buttons
for i, t in enumerate(['pos', 'neg', 'C', 'CE', '7', '8', '9', '/', '4', '5', '6', '*', '1', '2', '3', '-', '0', '.', '+', '=']):
    tk.Button(window, text=t, command=lambda d=t: calc(d), **btn).grid(row=i//4+1, column=i%4, **pad)

#run calculator
window.mainloop()

I made a fully working OOP version of your calculator based on the example I just gave you. It's probably not perfect. I only spent 10 minutes on it. I added key bindings so you don't have to click buttons. You can expand this, learn from it, ignore it ... whatever makes you happy.

import tkinter as tk

class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.oper   = ['/', '*', '-', '+']
        self.queue  = []
        self.result = 0
        self.equate = False
        
        self.output = tk.Text(self, font='Consolas 18 bold', height=2, width=20, wrap='word')
        self.output.grid(row=0, column=0, columnspan=4, pady=8, padx=4)
        
        btn = dict(width=6, height=3, font='Consolas 12 bold')
        pad = dict(pady=2)
        
        special = dict(neg='<Shift-Key-->',pos='<Shift-Key-+>',C='<Key-Delete>',CE='<Key-End>')
        
        for i, t in enumerate(['pos', 'neg', 'C', 'CE', '7', '8', '9', '/', '4', '5', '6', '*', '1', '2', '3', '-', '0', '.', '+', '=']):
            tk.Button(self, text=t, command=lambda d=t: self.calc(d), **btn).grid(row=i//4+1, column=i%4, **pad)
            if t.isnumeric() or t in self.oper or t == '.':
                self.bind_all(f'<Key-{t}>', lambda e, d=t: self.calc(d))
            elif t == '=':
                self.bind_all('<Return>', lambda e, d=t: self.calc(d))
            else:
                self.bind_all(special[t], lambda e, d=t: self.calc(d))
                
    def calc(self, input):
        print(input)
        if input.isnumeric() or input == '.':
            self.output.insert('end', input)
        elif input == 'pos':
            if self.output.get('1.0', '1.1') == '-':
               self.output.delete('1.0', '1.1') 
        elif input == 'neg':
            if self.output.get('1.0', '1.1') != '-':
               self.output.insert('1.0', '-')
        elif input in self.oper and (t := self.output.get('1.0', 'end-1c')):
            if not self.equate:
                self.queue.append(t)
            self.queue.append(input)
            self.output.delete('1.0', 'end')
            self.equate = False
        elif input == '=' and len(self.queue):
            self.equate = True
            if self.queue[-1] in self.oper:
                self.queue.append(self.output.get('1.0', 'end-1c'))
            elif len(self.queue) > 2:
                self.queue = self.queue+self.queue[-2:]
                    
            self.result = str(eval(' '.join(self.queue)))
            self.output.delete('1.0', 'end')
            self.output.insert('end', self.result)
        elif input in 'CE':
            if 'C' in input:
                self.output.delete('1.0', 'end')
            if 'E' in input:
                self.queue = []
            
                    
if __name__ == '__main__':
    app = App()
    app.title('Calcsturbator')
    app.resizable(width=False, height=False)
    app.mainloop()

Post a Comment for "How Do I Properly Insert The Numbers That I Pressed On In My Calculator Into The Text Widget At The Last Index?"