tkinter输入组件中的StringVar()错误

-1 投票
1 回答
701 浏览
提问于 2025-04-18 04:17

我有一段代码,已经回过头来修复了一些问题。这是一个数学游戏,它会生成一个问题;询问这个问题;检查答案并加分。我还是个初学者,遇到了一些问题,发现很多人也有类似的困扰。虽然我还是搞不明白。

我有一个输入框,想从里面获取信息,但总是出错。

有人能告诉我哪里出错了吗?应该把 v = StringVar() 放在哪里?为什么这样做是错的?我想了解一下原因。

这个游戏还在开发中,所以请忽略其他错误。

代码如下:

import tkinter as tk
import random as r

score = 0
a = 0
b = 0
answer = 0

def question_gen():
    global a
    global b
    global answer
    a = r.randint(0,100)
    b = r.randint(0,100)
    answer = (a+b)

def question_checker():
    global score
    user_input = v.get
    if user_input == answer:
        score += 1
    else:
        score += 0

class Demo1:
    def __init__(self, master):
        self.master = master
        self.frame = tk.Frame(self.master).pack()
        self.label = tk.Label(self.frame, text = 'Welcome To My Wonderful Math Game\n\nHow To Play\n\nWhen you pick a difficulty a new window will pop up\nYou have to answer to the question\nBefore the timer runs out\n\nGood Luck!').pack()
        self.button1 = tk.Button(self.frame, text = 'Easy', width = 25, command = self.new_window).pack()
        self.button2 = tk.Button(self.frame, text = 'Hard', width = 25, command = self.new_window).pack()

    def new_window(self):
        self.newWindow = tk.Toplevel(self.master)
        self.app = Demo2(self.newWindow)

class Demo2:
    def __init__(self, master):
        self.master = master
        self.frame = tk.Frame(self.master).pack()
        self.label = tk.Label(self.master, text = '{0} + {1} ='.format(a,b)).pack()
        self.entry = tk.Entry(self.master, textvariable=v).pack()
        self.quitButton = tk.Button(self.master, text = 'Quit', width = 25, command = self.close_windows).pack()
    def close_windows(self):
        self.master.destroy()

def main(): 
    root = tk.Tk()
    app = Demo1(root)
    root.mainloop()

if __name__ == '__main__':
    main()

1 个回答

1

在哪里放 v = StringVar() 呢?

你需要把 v 存放在一个可以随时访问的地方。

  1. 在创建输入控件的时候
  2. 在检查问题的时候

可能的解决方案包括:

  • 在更高的范围内声明 v,这样你就可以从任何地方访问它。
  • 把 v 声明为 demo2 的一个属性,然后把它作为参数传给问题检查器(我觉得这个更好,这样 Demo2 的责任就是显示和检查问题的答案)。
  • 把 v 声明为 demo1 的一个属性,然后把它作为参数传给 Demo2 的构造函数和问题检查器。

顺便说一下,如果你不使用 StringVar 的追踪功能(在每次变量变化时反应),你可以不使用 StringVar。

class Demo2:
    def __init__(self, master):
        #[...]
        self.entry = tk.Entry(self.master)
        self.entry.pack()
        #[...]
    def close_windows(self):
        #access entry content through
        self.entry.get()

另外要注意,在 tkinter 中一行创建控件和设置布局会错误地初始化你的控件变量。它们总是会包含 None,因为 pack(和 grid)总是返回 None。

撰写回答