Home > database >  Updating IntVar() Value and then Updating A Label That Uses The IntVar()
Updating IntVar() Value and then Updating A Label That Uses The IntVar()

Time:06-22

I have been trying to develop a simple checkbox scoring program.

In ideal conditions, the following code would, after confirming a robot has completed an obstacle course correctly, offer an option that should increase the score by 10 points. The second option is displayed, but the label (known as ScoreDisplay) does not update when it is selected, remaining as 0.

What is the solution be for the issue of the ScoreDisplay label not updating on-screen?

from tkinter import *

window = Tk()
window.geometry('600x600')
window.title("Vex Scoring")
Score = IntVar()

ObstacleBumper = IntVar()
ObstacleDistance = IntVar()
PlateuFace = IntVar()
PlateuPick = IntVar()
PlateuLED = IntVar()
ColorWheelCorrect = IntVar()
FlashGateCorrect = IntVar()
PedestalLEDCorrect = IntVar()
PedestalLEDIncorrect = IntVar()
PedestalCubeCorrect = IntVar()
PedestalCubeIncorrect = IntVar()
CorralCWCorrect = IntVar()
CorralCWIncorrect = IntVar()
BotHung = IntVar()
NoBalls = IntVar()

ScoreValues = {"ObstacleBumper":10, "ObstacleDistance":15, "PlateuFace":5, "PlateuPick":5, "PlateuLED":5, "ColorWheelCorrect":10, "FlashGateCorrect":10, "PedestalLEDCorrect":15, "PedestalLEDIncorrect":10, "PedestalCubeCorrect":10, "PedestalCubeIncorrect":5, "CorralCWCorrect":5, "CorralCWIncorrect":2, "BotHung":10, "NoBalls":10}

BotActions = {"ObstacleBumper":ObstacleBumper, "ObstacleDistance":ObstacleDistance, "PlateuFace":PlateuFace, "PlateuPick":PlateuPick, "PlateuLED":PlateuLED, "ColorWheelCorrect":ColorWheelCorrect, "FlashGateCorrect":FlashGateCorrect, "PedestalLEDCorrect":PedestalLEDCorrect, "PedestalLEDIncorrect":PedestalLEDIncorrect, "PedestalCubeCorrect":PedestalCubeCorrect, "PedestalCubeIncorrect":PedestalCubeIncorrect, "CorralCWCorrect":CorralCWCorrect, "CorralCWIncorrect":CorralCWIncorrect, "BotHung":BotHung, "NoBalls":NoBalls}

ScoreDisplay = Label(window, text = f"{Score.get()}")
ScoreDisplay.grid(column = 0, row = 20, padx = 1, pady = 1)

def ScoreUpdate():
  global Score
  # potentially unnecessary variable
  globalscore = Score.get()
  comparescore = 0
  comparelist = []
  # following for loop checks to see which actions are confirmed to have happened, and stores their names in comparelist
  for name, action in BotActions.items():
    if action == 1:
      comparelist.append(name)
    else:
      pass
  # following for loop checks if a given key from ScoreValues matches an entry in comparelist, and then adds the value of that key to comparescore. If globalscore is less than comparescore, the main score variable (known as Score) is modified to equal comparescore.
  for key, value in ScoreValues.items():
    if key in comparelist:
      comparescore  = value
    else:
      pass
  if globalscore < comparescore:
    Score.set(comparescore)
    ScoreDisplay.config(text = f"{Score.get()}")
  else:
    pass

def ObstacleConfirmed():
  ObstacleComBumper = Checkbutton(window, variable = ObstacleBumper, onvalue = 1, offvalue = 0, command = ScoreUpdate)
  ObCoBu = Label(window, text = "The bot completed the course using its bumper switches.")
  ObstacleComBumper.grid(column = 1, row = 1, padx = 1, pady = 1)
  ObCoBu.grid(column = 2, row = 1, padx = 1, pady = 1)
ObstacleCourseConfirm = Checkbutton(window, width = 1, height = 1, command = ObstacleConfirmed)
ObCoCo = Label(window, text = "The course was completed correctly.")
ObstacleCourseConfirm.grid(column = 0, row = 0, padx = 1, pady = 1)
ObCoCo.grid(column = 1, row = 0, padx = 1, pady = 1)

window.mainloop()

CodePudding user response:

In a nutshell, instead of using:

ScoreDisplay = Label(window, text=f"{Score.get()}")

use:

ScoreDisplay = Label(window, textvariable=Score)

And remove the:

ScoreDisplay.config(text = f"{Score.get()}")

line further down because the update will now happen automatically whenever the value of Score is changed (usually by calling Score.set()).

Here's some documentation on the Label widget that explains the textvariable= option it has. There's some more on the topic of using tkinter Variables like that in Control variables: the values behind the widgets section of the same document.

Below is your code with the above changes in it along with some I made for testing purposes for testing, plus many code formatting changes I also made to make it more readable by following the PEP 8 - Style Guide for Python Code — something I strongly suggest you begin doing yourself. Anyhow, significant non-cosmetic changes are indicated via # ALL CAP COMMENTS.

