-1

I am trying to learn python and am trying out new projects, in this case a mini calculator. I have been wanting to create a "self-updating" label that prints the inputs that you put into the calculator, for example: 5+5. I am trying to do this with the same variable "Computation" that I have holding the string that is later computed with eval() function. I saw a couple of examples using ".config" and "after" but I can't seem to be able to get it to work. I would appreciate it if someone would be able to help me, thanks!

import tkinter

from tkinter import Button, Tk, ttk, messagebox
root = Tk()

root.geometry("300x150+600+250")
root.configure(background="black")

Computation = ""
VarDisplay = Computation


def Display():
    global Computation
    VarDisplay.config(Computation=Computation)
    root.after(1000, Display)
def Clear():
    global Computation
    Computation = ""
def Answer ():
    global Computation
    Computation = eval(Computation)
    tkinter.messagebox.showinfo("Answer",Computation)
    Computation = ""
def Trolling ():
    tkinter.messagebox.showinfo("Greetings", "Hello :)")
def OneFunc ():
    global Computation
    Computation += "1" 
def TwoFunc ():
    global Computation
    Computation += "2"
def ThreeFunc ():
    global Computation
    Computation += "3"
def FourFunc ():
    global Computation
    Computation += "4"
def FiveFunc ():
    global Computation
    Computation += "5"
def SixFunc ():
    global Computation
    Computation += "6"
def SevenFunc ():
    global Computation
    Computation += "7"
def EightFunc ():
    global Computation
    Computation += "8"
def NineFunc ():
    global Computation
    Computation += "9"
def ZeroFunc ():
    global Computation
    Computation += "0"
def AdditionFunc ():
    global Computation
    Computation += "+"
def MultiplicationFunc ():
    global Computation
    Computation += "*"
def SubtractionFunc ():
    global Computation
    Computation += "-"
def DivisionFunc ():
    global Computation
    Computation += "/"
def PlusMinusFunc ():
    global Computation
    Computation += "(-)"
def PercentageFunc ():
    global Computation
    Computation += "/100 *"
def DecimalFunc ():
    global Computation
    Computation += "."



test = tkinter.Label(root, text="Calc", width = 8).grid(column=0, row=0)
VarDisplay = tkinter.Label(root, text=VarDisplay, width = 20,bg='black',fg='White').grid(column=1,row=0,columnspan=3)
ACButton = ttk.Button(root, text = "AC", width = 5, command = Clear).grid(column=0, row=1)
PlusMinusButton = ttk.Button(root, text = "+ -",   width = 5, command = PlusMinusFunc).grid(column=1, row=1)
PercentageButton = ttk.Button(root, text = "%",   width = 5, command = PercentageFunc).grid(column=2, row=1)
DivisionButton = ttk.Button(root, text = "/",   width = 5, command = DivisionFunc).grid(column=3, row=1)
SevenButton = ttk.Button(root, text = "7",   width = 5, command = SevenFunc).grid(column=0, row=2)
EightButton = ttk.Button(root, text = "8",   width = 5, command = EightFunc).grid(column=1, row=2)
NineButton = ttk.Button(root, text = "9",   width = 5, command = NineFunc).grid(column=2, row=2)
MultiplicationButton = ttk.Button(root, text = "*",  width = 5,  command = MultiplicationFunc).grid(column=3, row=2)
FourButton = ttk.Button(root, text = "4",   width = 5, command = FourFunc).grid(column=0, row=3)
FiveButton = ttk.Button(root, text = "5",   width = 5, command = FiveFunc).grid(column=1, row=3)
SixButton = ttk.Button(root, text = "6",   width = 5, command = SixFunc).grid(column=2, row=3)
MinusButton = ttk.Button(root, text = "-",   width = 5, command = SubtractionFunc).grid(column=3, row=3)
OneButton = ttk.Button(root, text = "1",   width = 5, command = OneFunc).grid(column=0, row=4)
TwoButton = ttk.Button(root, text = "2",   width = 5, command = TwoFunc).grid(column=1, row=4)
ThreeButton = ttk.Button(root, text = "3",   width = 5, command = ThreeFunc).grid(column=2, row=4)
AdditionButton = ttk.Button(root, text = "+",   width = 5, command = AdditionFunc).grid(column=3, row=4)
ZeroButton = ttk.Button(root, text = "0",   width = 5, command = ZeroFunc).grid(column=0, row=5)
DecimalButton = ttk.Button(root, text = ".",   width = 5, command = DecimalFunc).grid(column=1, row=5)
EqualButton = ttk.Button(root, text = "=",   width = 5, command = Answer).grid(column=2, row=5)
RandomButton = ttk.Button(root, text = ":)",    width = 5, command = Trolling).grid(column=3, row=5)

