Scott
Scott

Reputation: 132

Python Tkinter changing label text

I know that there are a lot of questions dealing with tkinter but I have looked at a bunch of them and none of them seem to help me.

import tkinter

class Calculator:

  def __init__(self):
    window = tkinter.Tk()
    window.geometry("200x300")
    window.title("Calculator")

    lbl = tkinter.Label(window, text="placeholder", bg="blue", textvariable="labelText")
    lbl.grid(row=0, column=0, columnspan=3)

    self.firstNumArray = []
    self.secondNumArray = []
    self.operation = ""
    self.currentNum = "first"

    def appendNumber(self, number):
      print("Appending Number")
      if self.currentNum == "first":
        self.firstNumArray.append(number)
        print("".join(str(x) for x in self.firstNumArray))
        lbl.config(text="".join(str(x) for x in self.firstNumArray))
        window.update()
      else:
        self.secondNumArray.append(number)

    for i in range(1,4):
      string = "Creating button at ({0},{1})".format(0,i)
      print(string)
      button = tkinter.Button(text=i, command=lambda: appendNumber(self, i))
      button.grid(row=1, column=i-1)

    for i in range(1,4):
      string = "Creating button at ({0},{1})".format(1,i)
      print(string)
      button = tkinter.Button(text=i+3, command=lambda: appendNumber(self, i+3))
      button.grid(row=2, column=i-1)

    for i in range(1,4):
      string = "Creating button at ({0},{1})".format(2,i)
      print(string)
      button = tkinter.Button(text=i+6, command=lambda: appendNumber(self, i+6))
      button.grid(row=3, column=i-1)


    div = tkinter.Button(text="/")
    mult = tkinter.Button(text="*")
    add = tkinter.Button(text="+")
    sub = tkinter.Button(text="-")

    add.grid(row=1, column=3)
    sub.grid(row=2, column=3)
    mult.grid(row=3, column=3)
    div.grid(row=4, column=3)

    button = tkinter.Button(text="0")
    button.grid(row=4, column=1)

    window.mainloop()



calc = Calculator()

When I launch the program the window opens. When I click on a button the text in the label does not change. I have tried using a StringVar as the textvariable and then calling the set() function, but that did not work either. I think it has to do with the scope of the function. I had to place the appendNumber() function inside the __init__() because for some reason self.lbl = tkinter.Label() makes nothing pop up at all.

Upvotes: 1

Views: 1693

Answers (1)

tobias_k
tobias_k

Reputation: 82949

There are a few problems with your code.

  1. labelText should, of course, be a StringVar and not a string...

    labelText = tkinter.StringVar()
    lbl = tkinter.Label(window, bg="blue", textvariable=labelText)
    lbl.grid(row=0, column=0, columnspan=3)
    
  2. Now you can use labelText.set to update the text. Also, no need for self parameter or window.update

    def appendNumber(number):
        if self.currentNum == "first":
            self.firstNumArray.append(number)
            labelText.set("".join(str(x) for x in self.firstNumArray))
        else:
            self.secondNumArray.append(number)
    
  3. You can put all the buttons in one loop using // (integer (!) division) and % (modulo) operations. Also, be aware that the variable in the lambda is evaluated when the function is called, not when it is declared, i.e. all the lambdas will use the last value of i (9 in this case) -- see e.g. here. As a remedy, use lambda n=i+1: appendNumber(n).

    for i in range(9):
        btn = tkinter.Button(text=i+1, command=lambda n=i+1: appendNumber(n))
        btn.grid(row=i//3+1, column=i%3)
    
  4. Not really a problem, but since you don't need a reference to those buttons, you can make your code a bit more compact (same for the others):

    tkinter.Button(text="/").grid(row=1, column=3)
    

Upvotes: 1

Related Questions