【问题标题】:Tkinter calculator fails to update labelTkinter 计算器无法更新标签
【发布时间】:2016-12-03 14:15:53
【问题描述】:

我尝试使用 tkinter 制作一个简单的整数符号计算器。它有一个具有两个不同功能的类。第二个功能应该在用户按下“Enter”按钮时启动。当我运行代码时,窗口会按预期出现。但是当我键入并点击“Enter”时,第二个函数无法运行并且不会更新标签。我希望它更新为“这个数字是正数。”、“这个数字是 0。”或“这个数字是负数”。相反,它保持空白。

我怀疑它是否相关,但我在 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()

【问题讨论】:

    标签: python user-interface tkinter label calculator


    【解决方案1】:

    第一个问题:在您的构造函数中,您将名为 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() 函数本质上是一个无限循环,您已将它放在构造函数中。因此构造函数不会返回构造函数通常应该的方式。将该语句从__init__ 函数中取出并放在最后,在对IntegerSign 的调用之后,并使其成为将来使用的模式。

    【讨论】:

      【解决方案2】:

      要设置 StringVar 的值,您需要使用 set 方法。 现在你所做的就是重新分配变量。您还可以通过在第一次初始化时给它一个值来设置 stringvar 的(默认)值。例如- var = tk.StringVar(value="some value")

      编辑:没有看到您还将 self.statement 设置为标签小部件...如果您在此答案的底部一直使用该方法,并且完全忽略(可选)stringvar,这将起作用。但是,当您这样做时,您可以将其视为便签。你贴了一张便签,上面写着“这个变量保存这个值”,然后你重新分配了这个变量,在之前的那个上面写了另一个便签,上面写着“它现在保存这个值”作为一个非常松散的视觉类比。

      >>> 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' 更改标签文本

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-04-12
        • 1970-01-01
        • 2014-08-01
        • 2017-11-18
        • 2015-12-08
        • 2015-05-24
        相关资源
        最近更新 更多