如何让python/tkinter标签组件更新?

29 投票
5 回答
118385 浏览
提问于 2025-04-15 17:06

我正在尝试让一个Python/Tkinter的标签组件更新它的内容。根据今天早些时候的一个讨论,我按照指示把组件组合在一起。但是在运行时,这个标签组件并没有改变内容,而是一直保持着最初的内容。根据我所能判断,decrement_widget()这个函数根本没有被调用。有没有什么想法?

def snooze (secs):
  """
  Snoozes for the given number of seconds. During the snooze, a progress
  dialog is launched notifying the 
  """

  root = Tkinter.Tk()
  prompt = 'hello'
  label1 = Tkinter.Label(root, text=prompt, width=len(prompt))
  label1.pack()

  remaining = secs

  def decrement_label ():
    text = "Snoozing %d sec(s)" % remaining
    remaining -= 1
    label1.config(text=text, width=100)
    label1.update_idletasks()

  for i in range(1, secs + 1):
    root.after(i * 1000, decrement_label )

  root.after((i+1) * 1000, lambda : root.destroy())
  root.mainloop()

5 个回答

1
    import tkinter
    from tkinter import *

    # just init some vars
    remaining = 0                
    secs = 0
    root = tkinter.Tk()
    prompt = StringVar()

    def snooze (secs):
      """
      Snoozes for the given number of seconds. During the snooze, a progress
      dialog is launched notifying the 
      """
      def decrement_label ():
        global remaining, prompt
        remaining -= 1
        prompt.set('Snoozing %d sec(s)' % remaining)
        label1.update_idletasks()
        if not remaining:
          print("end ... ")
          root.destroy()

      global remaining
      prompt.set("hello")
      label1 = tkinter.Label(root, textvariable=prompt, width=30)
      label1.pack()

      remaining = secs
      for i in range(1, secs + 1):
        root.after(i * 1000, decrement_label )

    snooze(10)
    root.mainloop()

当然可以!请把你想要翻译的内容发给我,我会帮你把它变得简单易懂。

9

我觉得你遇到的“在赋值前引用”错误是因为Python认为remaining是在本地作用域里。

在Python 3中,你可以使用nonlocal remaining来解决这个问题。但是在Python 2中,我认为没有办法引用一个既不是本地也不是全局的作用域。这个方法对我有效:

remaining = 0

def snooze (secs):
  """
  Snoozes for the given number of seconds. During the snooze, a progress
  dialog is launched notifying the 
  """

  global remaining
  root = Tkinter.Tk()
  prompt = 'hello'
  label1 = Tkinter.Label(root, text=prompt, width=len(prompt))
  label1.pack()

  remaining = secs

  def decrement_label ():
    global remaining
    text = "Snoozing %d sec(s)" % remaining
    remaining -= 1
    label1.config(text=text, width=100)
    label1.update_idletasks()

  for i in range(1, secs + 1):
    root.after(i * 1000, decrement_label )

  root.after((i+1) * 1000, lambda : root.destroy())
  root.mainloop()
47

你需要把标签的 textvariable 设置为一个 StringVar;当这个 StringVar 发生变化时(比如你调用 myStringVar.set("这里是文本")),标签上的文本也会自动更新。没错,我也觉得这样做确实有点奇怪。

想了解更多信息,可以看看 Tkinter书籍

你可以把一个Tkinter变量和标签关联起来。当这个变量的内容改变时,标签会自动更新:

v = StringVar()
Label(master, textvariable=v).pack()

v.set("New Text!")

撰写回答