Tkinter 计算器无法更新标签
Tkinter calculator fails to update label
我尝试使用 tkinter 制作一个简单的整数符号计算器。它有一个 class 具有两种不同的功能。第二个功能应该在用户按下 "Enter" 按钮时启动。当我 运行 代码时, window 会按预期出现。但是当我输入并点击 "Enter" 时,第二个函数无法 运行 并且不会更新标签。我希望它更新为 "This number is positive."、"This number is 0." 或 "This number is negative." 而不是它保持空白。
我怀疑它是否相关,但我在 PyCharm Community Edition 5.0.4 中制作了这个程序,并且我使用的是 Python 3.5(32 位)。
import tkinter
class IntegerSign:
def __init__(self):
self.window = tkinter.Tk()
self.window.title("Integer Sign Calculator")
self.window.geometry("300x150")
self.number_frame = tkinter.Frame(self.window)
self.solution_frame = tkinter.Frame(self.window)
self.button_frame = tkinter.Frame(self.window)
self.number_label = tkinter.Label(self.number_frame, text="Enter an integer:")
self.number_entry = tkinter.Entry(self.number_frame, width=10)
self.number_label.pack(side='left')
self.number_entry.pack(side='left')
self.statement = tkinter.StringVar()
self.solution_label = tkinter.Label(self.solution_frame, textvariable=self.statement)
self.statement = tkinter.Label(self.solution_frame, textvariable=self.statement)
self.solution_label.pack(side='left')
self.calc_button = tkinter.Button(self.button_frame, text='Enter', command=self.calc_answer)
self.quit_button = tkinter.Button(self.button_frame, text='Quit', command=self.window.destroy)
self.calc_button.pack(side='left')
self.quit_button.pack(side='left')
self.number_frame.pack()
self.solution_frame.pack()
self.button_frame.pack()
tkinter.mainloop()
def calc_answer(self):
self.number = int(self.number_entry.get())
self.statement = tkinter.StringVar()
if self.number > 0:
self.statement = "This number is positive."
elif self.number == 0:
self.statement = "This number is 0."
else:
self.statement = "This number is negative."
IntegerSign()
要设置 StringVar 的值,您需要使用 set
方法。
现在您所做的只是重新分配变量。您还可以通过在首次初始化时给它一个值来设置 stringvar 的(默认)值。例如- var = tk.StringVar(value="some value")
编辑:没看到您还将 self.statement 设置为标签小部件...如果您一直使用此答案底部的方法并忽略(可选) 完全是 stringvar 的。但是,当您这样做时,您可以将其视为便签。你贴了一张写着 "this variable holds this value" 的便利贴,然后你重新分配了变量,把另一张便条放在前一张写着 "it now holds this value" 的便条上作为一个非常松散的视觉类比。
>>> import tkinter as tk
>>> root = tk.Tk()
>>> statement = tk.StringVar()
>>> type(statement)
>>> <class 'tkinter.StringVar'>
>>> statement = "This number is positive"
>>> type(statement)
>>> <class 'str'>
>>> statement = tk.StringVar()
>>> statement.set("This number is positive")
>>> statement.get()
'This number is positive'
>>> type(statement)
>>> <class 'tkinter.StringVar'>
或者,您可以通过 label_widget['text'] = 'new_text'
更改标签文本
第一个问题:在您的构造函数中,您将名为 self.statement 的变量初始化为 StringVar,然后再次初始化为 Label。在第二次初始化之后,您将无法访问第一个对象。您需要使用两个不同的名称。
第二个问题:在您的事件处理程序 calc_answer
中,您创建了一个名为 self.statement
的新对象,但您需要 set
将一个新值转换为旧值(参见 docs)。这是按预期运行的程序的修改版本:
import tkinter
class IntegerSign:
def __init__(self):
self.window = tkinter.Tk()
self.window.title("Integer Sign Calculator")
self.window.geometry("300x150")
self.number_frame = tkinter.Frame(self.window)
self.solution_frame = tkinter.Frame(self.window)
self.button_frame = tkinter.Frame(self.window)
self.number_label = tkinter.Label(self.number_frame, text="Enter an integer:")
self.number_entry = tkinter.Entry(self.number_frame, width=10)
self.number_label.pack(side='left')
self.number_entry.pack(side='left')
self.solution_string = tkinter.StringVar()
self.solution_label = tkinter.Label(self.solution_frame, textvariable=self.solution_string)
self.statement = tkinter.Label(self.solution_frame, textvariable=self.solution_string)
self.solution_label.pack(side='left')
self.calc_button = tkinter.Button(self.button_frame, text='Enter', command=self.calc_answer)
self.quit_button = tkinter.Button(self.button_frame, text='Quit', command=self.window.destroy)
self.calc_button.pack(side='left')
self.quit_button.pack(side='left')
self.number_frame.pack()
self.solution_frame.pack()
self.button_frame.pack()
tkinter.mainloop()
def calc_answer(self):
self.number = int(self.number_entry.get())
if self.number > 0:
self.solution_string.set("This number is positive.")
elif self.number == 0:
self.solution_string.set("This number is 0.")
else:
self.solution_string.set("This number is negative.")
IntegerSign()
此代码有效,但包含我建议您修复的错误做法。函数 tkinter.mainloop()
本质上是一个无限循环,您已将其放在构造函数中。因此,构造函数不会 return 构造函数通常应该采用的方式。将该语句从 __init__
函数中取出并放在末尾,在调用 IntegerSign
之后,并使其成为将来要使用的模式。
我尝试使用 tkinter 制作一个简单的整数符号计算器。它有一个 class 具有两种不同的功能。第二个功能应该在用户按下 "Enter" 按钮时启动。当我 运行 代码时, window 会按预期出现。但是当我输入并点击 "Enter" 时,第二个函数无法 运行 并且不会更新标签。我希望它更新为 "This number is positive."、"This number is 0." 或 "This number is negative." 而不是它保持空白。
我怀疑它是否相关,但我在 PyCharm Community Edition 5.0.4 中制作了这个程序,并且我使用的是 Python 3.5(32 位)。
import tkinter
class IntegerSign:
def __init__(self):
self.window = tkinter.Tk()
self.window.title("Integer Sign Calculator")
self.window.geometry("300x150")
self.number_frame = tkinter.Frame(self.window)
self.solution_frame = tkinter.Frame(self.window)
self.button_frame = tkinter.Frame(self.window)
self.number_label = tkinter.Label(self.number_frame, text="Enter an integer:")
self.number_entry = tkinter.Entry(self.number_frame, width=10)
self.number_label.pack(side='left')
self.number_entry.pack(side='left')
self.statement = tkinter.StringVar()
self.solution_label = tkinter.Label(self.solution_frame, textvariable=self.statement)
self.statement = tkinter.Label(self.solution_frame, textvariable=self.statement)
self.solution_label.pack(side='left')
self.calc_button = tkinter.Button(self.button_frame, text='Enter', command=self.calc_answer)
self.quit_button = tkinter.Button(self.button_frame, text='Quit', command=self.window.destroy)
self.calc_button.pack(side='left')
self.quit_button.pack(side='left')
self.number_frame.pack()
self.solution_frame.pack()
self.button_frame.pack()
tkinter.mainloop()
def calc_answer(self):
self.number = int(self.number_entry.get())
self.statement = tkinter.StringVar()
if self.number > 0:
self.statement = "This number is positive."
elif self.number == 0:
self.statement = "This number is 0."
else:
self.statement = "This number is negative."
IntegerSign()
要设置 StringVar 的值,您需要使用 set
方法。
现在您所做的只是重新分配变量。您还可以通过在首次初始化时给它一个值来设置 stringvar 的(默认)值。例如- var = tk.StringVar(value="some value")
编辑:没看到您还将 self.statement 设置为标签小部件...如果您一直使用此答案底部的方法并忽略(可选) 完全是 stringvar 的。但是,当您这样做时,您可以将其视为便签。你贴了一张写着 "this variable holds this value" 的便利贴,然后你重新分配了变量,把另一张便条放在前一张写着 "it now holds this value" 的便条上作为一个非常松散的视觉类比。
>>> import tkinter as tk
>>> root = tk.Tk()
>>> statement = tk.StringVar()
>>> type(statement)
>>> <class 'tkinter.StringVar'>
>>> statement = "This number is positive"
>>> type(statement)
>>> <class 'str'>
>>> statement = tk.StringVar()
>>> statement.set("This number is positive")
>>> statement.get()
'This number is positive'
>>> type(statement)
>>> <class 'tkinter.StringVar'>
或者,您可以通过 label_widget['text'] = 'new_text'
第一个问题:在您的构造函数中,您将名为 self.statement 的变量初始化为 StringVar,然后再次初始化为 Label。在第二次初始化之后,您将无法访问第一个对象。您需要使用两个不同的名称。
第二个问题:在您的事件处理程序 calc_answer
中,您创建了一个名为 self.statement
的新对象,但您需要 set
将一个新值转换为旧值(参见 docs)。这是按预期运行的程序的修改版本:
import tkinter
class IntegerSign:
def __init__(self):
self.window = tkinter.Tk()
self.window.title("Integer Sign Calculator")
self.window.geometry("300x150")
self.number_frame = tkinter.Frame(self.window)
self.solution_frame = tkinter.Frame(self.window)
self.button_frame = tkinter.Frame(self.window)
self.number_label = tkinter.Label(self.number_frame, text="Enter an integer:")
self.number_entry = tkinter.Entry(self.number_frame, width=10)
self.number_label.pack(side='left')
self.number_entry.pack(side='left')
self.solution_string = tkinter.StringVar()
self.solution_label = tkinter.Label(self.solution_frame, textvariable=self.solution_string)
self.statement = tkinter.Label(self.solution_frame, textvariable=self.solution_string)
self.solution_label.pack(side='left')
self.calc_button = tkinter.Button(self.button_frame, text='Enter', command=self.calc_answer)
self.quit_button = tkinter.Button(self.button_frame, text='Quit', command=self.window.destroy)
self.calc_button.pack(side='left')
self.quit_button.pack(side='left')
self.number_frame.pack()
self.solution_frame.pack()
self.button_frame.pack()
tkinter.mainloop()
def calc_answer(self):
self.number = int(self.number_entry.get())
if self.number > 0:
self.solution_string.set("This number is positive.")
elif self.number == 0:
self.solution_string.set("This number is 0.")
else:
self.solution_string.set("This number is negative.")
IntegerSign()
此代码有效,但包含我建议您修复的错误做法。函数 tkinter.mainloop()
本质上是一个无限循环,您已将其放在构造函数中。因此,构造函数不会 return 构造函数通常应该采用的方式。将该语句从 __init__
函数中取出并放在末尾,在调用 IntegerSign
之后,并使其成为将来要使用的模式。