import tkinter as tk
from tkinter.constants import *

window = tk.Tk()
window.geometry('600x600')
window.title("Vex Scoring")
Score = tk.IntVar()

ObstacleBumper = tk.IntVar()
ObstacleDistance = tk.IntVar()
PlateuFace = tk.IntVar()
PlateuPick = tk.IntVar()
PlateuLED = tk.IntVar()
ColorWheelCorrect = tk.IntVar()
FlashGateCorrect = tk.IntVar()
PedestalLEDCorrect = tk.IntVar()
PedestalLEDIncorrect = tk.IntVar()
PedestalCubeCorrect = tk.IntVar()
PedestalCubeIncorrect = tk.IntVar()
CorralCWCorrect = tk.IntVar()
CorralCWIncorrect = tk.IntVar()
BotHung = tk.IntVar()
NoBalls = tk.IntVar()

ScoreValues = {"ObstacleBumper": 10, "ObstacleDistance": 15, "PlateuFace": 5,
               "PlateuPick": 5, "PlateuLED": 5, "ColorWheelCorrect": 10,
               "FlashGateCorrect": 10, "PedestalLEDCorrect": 15,
               "PedestalLEDIncorrect": 10, "PedestalCubeCorrect": 10,
               "PedestalCubeIncorrect": 5, "CorralCWCorrect": 5, "CorralCWIncorrect": 2,
               "BotHung": 10, "NoBalls": 10}

BotActions = {"ObstacleBumper": ObstacleBumper, "ObstacleDistance": ObstacleDistance,
              "PlateuFace": PlateuFace, "PlateuPick": PlateuPick, "PlateuLED": PlateuLED,
              "ColorWheelCorrect": ColorWheelCorrect,
              "FlashGateCorrect": FlashGateCorrect,
              "PedestalLEDCorrect": PedestalLEDCorrect,
              "PedestalLEDIncorrect": PedestalLEDIncorrect,
              "PedestalCubeCorrect": PedestalCubeCorrect,
              "PedestalCubeIncorrect": PedestalCubeIncorrect,
              "CorralCWCorrect": CorralCWCorrect, "CorralCWIncorrect": CorralCWIncorrect,
              "BotHung": BotHung, "NoBalls": NoBalls}

#ScoreDisplay = tk.Label(window, text=f"{Score.get()}")
ScoreDisplay = tk.Label(window, textvariable=Score)
ScoreDisplay.grid(column=0, row=20, padx=1, pady=1)

def ScoreUpdate():
#    global Score  # NOT NEEDED

    # FOR TESTING PURPOSES, INCREMENT Score EVERY TIME THIS FUNCTION IS CALLED
    # SO ScoreDisplay LABEL WILL UPDATE.
    Score.set(Score.get() 1)

#    # potentially unnecessary variable
#    globalscore = Score.get()  # YOU'RE RIGHT, IT'S NOT NECESSARY
    comparescore = 0
    comparelist = []
    # following for loop checks to see which actions are confirmed to have
    # happened, and stores their names in comparelist.
    for name, action in BotActions.items():
        if action == 1:
            comparelist.append(name)
        else:
            pass
    # following for loop checks if a given key from ScoreValues matches an entry
    # in comparelist, and then adds the value of that key to comparescore. If
    # globalscore is less than comparescore, the main score variable (known as
    # Score) is modified to equal comparescore.
    for key, value in ScoreValues.items():
        if key in comparelist:
            comparescore  = value
        else:
            pass
    if Score.get() < comparescore:
        Score.set(comparescore)  # UPDATES ScoreDisplay LABEL AUTOMATICALLY.
#        ScoreDisplay.config(text = f"{Score.get()}")  # NO LONGER NECESSARY.
    else:
        pass

def ObstacleConfirmed():
    ObstacleComBumper = tk.Checkbutton(window, variable=ObstacleBumper, onvalue=1,
                                    offvalue=0, command=ScoreUpdate)
    ObCoBu = tk.Label(window,
                      text="The bot completed the course using its bumper switches.")
    ObstacleComBumper.grid(column=1, row=1, padx=1, pady=1)
    ObCoBu.grid(column=2, row=1, padx=1, pady=1)

ObstacleCourseConfirm = tk.Checkbutton(window, width=1, height=1,
                                       command=ObstacleConfirmed)
ObCoCo = tk.Label(window, text="The course was completed correctly.")
ObstacleCourseConfirm.grid(column=0, row=0, padx=1, pady=1)
ObCoCo.grid(column=1, row=0, padx=1, pady=1)

window.mainloop()

CodePudding user response:

action == 1 inside ScoreUpdate() should be action.get() == 1 because action is an IntVar.

def ScoreUpdate():
  ...
  for name, action in BotActions.items():
    if action.get() == 1:    ### used action.get() instead of action
      comparelist.append(name)
    else:
      pass
  ...
  • Related