我需要从创建标签的函数外部更新一些标签文本

时间:2019-09-16 16:53:49

标签: python tkinter

我在函数内部创建了一个tkinter.Label,并且从代码的完全分开的一部分中,我需要更新文本。

在过去的一个小时内,我几乎尝试了google提供的所有解决方案,但我无法让它们中的任何一个都能正常工作,有些错误,有些显示空白,有些却无能为力。

我正在如下创建标签

def createWindow():
    window = tkinter.Tk()
    container = tkinter.Frame(window, padx=5, pady=5)
    summaryFrame = tkinter.Frame(container, bd=2, relief='groove')
    summaryFrame.pack(side='top', fill='x')
    summaryUser = tkinter.Label(summaryFrame, text='Some text').grid(row=1, column=1, sticky='w')

很久以后,我需要更改此标签的文本,但是由于我不再在此createWindow()函数中,因此无法访问包含文本的summaryUser变量。

我尝试了summaryEvent [“ text”](错误,因为它不可用),我尝试使用全局变量并使用textvariable = AGlobalVariable而不是text ='Some text'(将标签文本留为空白)和许多其他方法google结果全部失败。

这似乎应该比这更容易...

编辑1

我尝试了以下方法...

summaryUserText = 'Some text'

def createWindow():
    global summaryUserText
    window = tkinter.Tk()
    container = tkinter.Frame(window, padx=5, pady=5)
    summaryFrame = tkinter.Frame(container, bd=2, relief='groove')
    summaryFrame.pack(side='top', fill='x')
    summaryUser = tkinter.Label(summaryFrame, textvariable=summaryUserText)
    summaryUser.grid(row=1, column=1, sticky='w')

当我尝试这样做时,标签只是以空白开始,而不是变量的内容。

编辑2

我也尝试了以下方法...

summaryUserText= tkinter.StringVar()
summaryUserText.set('Some text')

def createWindow():
    ...
    summaryUser= tkinter.Label(summaryFrame, textvariable=summaryUserText)

但是,一旦python看到第一行,它就会出现以下错误...

  File "C:\Program Files\Python37\lib\tkinter\__init__.py", line 480, in __init__
    Variable.__init__(self, master, value, name)
  File "C:\Program Files\Python37\lib\tkinter\__init__.py", line 317, in __init__
    self._root = master._root()
AttributeError: 'NoneType' object has no attribute '_root'

编辑3

在一个完整的文件中模拟问题的最简单的代码

import tkinter

def loadEvent():
    global summaryEventText
    summaryEventText.set('Updated')
    print('Updated')

def createWindow():
    global  summaryEventText
    window = tkinter.Tk()
    summaryEventText = tkinter.StringVar()
    summaryEventText.set('Init')
    summaryEventLabel = tkinter.Label(window, text='Event:').grid(row=0, column=0, sticky='e')
    summaryEvent = tkinter.Label(window, textvariable=summaryEventText).grid(row=0, column=1, sticky='w')
    window.mainloop()

createWindow()
loadEvent()

没有错误,print('Updated')有效,但是summaryEventText.set('Updated')不起作用。

1 个答案:

答案 0 :(得分:-1)

简短的答案是:要更改对象,您必须具有对该对象的引用。这不是tkinter独有的,它是编程的基本方面。您正在使用局部变量,根据定义,这意味着您无法访问该函数之外的小部件。因此,解决方案是不使用局部变量。

适当的解决方案要求您保存其他函数可以访问的引用,或者提供可以返回引用的函数。让该函数返回引用,使用全局变量或使用类变量。

您的特定示例最简单的解决方案是使用全局变量。例如:

import tkinter

def loadEvent():
    ...
    summaryEventLabel.configure(text='Updated')
    ...

def createWindow():
    global  summaryEventLabel
    ...
    summaryEventLabel = tkinter.Label(window, text='Event:')
    summaryEventLabel.grid(row=0, column=0, sticky='e')
    ...

createWindow()
loadEvent()

但是,您的特定示例将不起作用,因为window.mainloop()在窗口被销毁或调用其quit方法之前不会返回。这意味着createWindow将不会返回,因此不会调用loadEvent

如果您要构建程序来避免此问题(例如,为响应按钮单击或其他事件而调用loadEvent),则此解决方案将起作用。

这是一个有效的示例,可在5秒后更新标签:

import tkinter

def loadEvent():
    summaryEventLabel.configure(text='Updated')
    print('Updated')

def createWindow():
    global  summaryEventLabel
    window = tkinter.Tk()
    summaryEventText = tkinter.StringVar()
    summaryEventText.set('Init')
    summaryEventLabel = tkinter.Label(window, text='Event:')
    summaryEventLabel.grid(row=0, column=0, sticky='e')
    summaryEvent = tkinter.Label(window, textvariable=summaryEventText).grid(row=0, column=1, sticky='w')
    window.after(5000, loadEvent)
    window.mainloop()

createWindow()