issues with updating labels from functions in tkinter python 3.8.2

So I've been teaching myself some tkinter to start building some real apps, and my first project is to build an interface for the Courera's all-too-famous Rock-Paper-Scissors-Lizard-Spock game.

Up to now I have all the buttons working fine enough (even though I feel like they are not updating anything if i repeatedly click on the same button without changing choice, as the result of the match never changes) and the result panel also works. that's what's makng me crazy, as far as I can see, the win counters and the computer choice panel follow the same logic and for some reason are not updating when I click a button. any hints?

Thanks already for the patience, and code as follows

import tkinter as tk
import random
from functools import partial

#setting the window early as I had issues and bugs when called after defining functions
window = tk.Tk()
window.geometry('350x200')

#global variables
result= tk.StringVar()
result.set("")
comp = tk.IntVar()
guess = tk.StringVar()
guess.set("")
playerWin = tk.IntVar()
playerWin.set(0)
compWin = tk.IntVar()
compWin.set(0)

#function that handles the computer's play in each game
def compPlay():
    global guess, comp
    comp.set(random.randrange(0,5))
    if comp.get()== 0:
        guess.set("Rock")
    elif comp.get()== 1:
        guess.set("Spock")
    elif comp.get() == 2:
        guess.set("Paper")
    elif comp.get() == 3:
        guess.set("Lizard")
    elif comp.get() == 4:
        guess.set("Scissors")

#function to play human vs computer choices and see who wins
def gameplay(playerNum,compNum):
    global result, comp, playerWin, compWin
    if playerNum == comp.get():
        result.set("It's a tie!")
    elif (playerNum - comp.get()) % 5 <= 2:
        result.set("Player wins!")
        playerWin = playerWin.get() + 1
    elif (playerNum - comp.get()) % 5 >= 3:
        result.set("Computer wins!")
        compWin += compWin.get() + 1
    else:
        result.set(text = "")
        
# game title
lblGame= tk.Label(text="Rock, Scissors, Paper, Lizard, Spock").pack()

#frame with the buttons for player choices
playerFrame = tk.Frame(window)
btRock = tk.Button(playerFrame, text = "Rock", width = 15, command = partial(gameplay, 0,compPlay)).pack()
btScissors = tk.Button(playerFrame, text = "Scissors", width = 15, command = partial(gameplay, 1,compPlay)).pack()
btPaper = tk.Button(playerFrame, text = "Paper", width = 15, command = partial(gameplay, 2,compPlay)).pack()
btLizard = tk.Button(playerFrame, text = "Lizard", width = 15, command = partial(gameplay, 3,compPlay)).pack()
btSpock = tk.Button(playerFrame, text = "Spock", width = 15, command = partial(gameplay, 4,compPlay)).pack()
playerFrame.pack(side = tk.LEFT)

#frame with info about the game, as in what the computer chose and the result of the play
compFrame = tk.Frame(window)
lbComp = tk.Label(compFrame, text = "Computer plays:").pack()
lbGuess = tk.Label(compFrame, textvariable = guess, relief = tk.GROOVE, borderwidth = 5, width = 15).pack()
lbRes = tk.Label(compFrame, text = "and the result of the game is").pack()
lbMatch = tk.Label(compFrame, textvariable = result, relief = tk.GROOVE, borderwidth = 5, width = 15).pack()

#mini frames for score keeping
playerFrame = tk.Frame(compFrame, relief = tk.GROOVE, borderwidth = 3)
playerSide = tk.Label(playerFrame, text = "Player points:").pack()
playerScore = tk.Label(playerFrame, textvariable = str(playerWin)).pack()
playerFrame.pack(side = tk.LEFT)

compScoreFrame = tk.Frame(compFrame, relief = tk.GROOVE, borderwidth = 3)
compSide = tk.Label(compScoreFrame, text = "Computer points:").pack()
compScore = tk.Label(compScoreFrame, textvariable = str(compWin)).pack()
compScoreFrame.pack(side = tk.RIGHT)

compFrame.pack(side = tk.RIGHT)

window.mainloop()

I get this error on the console whenever the game should give points to either player:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.8/tkinter/__init__.py", line 1883, in __call__
    return self.func(*args)
  File "~/Interactive Python/teste tkinter3.py", line 54, in gameplay
    playerWin = playerWin.get() + 1
AttributeError: 'int' object has no attribute 'get'

Upvotes: 0

Views: 111

Answers (2)

Benjamin
Benjamin

Reputation: 3448

There are several problems that are not working properly here:

  1. The Computer plays label field is not refreshing, because you never call the compPlay() function. This function should be called each time the player presses the left-hand button, but this function is unused in the gameplay method. Simply call this function to refresh the computer guess and set the value of a label.
  2. In the gameplay function the compWin and playerWin objects are not ints but tkinter.Intvar so you should set their variables instead of using + and +=. This is the reason for this error.

Upvotes: 1

Kevin Mayo
Kevin Mayo

Reputation: 1159

That's because playWin is a tkinter.Intvar object,you need to change the function gameplay to:

def gameplay(playerNum, compNum):
    global result, comp, playerWin, compWin
    if playerNum == comp.get():
        result.set("It's a tie!")
    elif (playerNum - comp.get()) % 5 <= 2:
        result.set("Player wins!")
        playerWin.set(playerWin.get() + 1)
    elif (playerNum - comp.get()) % 5 >= 3:
        result.set("Computer wins!")
        compWin.set(compWin.get() + 1)
    else:
        result.set(text="")

Upvotes: 2

Related Questions