【问题标题】:issue with a calculator program in Tkinter with Python 3使用 Python 3 在 Tkinter 中的计算器程序出现问题
【发布时间】:2014-12-10 19:37:29
【问题描述】:

这里是代码(编辑见下文):

from tkinter import *

my_int_var = 0

def button_1_method():      #what's important is this method and the button_1 defined below
    my_int_var.set = my_int_var.get + 1
    entry_field.set = my_int_var

root = Tk()
frame_1 = Frame(root)
frame_1.pack()
frame_2 = Frame(root)
frame_2.pack()
frame_3 = Frame(root)
frame_3.pack()
frame_4=Frame(root)
frame_4.pack()

entry_field = Entry(frame_4)
entry_field.pack()

button_add = Button(frame_1, text = "add")
button_subtract = Button(frame_1, text = "subtract")
button_multiply = Button(frame_1, text = "multiply")
button_divide = Button(frame_1, text = "divide")
button_calculate = Button(frame_3, text = "calculate")
button_calculate.pack()

button_add.grid(row = 0)
button_subtract.grid(row = 0, column = 1)
button_multiply.grid(row=0,column= 2)
button_divide.grid(row=0,column = 3)

button_1 = Button(frame_2,text = "1", command = button_1_method())
button_2 = Button(frame_2,text = "2")
button_3 = Button(frame_2,text = "3")
button_4 = Button(frame_2,text = "4")
button_5 = Button(frame_2,text = "5")
button_6 = Button(frame_2,text = "6")
button_7 = Button(frame_2,text = "7")
button_8 = Button(frame_2,text = "8")
button_9 = Button(frame_2,text = "9")
button_0 = Button(frame_2,text = "0")

button_1.grid(row = 0)
button_2.grid(row = 0,column = 1)
button_4.grid(row=0, column= 3)
button_5.grid(row=0, column= 4)
button_6.grid(row=0, column= 5)
button_7.grid(row=0, column= 6)
button_8.grid(row=0, column= 7)
button_9.grid(row=0, column= 8)
button_0.grid(row=0, column= 9)

root.mainloop()

每当按下“一个”按钮时,我都会尝试将“1”添加到条目中显示的数字。但是我正在使用 button_1_method 并遇到各种错误。我该如何解决它,以便每当我按下一个按钮时,条目中的数字都会添加一个“1”(其余数字按钮也是如此)?

编辑:我改变了一点:

my_str_var = StringVar()

def button_1_method(my_str_var):
    my_str_var.set(my_str_var.get() + 1)
    entry_field.set(my_str_var)


button_1 = Button(frame_2,text = "1", command = button_1_method)

现在这是我得到的错误:

Traceback (most recent call last):
  File "C:/Users/TOTTY/PycharmProjects/beginnerpoject/python calculator.py", line 5, in <module>
    my_str_var = StringVar()
  File "C:\Python34\lib\tkinter\__init__.py", line 332, in __init__
    Variable.__init__(self, master, value, name)
  File "C:\Python34\lib\tkinter\__init__.py", line 236, in __init__
    self._root = master._root()
AttributeError: 'NoneType' object has no attribute '_root'

【问题讨论】:

  • 不要说“我遇到错误”让我们猜测问题所在,复制并粘贴整个错误消息(带有回溯)。 Python 为您提供所有这些信息的原因是它通常很有用。
  • 另外,如果这是一个计算器应用程序,我不认为您真的想在单击 1 按钮时将数字加 1;您想将 1 位数字附加到字符串 - 或者,如果您想用数字而不是字符串来考虑,您想乘以 10,然后加 1。
  • @abarnert 好的,我更改了它并发布了我现在收到的新错误消息
  • 新的错误是因为在创建root之前不能创建StringVar。 (没有很好的记录,所以这是一个可以理解的错误……)只需将root = Tk() 移到顶部,它就会消失。
  • 但是,您的代码仍然无法工作,因为您至少还有两个其他问题。首先,您不能将数字 1 添加到字符串中。您可以将字符串 '1' 附加到字符串;这可能就是你想要的。其次,您还没有以任何方式将my_str_var 附加到entry_field。你可能想要entry_field = Entry(frame_4, textvariable=my_string_var)。 (参见Entry 文档中的示例。)然后您不需要调用entry_field.set(这很好,因为不存在这样的Entry.set 方法)。

标签: python tkinter calculator


【解决方案1】:

set 是一个方法,你必须调用get 也是如此。

所以,不要这样:

my_int_var.set = my_int_var.get + 1

这样做:

my_int_var.set(my_int_var.get() + 1)

但除此之外,您还有另一个问题。 my_int_var 不是 Tk IntVar,它只是一个普通的旧 int,它没有这样的方法。它也不会以任何方式附加到您的 Entry 小部件。

因此,您需要使用my_int_var = IntVar() 创建一个Tk var,然后您需要在构造函数或config 调用中将其传递给小部件。

如果您查看找到 get 和 set 方法的文档,您会看到一些应该很明显的示例。特别是,请参阅 Entry 文档中模式下的第三个示例(但请务必阅读整个部分)。


除了与您的错误直接相关的问题之外,还有其他问题。例如:

button_1 = Button(frame_2,text = "1", command = button_1_method())

您想将函数button_1_method 作为命令传递。但这不是你正在做的;您正在调用该函数,获取它的返回值,并将 that 作为命令传递。 (这与您的第一个问题完全相反,您想要调用一个函数但没有使用括号。您不能指望 Python 猜测您何时要调用函数以及何时要将其用作值;括号是你告诉它调用函数的方式。)

同样,正如我在评论中提到的,即使你没问题,在数字上加 1 也不是计算器上的 1 键的作用。您需要直接了解数字及其字符串表示形式之间的差异,否则您将在使用此应用程序时遇到更多问题。 1 != '1',但是str(1) == '1' and 1 == int('1')

在您的更新版本中,您已将其更改为使用StringVar,其值当然是一个字符串,并且您正尝试将1 添加到其值中。这是同样的问题。同样,数字1 和字符串'1' 不是一回事。

当不存在此类方法时,您还尝试在 Entry 对象上调用 set 方法。阅读Entry 文档以了解如何更改或替换Entry 的值—但如果您使用的是StringVar(如在您编辑的代码中),则无需首先执行此操作地方。这就是将变量绑定到小部件的全部意义所在。任何一个的变化都会影响另一个。因此,当您调用 my_str_var.get 时,您将获得 Entry 小部件的当前内容,而当您调用 my_str_var.set 时,您将替换小部件的内容。

【讨论】:

  • @Laflexos:inttkinter.IntVar 的类型不同。你和提问者犯了同样的错误。
  • 首先,我在您第一次编辑后立即删除了我的评论。苏,对不起。除此之外,我写评论是因为有问题的是int,而不是因为它应该是。谢谢你的解释。
猜你喜欢
  • 1970-01-01
  • 2018-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-05
  • 2021-02-21
  • 2020-03-18
  • 1970-01-01
相关资源
最近更新 更多