Display()
root.mainloop()
  • why dont you use the options `textvariable` on the label? – Thingamabobs Oct 11 '22 at 13:42
  • your variable names are overlapping quite a lot, you need to keep them separate. That might not fix this problem, but it will help with them in the future. – KaliMachine Oct 11 '22 at 13:44
  • Please reduce this code down to a minimal example. I doubt that we need more than a dozen buttons and functions to reproduce this problem. See [mcve]. Also, please describe what _"can't seem to be able to get it to work"_ means - why can't you? What happens when you try? – Bryan Oakley Oct 11 '22 at 14:13
  • Try googling : " why I should not use eval() in my python code" – pippo1980 Oct 11 '22 at 15:08
  • Have a look at https://www.geeksforgeeks.org/python-setting-and-retrieving-values-of-tkinter-variable/amp/ – pippo1980 Oct 11 '22 at 15:17
  • I originally tries to simply add the value as a variable. The way in which I tried to do this is to create a label and assign the text as text = Computation. According to my logic, each time a button was pressed, the variable auto updated and would change within the table as it was assigned the same variable – MDares03 Oct 11 '22 at 15:38

1 Answers1

0

this works a little bit further

import tkinter


from tkinter import Tk
root = Tk()

root.geometry("300x200+600+250")
root.configure(background="black")

Computation = ""
VarDisplay = Computation


def Display():
    global Computation
    VarDisplayTK.config(text=Computation)
    root.after(100, Display)
    
def Clear():
    global Computation
    Computation = ""
    print('clear !!!!!!!!!!!')
    
    
def Answer ():
    global Computation
    Computation = eval(Computation)
    tkinter.messagebox.showinfo("Answer",Computation)
    Computation = ""

def Trolling ():
    tkinter.messagebox.showinfo("Greetings", "Hello :)")

def OneFunc ():
    global Computation
    Computation += "1" 

def TwoFunc ():
    global Computation
    Computation += "2"
    
def ThreeFunc ():
    global Computation
    Computation += "3"
    
def FourFunc ():
    global Computation
    Computation += "4"
    
def FiveFunc ():
    global Computation
    Computation += "5"
    
def SixFunc ():
    global Computation
    Computation += "6"
    
def SevenFunc ():
    global Computation
    Computation += "7"
    
def EightFunc ():
    global Computation
    Computation += "8"
    
def NineFunc ():
    global Computation
    Computation += "9"
    
def ZeroFunc ():
    global Computation
    Computation += "0"
    
def AdditionFunc ():
    global Computation
    Computation += "+"
    
def MultiplicationFunc ():
    global Computation
    Computation += "*"
    
def SubtractionFunc ():
    global Computation
    Computation += "-"
    
def DivisionFunc ():
    global Computation
    Computation += "/"
    
def PlusMinusFunc ():
    global Computation
    Computation += "-"
    
def PercentageFunc ():
    global Computation
    Computation += "/100 *"
    
def DecimalFunc ():
    global Computation
    Computation += "."
    

