我在函数内部创建了一个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')不起作用。
答案 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()