str AttributeError:'str'对象没有属性'set'(更新标签)

时间:2017-04-03 11:57:33

标签: python tkinter

这是一款简单的数学游戏。感兴趣的功能是checkAnswer()。我正在尝试更新label1,以便标签使用新的str更新,而不是连续打印多个标签。

错误:

  

AttributeError:'str'对象没有属性'set'

from tkinter import *

from random import randint

num1 = 0
num2 = 0
userAnswer = 0
answer = 0
score = 0
labeltext = ""

#PROGRAM FUNCTIONS
def question():
    global num1, num2
    global answer
    num1 = randint(1,10)
    num2 = randint(1,10)
    question = Label(text = "What is " + str(num1)+ " + " + str(num2) + "?").pack()
    answer = num1+num2
    print(answer) #testing purposes

def userAnswer():
    global userAnswer
    userAnswer = IntVar()
    entry = Entry(root, textvariable = userAnswer).pack()
    submit = Button(root, text = "submit", command = checkAnswer).pack()

def checkAnswer():
    global labeltext
    print(userAnswer.get())
    if userAnswer == answer:
        labeltext.set("good job")
        score += 1
    elif userAnswer != answer:
        labeltext.set("oh no")
    labeltext = StringVar()
    label1 = Label(root, textvariable = labeltext).pack()

#INTERFACE CODE
root = Tk()

question()
userAnswer()
root.mainloop()

1 个答案:

答案 0 :(得分:5)

您得到的是AttributeError,因为您最初将字符串""绑定到全局名称labeltext,而Python字符串没有.set方法。 (这不会有意义,因为Python字符串是不可变的)。您最终将Tkinter StringVar绑定到labeltext,而StringVar .set方法,但您的代码在此之后执行此操作&#39 ; s已经尝试在普通Python字符串上调用.set

您命名为IntVar的{​​{1}}也会出现类似问题。这还有一个问题:它的名字与你的一个功能发生冲突。你做不到!

这是您修改过的代码版本,还有一些其他的小改动。由于您只是调用这些对象的方法,因此无需在userAnswerglobal上使用StringVar指令。如果需要对全局对象执行赋值,只需访问全局的现有值或调用其中一个方法,则只需要IntVar

global

但是,该代码仍有几个问题。它只能问一个问题。每次你点击"提交"按钮它会添加一个新的global小部件,我认为你真的不想这样做。

使用全局变量不是一个好主意。它们打破了模块化,这使得代码更难理解,更难以修改和重用。

这是程序的增强版本,它将所有内容放入一个类中,因此我们可以使用实例属性而不是全局变量。

此版本提出了多个问题。它没有"提交"按钮,而当用户点击主键盘或数字键盘上的Enter / Return键时,问题会自动提交。

from tkinter import *
from random import randint

#PROGRAM FUNCTIONS
def question():
    global true_answer
    num1 = randint(1,10)
    num2 = randint(1,10)
    Label(text="What is " + str(num1)+ " + " + str(num2) + "?").pack()
    true_answer = num1 + num2
    print(true_answer) #testing purposes

def answer():
    Entry(root, textvariable=userAnswer).pack()
    Button(root, text="submit", command=checkAnswer).pack()

def checkAnswer():
    global score
    print(userAnswer.get()) #testing purposes
    if userAnswer.get() == true_answer:
        labeltext.set("good job")
        score += 1
    else:
        labeltext.set("oh no")
    label1 = Label(root, textvariable=labeltext).pack()

#INTERFACE CODE
root = Tk()

true_answer = 0
score = 0

userAnswer = IntVar()
labeltext = StringVar()

question()
answer()
root.mainloop()

请注意Label声明。使用此表单比使用import tkinter as tk from random import randint class Quiz(object): def __init__(self): root = tk.Tk() # The question self.question_var = tk.StringVar() tk.Label(root, textvariable=self.question_var).pack() # The answer self.user_answer_var = tk.StringVar() entry = tk.Entry(root, textvariable=self.user_answer_var) entry.pack() # Check the answer when the user hits the Enter key, # either on the main keyboard or the numeric KeyPad entry.bind("<Return>", self.check_answer) entry.bind("<KP_Enter>", self.check_answer) self.true_answer = None # The response self.response_var = tk.StringVar() self.score = 0 tk.Label(root, textvariable=self.response_var).pack() # Ask the first question self.ask_question() root.mainloop() def ask_question(self): num1 = randint(1, 10) num2 = randint(1, 10) self.question_var.set("What is {} + {}?".format(num1, num2)) self.true_answer = num1 + num2 #print(self.true_answer) #testing purposes def check_answer(self, event): user_answer = self.user_answer_var.get() #print(user_answer) #testing purposes if int(user_answer) == self.true_answer: text = "Good job" self.score += 1 else: text = "Oh no" self.response_var.set('{} Score={}'.format(text, self.score)) # Clear the old answer and ask the next question self.user_answer_var.set('') self.ask_question() Quiz() 更好 更好 import将130个名称转储到您的命名空间中,这很糟糕,并且可能导致名称冲突,尤其是如果您使用其他模块进行星型导入。 import tkinter as tk表单要求您进行更多的输入,但它也使代码更容易阅读,因为很明显哪些名称来自Tkinter。

我还更改了变量和类方法(函数)的名称,因此它们符合Python PEP-0008样式指南。

可以进行各种进一步的改进。特别是,此代码不能优雅地处理不是有效整数的用户输入。