Tkinter“条目”对象不更新文本变量变量(Python 3.4)

Lie*_*ith 2 python user-interface tkinter python-3.x

我正在尝试编写一个简单的 Python 程序,它允许用户以十进制或点分十进制格式输入 IP 地址,然后将其转换为相反的格式并将其显示在同一个输入框中(即,如果他们输入十进制 IP 地址,他们可以单击一个按钮,他们的输入将被替换为点分十进制等效项)。

我遇到的问题是将数据从输入框中拉出,然后将新数据放回输入框中。我只用 GUI 代码编写了一个示例,没有其他任何转换逻辑,以简化问题:

import tkinter as tk

root = tk.Tk()
root.title("Test")

win1 = tk.Frame(root)
win1.grid()

x = tk.StringVar()
y = tk.StringVar()

xBox = tk.Entry(win1)
xBox.grid(row = 0, column = 0)
xBox.textvariable = x

yBox = tk.Entry(win1)
yBox.grid(row = 1, column = 0)
yBox.textvariable = y

button = tk.Button(win1,text = "Calculate", command = lambda: copyVal())
button.grid(row = 2, column = 0)

def copyVal():
    print("x: " + x.get())
    print("y: " + y.get())
    xVal = x.get()
    print("xval: " + xVal)
    y.set(xVal)
    root.update_idletasks()

root.mainloop()
Run Code Online (Sandbox Code Playgroud)

这是我希望使用此代码发生的事情:

  1. 在顶部框中输入的值应存储在StringVar x.
  2. 单击“计算”按钮应运行该copyVal()函数:
  3. copyVal()获取 的值StringVar x并将其存储为xVal
  4. copyVal()将 的值设置StringVar y为 match xVal
  5. 底部框中的文本现在应该与顶部框中的文本匹配。

相反,它不会检索 的值StringVar x,因此无需设置StringVar y任何内容。

我尝试了以下变体:

  1. 使用xVal = xBox.get()代替xVal = x.get():这将检索顶部输入框的内容,并设置 的值StringVar y以匹配它,但底部输入框不会更改。
  2. 使用command = copyVal()代替command = lambda: copyVal()copyVal函数在程序执行时立即执行,而不是在按下按钮时执行。
  3. copyVal函数移出根主循环:NameError按下按钮时引发异常(copyVal被视为未定义)。
  4. 移动root.update_idletasks()外部copyVal功能没有任何影响。

我已经环顾四周寻找此问题的解决方案,但无论我发现有多少人遇到类似问题,他们的修复程序似乎都没有为我解决问题(我通常看到他们被告知StringVar()用于获取/设置值) . 我对使用 Tkinter 完全陌生,所以我确信这是我忽略的非常基本的东西,我感谢任何人可以提供的任何建议。

小智 5

Python 对象通常允许您任意添加属性:

>>> class Foo:
...     pass
...
>>> foo = Foo()
>>> foo.a = 1  # No error.  It makes a new attribute.
>>> foo.a
1
>>>
>>> def foo():
...     pass
...
>>> foo.a = 1  # Works with function objects too.
>>> foo.a
1
>>>
Run Code Online (Sandbox Code Playgroud)

所以,当你这样做时:

xBox.textvariable = x
...
yBox.textvariable = y
Run Code Online (Sandbox Code Playgroud)

您实际上并未将Entrys 的textvariable选项设置为xy。相反,您正在创建以textvariable这些对象中的每一个命名的新属性。

要解决此问题,请在创建小部件时设置 eachEntrytextvariable选项:

xBox = tk.Entry(win1, textvariable=x)
...
yBox = tk.Entry(win1, textvariable=y)
Run Code Online (Sandbox Code Playgroud)

.config稍后使用该方法更改它们:

xBox.config(textvariable=x)
...
yBox.config(textvariable=y)
Run Code Online (Sandbox Code Playgroud)