简体   繁体   English

从 tkinter python 3.8.2 中的函数更新标签的问题

[英]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.所以我一直在自学一些 tkinter 来开始构建一些真正的应用程序,而我的第一个项目是为 Courera 非常著名的 Rock-Paper-Scissors-Lizard-Spock 游戏构建一个界面。

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'

That's because playWin is a tkinter.Intvar object,you need to change the function gameplay to:那是因为playWintkinter.Intvar object,你需要将 function gameplay更改为:

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="")

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.计算机播放label 字段不刷新,因为您从未调用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.这个 function 应该在玩家每次按下左键时被调用,但是这个 function 在gameplay方法中没有被使用。 Simply call this function to refresh the computer guess and set the value of a label.只需调用此 function 即可刷新计算机猜测并设置 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 += .gameplay function 中, compWinplayerWin对象不是ints ,而是tkinter.Intvar所以你应该set它们的变量而不是使用++= This is the reason for this error.这就是此错误的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM