tkinter标签更新但不正确

时间:2016-08-16 22:05:29

标签: python tkinter label

使用Python 3.5。我有tkinter表格。用户单击按钮可将许多文件导入Listbox。另一个按钮循环访问文件并从中读取和提取数据。

我在表单上有一个Label,表示循环的状态。大多数情况下,状态按预期工作,但最后添加了额外的字符。我不确定角色的来源。我还print()Label相同的内容返回到屏幕,print()显示了应该显示的内容。

我的问题是为什么我的Label没有显示正确的字符串?

我的代码大大缩短了:

class tk_new_db:
    def __init__(self, master):
        self.master = master  # sets 'root' to the instance variable 'master'
        self.var_text_2 = StringVar()
        self.var_text_2.set('STATUS: Active')
        self.label_6 = Label(master, textvariable=self.var_text_2,
                             font=self.font_10)
        self.label_6.grid(row=15, sticky=W, padx=15)

    def execute_main(self):  # extract data from files
        file_num = 0
        nf = len(self.listbox_1.get(0, END))
        for fr in li:
            file_num += 1
            print('STATUS: Extracting Loads from File '
                  '{} in {}'.format(file_num, nf))
            self.var_text_2.set('STATUS: Extracting Loads from File '
                                '{} in {}'.format(file_num, nf))
            self.master.update_idletasks()

print()正在编写以下内容: STATUS: Extracting Loads from File 1 in 5

Label正在编写以下内容: STATUS: Extracting Loads from File 1 in 5 nce...

它总是在表单上添加' nce...'

编辑:

我之前在程序中使用self.var_text_2' nce...'看起来像是前一个字符串的片段。我曾尝试以两种不同的方式重置变量,但我仍然得到相同的结果。

    self.var_text_2.set('STATUS: Checking .F06 Files for Convergence...')
    self.master.update_idletasks()
    self.var_text_2.__del__()

    self.var_text_2.set('STATUS: Checking .F06 Files for Convergence...')
    self.master.update_idletasks()
    self.var_text_2.set('')

如何正确删除StringVar()以便重复使用?

2 个答案:

答案 0 :(得分:0)

我能想到的唯一解释是你在相同的行和列中堆叠标签,所以当你添加一个以" nce ...结尾的长字符串时#34;然后通过在同一网格单元格中添加较短的标签来更新屏幕,下方较长标签的尾随文本将显示出来。

我得出这个结论的原因是:

  1. 这是我多次见过的常见错误
  2. tkinter中没有可能导致此错误的错误
  3. 您已经展示的代码中没有任何内容可以添加" nce ..."到字符串的末尾
  4. 您使用sticky="w"而非sticky="ew"的事实,如果放置在同一行和列中,这会导致较短的标签未完全覆盖较长的标签

答案 1 :(得分:0)

我想我可以解释一下。 Root.mainloop重复调用root.update。 Root.update在'main'事件队列上执行任务。简而言之,它只在事件队列为空 检查文件事件(非Windows),window-gui事件和计时器事件后才执行idletasks。 Idletasks从未被很好地记录,但似乎主要是屏幕更新任务,从未添加到主事件队列中。因此,idletask可能会无限期地保持不动。 Root.update_idletasks存在以强制执行idletasks。

当mainloop运行时,在更新运行的任务中调用update通常是不必要的,可能更糟。这只适合喜欢冒险的专家。因此,您已阅读的警告(假设您正在运行mainloop)。

当mainloop没有运行并且没有重复调用更新时,要么是因为你从未调用过mainloop,要么是因为你用长时间运行的循环来阻止它,那么你可能必须自己调用update。你似乎发现的是,完全处理StringVar更新的部分是一个主要事件,而不仅仅是一个idletask。

我同情你希望用for循环执行重复任务,但目前这样做意味着自己承担事件处理的责任。我希望将来有可能让'async for'(3.5中的新功能)与Tk.mainloop互操作,但它并不像我希望的那么容易。

同时,您可以将for循环的主体放入回调并使用root.after循环。