【问题标题】:Tkinter: Problems when saving multiple Entry widgets to listTkinter:将多个条目小部件保存到列表时出现问题
【发布时间】:2016-03-29 03:05:25
【问题描述】:

我正在开发一个界面,用户将从显示的图像中选择点。包含选定点的列表显示在窗口的右侧。每次用户单击一个点时,列表都会更新以添加新点。列表中的点显示为坐标,在坐标旁边有一个 Entry 小部件,因此用户可以为该特定点分配一个文本标签。

由于我不知道用户要选择多少个点,并且我不知道用户是要在选择一个点后立即填写名称条目还是在选择所有点后填写,所以用户按下“CONTINUE”按钮后,将读取 Entry 小部件中的文本。

到目前为止,我一直在做的是:每次添加一个新点,即每次创建一个新的 Entry 小部件时,都会将该小部件保存到一个列表中。这是每次添加新点时执行的函数:

def _update_point_list(self):
    self.dynamic_frame.pack_forget()
    self.dynamic_frame.destroy()
    self.dynamic_frame = Frame(self.Fpoints)
    self.dynamic_frame.pack()

    for coo, i in zip(self.dynamic_points, range(len(self.dynamic_points))):
        L = Label(self.dynamic_frame, text=str([coo[0], coo[1]]))
        T = Entry(self.dynamic_frame, width=15)
        T.insert(INSERT, "Target name")
        B = Button(
            self.dynamic_frame,
            text='\xe2\x98\x92'.decode('utf8'),
            command=lambda i=i: self._button_remove_point(i))
        L.grid(row=i + 1, column=1)
        T.grid(row=i + 1, column=2)
        B.grid(row=i + 1, column=3)
        print T
        self.entries.append(T)

    if len(self.dynamic_points) > 0:
        self.cont.configure(state=ACTIVE)
        self.label.configure(
            text='\n              Selected points              \n')
    else:
        self.cont.configure(state=DISABLED)
        self.label.configure(
            text='\n            No points selected            \n')

“CONTINUE”按钮在按下时会调用以下函数:

def _read_data(self):
    for t in self.entries:
        self.labels.append(t.get())

但是,当我运行它时,我收到以下错误:

Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in __call__
return self.func(*args)
File "/media/Fran/dataproc/timeseries/astrointerface.py", line 202, in _read_data
self.labels.append(t.get())
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 2475, in get
return self.tk.call(self._w, 'get')
TclError: invalid command name ".140339446529128.140339400493320.140339400493896.140339400493608"

如果我打印“self.labels”,它会显示:

.140339446529128.140339400493320.140339400493896.140339400493608

尽管我知道我可以通过在条目右侧添加另一个按钮来“加载”目标名称来解决此问题,但我更希望通过单击来完成此操作。但是,我没有在代码中看到我的错误。

我一直在网站上查看类似的答案,他们都使用将条目小部件添加到列表中,所以我真的不知道这里会发生什么。

非常感谢。

【问题讨论】:

  • 所有条目 ID 已合并为一个字符串 --> TclError: invalid command name ".140339446529128.140339400493320.140339400493896.140339400493608" 尝试仅使用一个条目,删除 _read_data() 中的条目内容重复使用相同的小部件。
  • "invalid command name ".xxxxx"" 通常意味着您正在尝试调用已删除小部件上的方法。此代码是否在入口小部件被销毁后运行?
  • 为了更好地分析您的问题,更多代码会有所帮助。在调用_read_data 之前和将条目添加到列表之后会发生什么?还可以在获取条目数据之前尝试打印t,以检查它是否是预期的类型。
  • 在销毁父框架时,是否也重新初始化了你的条目列表? self.entries = [] 销毁 def _update_point_list(self) 中的框架后

标签: python tkinter


【解决方案1】:

_update_point_list 破坏 dynamic_frame 并在第一个 for 循环中将创建的条目附加到 self.entries。因此,您的旧条目(作为动态框架的子项被销毁)仍在列表中。在self.dynamic_frame.destroy() 内部_update_point_list 之后设置self.entries = [] 应该可以解决您的问题。

来自 effbot 文档:

破坏() [#] 销毁小部件。小部件从屏幕上移除,并且与小部件关联的所有资源都被释放。

【讨论】:

    猜你喜欢
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-14
    • 1970-01-01
    • 2016-08-18
    相关资源
    最近更新 更多