Python str AttributeError:';str';对象没有属性';设置';(更新标签)

Python str AttributeError:';str';对象没有属性';设置';(更新标签),python,tkinter,Python,Tkinter,这是一个简单的数学游戏。感兴趣的函数是checkAnswer()。我正在尝试更新label1,以便使用新的str更新标签,而不是连续打印多个标签 错误: AttributeError:“str”对象没有属性“set” 您得到的是AttributeError,因为您最初将字符串“绑定到全局名称labeltext,而Python字符串没有.set方法。(这没有意义,因为Python字符串是不可变的)。您最终将TkinterStringVar绑定到labeltext,并且StringVars确实有一个

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

错误:

AttributeError:“str”对象没有属性“set”


您得到的是
AttributeError
,因为您最初将字符串
绑定到全局名称
labeltext
,而Python字符串没有
.set
方法。(这没有意义,因为Python字符串是不可变的)。您最终将Tkinter
StringVar
绑定到
labeltext
,并且
StringVar
s确实有一个
.set
方法,但是您的代码在尝试调用普通Python字符串上的
.set
后会这样做

您命名的
userAnswer
IntVar
也会出现类似问题。这还有一个问题:它的名称与您的一个函数冲突。你不能那样做

这是代码的修复版本,还有一些其他的小改动。无需对那些
StringVar
s或
IntVar
使用
global
指令,因为您只需调用这些对象的方法。如果需要对全局对象执行赋值,则只需
global
,仅访问全局对象的现有值或调用其方法之一不需要
global
指令

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()

但是,该代码仍然存在一些问题。它只能问一个问题。每次你点击“提交”按钮时,它都会添加一个新的
标签
小部件,我想这不是你真正想要的

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

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

这个版本提出了多个问题。它没有“提交”按钮,而是在用户点击主键盘或数字键盘上的回车键时自动提交问题

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()
将tkinter作为tk导入
从随机导入randint
课堂问答(对象):
定义初始化(自):
root=tk.tk()
#问题
self.question_var=tk.StringVar()
Label(root,textvariable=self.question\u var).pack()
#答案
self.user\u answer\u var=tk.StringVar()
entry=tk.entry(root,textvariable=self.user\u answer\u var)
entry.pack()
#当用户点击回车键时检查答案,
#在主键盘或数字键盘上
entry.bind(“,self.check\u-response)
entry.bind(“,self.check\u-response)
self.true\u答案=无
#反应
self.response_var=tk.StringVar()
self.score=0
Label(root,textvariable=self.response\u var).pack()
#问第一个问题
self.ask_question()
root.mainloop()
def提问(自我):
num1=randint(1,10)
num2=randint(1,10)
self.question_var.set(“什么是{}+{}?”.format(num1,num2))
self.true\u答案=num1+num2
#打印(自我真实回答)#测试目的
def检查_答案(自身、事件):
user\u answer=self.user\u answer\u var.get()
#打印(用户回答)#测试目的
如果int(用户回答)=self.true\u回答:
text=“干得好”
self.score+=1
其他:
text=“哦,不”
self.response_var.set({}Score={}.format(text,self.Score))
#清除旧答案,然后问下一个问题
self.user\u answer\u var.set(“”)
self.ask_question()
测验()
请注意
import tkinter as tk
语句。使用此表单比tkinter import*
中的
要好得多,因为“星型”导入会将130个名称转储到您的命名空间中,这很混乱,并且可能导致名称冲突,特别是如果您与其他模块进行星型导入。
import tkinter as tk
表单要求您多键入一些内容,但它也使代码更易于阅读,因为很明显哪些名称来自tkinter

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


可以进行各种进一步的增强。特别是,此代码不能很好地处理无效整数的用户输入。

您得到的是
AttributeError
,因为您最初将字符串
绑定到全局名称
labeltext
,而Python字符串没有
.set
方法。(这没有意义,因为Python字符串是不可变的)。您最终将Tkinter
StringVar
绑定到
labeltext
,并且
StringVar
s确实有一个
.set
方法,但是您的代码在尝试调用普通Python字符串上的
.set
后会这样做

您命名的
userAnswer
IntVar
也会出现类似问题。这还有一个问题:它的名称与您的一个函数冲突。你不能那样做

这是代码的修复版本,还有一些其他的小改动。无需对那些
StringVar
s或
IntVar
使用
global
指令,因为您只需调用这些对象的方法。如果需要对全局对象执行赋值,则只需
global
,仅访问全局对象的现有值或调用其方法之一不需要
global
指令

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()

但是,该代码仍然存在一些问题。它只能问一个问题。每次