test = tkinter.Label(root, text="Calc", width = 8).grid(column=0, row=0)
VarDisplayTK = tkinter.Label(root, text=VarDisplay, width = 20,bg='red',fg='White')
VarDisplayTK .grid(column=1,row=0,columnspan=3)
ACButton = tkinter.Button(root, text = "AC", width = 5, command = Clear)
ACButton.grid(column=0, row=1)
PlusMinusButton = tkinter.Button(root, text = "+ -",   width = 5, command = PlusMinusFunc)
PlusMinusButton.grid(column=1, row=1)
PercentageButton = tkinter.Button(root, text = "%",   width = 5, command = PercentageFunc)
PercentageButton.grid(column=2, row=1)
DivisionButton = tkinter.Button(root, text = "/",   width = 5, command = DivisionFunc)
DivisionButton.grid(column=3, row=1)
SevenButton = tkinter.Button(root, text = "7",   width = 5, command = SevenFunc)
SevenButton.grid(column=0, row=2)
EightButton = tkinter.Button(root, text = "8",   width = 5, command = EightFunc)
EightButton.grid(column=1, row=2)
NineButton = tkinter.Button(root, text = "9",   width = 5, command = NineFunc)
NineButton.grid(column=2, row=2)
MultiplicationButton = tkinter.Button(root, text = "*",  width = 5,  command = MultiplicationFunc)
MultiplicationButton.grid(column=3, row=2)
FourButton = tkinter.Button(root, text = "4",   width = 5, command = FourFunc)
FourButton.grid(column=0, row=3)
FiveButton = tkinter.Button(root, text = "5",   width = 5, command = FiveFunc)
FiveButton.grid(column=1, row=3)
SixButton = tkinter.Button(root, text = "6",   width = 5, command = SixFunc)
SixButton.grid(column=2, row=3)
MinusButton = tkinter.Button(root, text = "-",   width = 5, command = SubtractionFunc)
MinusButton.grid(column=3, row=3)
OneButton = tkinter.Button(root, text = "1",   width = 5, command = OneFunc)
OneButton.grid(column=0, row=4)
TwoButton = tkinter.Button(root, text = "2",   width = 5, command = TwoFunc)
TwoButton.grid(column=1, row=4)
ThreeButton = tkinter.Button(root, text = "3",   width = 5, command = ThreeFunc)
ThreeButton.grid(column=2, row=4)
AdditionButton = tkinter.Button(root, text = "+",   width = 5, command = AdditionFunc)
AdditionButton.grid(column=3, row=4)
ZeroButton = tkinter.Button(root, text = "0",   width = 5, command = ZeroFunc)
ZeroButton.grid(column=0, row=5)
DecimalButton = tkinter.Button(root, text = ".",   width = 5, command = DecimalFunc)
DecimalButton.grid(column=1, row=5)
EqualButton = tkinter.Button(root, text = "=",   width = 5, command = Answer)
EqualButton.grid(column=2, row=5)
RandomButton = tkinter.Button(root, text = ":)",    width = 5, command = Trolling)
RandomButton.grid(column=3, row=5)


Display()
# root.after(100, Display) # used more often than Display()
root.mainloop()

not sure its the right way to build a Tkinter app.

See here for reason your code wasnt working well:

Why is Tkinter widget stored as None? (AttributeError: 'NoneType' object ...)(TypeError: 'NoneType' object ...)

Why do my Tkinter widgets get stored as None?

https://stackoverflow.com/questions/1101750/tkinter-attributeerror-nonetype-object-has-no-attribute-attribute-name

Quote:

The grid, pack, and place methods of every Tkinter widget operate in-place and always return None. This means that you cannot call them on the same line as you create a widget. Instead, they should be called on the line below:

tried to make a shorter version of your code, still doent work

when you eval a string starting with 0 i.e. 03 +3 and

the +- doesnt work well too.

import tkinter as tk


class App:

    def __init__(self, master):
        
        self.master = master
    
        self.keyz = ['AC', '+-','%','/','7','8','9','*','4','5','6','-','1','2','3','+','0','.','=',':)']
        
        self.master.geometry("270x210+600+250")
        self.master.configure(background="black")
        
        self.computation = tk.StringVar()
        
        self.computation.set("")
        
        self.computation.trace('w', self.callback)
     
        self.VarDisplay = tk.Label(self.master, text=self.computation.get(),
                                              height = 3, width = 20, bg = 'black', fg ='White')
        self.mbox = tk.messagebox
        
        self.draw()
        
        
    def callback(self, *args):
        
        # print('args : ', [*args])
        self.VarDisplay.config(text = self.computation.get())

    def draw(self):

        self.VarDisplay.grid(column=0,row=0,columnspan=3)
        
        col, row = 0 , 1
        for i in self.keyz:
            
            print(i, type(i), str(i))

            i = tk.Button(self.master, text = str(i), width = 5,  command = lambda i=i : self.comm(str(i)))
            
            i.grid(column = col , row = row)      
            
            print(i, type(i), str(i))
            
            
            if col >= 3:
                col = 0
                row += 1
                
            else: 
                col +=1
                
    def comm(self, string: str):
        
        if string == ':)':
            
            self.mbox.showinfo("Greetings", "Hello :)")
            
        elif string == 'AC':
            self.computation.set("")
            
        elif string == '=':
            
            self.mbox.showinfo("Answer", eval(self.computation.get()))
            self.computation.set("")
            
        elif string == '+-':
            
            
            if self.computation.get()[0] == '-':
                
                self.computation.set(self.computation.get()[1:])
            
            else:
                
                self.computation.set('-'+self.computation.get())
                
        
        else:
            self.computation.set(self.computation.get()+string)
        

if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    root.mainloop()
pippo1980
  • 2,181
  • 3
  • 14
  • 30