繁体   English   中英

在 Python TkInter 中更新标签文本

[英]Update Label Text in Python TkInter

是否有任何可能的方法来创建使用字符串和变量作为文本的 TkInter 标签?

例如:

name = "bob"
Label(root, text="hello, my name is "+name)

但是,与其仅在创建标签时将标签文本设为上述内容,还不如在“名称”更改时更新文本,而无需引用标签实例本身。

有谁知道这是否可能?

你必须告诉标签以某种方式改变。

这里有一个例子。 标签的text定义为StringVar text变量text ,可以随时使用text.set()进行更改。
在示例中,当您单击复选框时,命令change告诉标签更改为新值(此处简化为采用两个值, oldnew

from Tkinter import Tk, Checkbutton, Label
from Tkinter import StringVar, IntVar

root = Tk()

text = StringVar()
text.set('old')
status = IntVar()

def change():
    if status.get() == 1:   # if clicked
        text.set('new')
    else:
        text.set('old')


cb = Checkbutton(root, variable=status, command=change)
lb = Label(root, textvariable=text)
cb.pack()
lb.pack()

root.mainloop()

您不能完全按照您的要求去做——您不能同时将静态字符串和变量与标签相关联。 您可以采取一些措施来获得所需的效果,但您所做的只是增加了复杂性而没有真正的收益。 例如,您可以将StringVar的实例分配给Label小部件的textvariable属性。 当您这样做时,对变量的任何更新都会更新标签。 但是,您最终必须进行函数调用来更新变量,因此与进行函数调用以直接更新标签相比,您并没有真正获得任何好处。

另一种选择是使用两个标签——一个用于静态文本,一个用于变量。 将它们并排放置,没有边框,这样用户就不会注意到。 然后,当您更新变量时,您将获得所需的效果。 但是,您仍然需要进行函数调用来设置变量,因此您并没有真正获得多少收益。

另一种选择是使用StringVar两个实例——一个用于标签,另一个用于名称。 您可以在 name 变量上放置一个跟踪,以便当它发生变化时,您会使用静态字符串和 name 变量的值自动更新另一个变量,这将导致标签自动更新。 然而,再次,您必须进行函数调用才能使一切都运转起来

因此,如您所见,有多种选择,但它们都增加了代码的复杂性,与直接更新标签相比并没有真正的好处。 只有当值需要一次出现在多个小部件中时,这些其他方法才能为您带来优势。 在这种情况下,您可以将变量与两个或多个小部件相关联,单个函数调用将更新所有关联的小部件。

是的——标准 Tkinter < variable >-s 机制是这样做的:

有一个 Tkinter StringVar() (以及类似的IntVar()DoubleVar()BoolVar() )对象构造函数,它准备了一个智能对象,准备好稍后在 Tkinter Widgets 中用于此目的。

您可以使用.set() / .get()方法来操作此类对象的值。

name              = StringVar()        # this creates a Tkinter object
name.set( "bob" )                      # .set() assigns / .get() retrieves
L = Label( root, textvariable = name ) # makes the <name> used in Label Widget

标签文本通过在 <变量> 中分配的新值而正确更改

name.set( "alice" )                    # .set() assigns a new value -> promoted
print L['text']                        # show, a value has been promoted in L

仅供参考:高级<变量>-s'工具

您可能还想了解更高级的 Tkinter 变量工具。 还有与 Tkinter 变量相关的更强大的工具——称为trace -er(s)——它们将 Tkinter 系统设置为“监视”对“跟踪”变量的任何更改,这可以关联进一步的自动响应活动,自动启动跟踪事件类型。

aWriteTraceID = name.trace_variable( "w", f2CallOnWriteAccessToTracedVariable )
aRead_TraceID = name.trace_variable( "r", f2CallOnRead_AccessToTracedVariable )
aDel__TraceID = name.trace_variable( "u", f2CallOnDel__AccessToTracedVariable )

name.trace_vinfo()                        # show all associated <<Tracers>>

>>> name.trace_vinfo()
[('u', '12945528f2CallOnDel__AccessToTracedVariable'),
 ('r', '12251384f2CallOnRead_AccessToTracedVariable'),
 ('w', '12760924f2CallOnWriteAccessToTracedVariable')
]

name.trace_vdelete( aRead_TraceID )       # delete an identified <<Tracer>>
name.trace_vdelete( aWriteTraceID )       # delete an identified <<Tracer>>

del( name )                               # del() makes name undefined
# so this will "auto-launch" the last, still active <<Tracer>>
# you assigned above -- the function f2CallOnDel__AccessToTracedVariable()

该工具可帮助您创建非常强大的 GUI 工具箱策略,用于高效、事件驱动、完全自反射的分层 [模型-视觉-控制器],在Tkinter.mainloop()调度程序的引擎盖下进行监督

如何把它放在一起?

正如 abarnert 所提议的,自动化版本原则上可能看起来像这样

name = StringVar()                         # a pure name holder
show = StringVar()                         # a post-processed text

L = Label( root, textvariable = show )     # L will display a post-processed string
L.pack()                                   # L goes into GUI framework's geometry manager

#                                          # prepare the <<Handler>> function
def autoProcessAndPropagateOnNameVarCHANGE( p1, p2, p3, p4 = name, p5 = show ):
    #                                      # this function will get called
    #                                      # upon WRITE-ACCESS <<Tracer>>
    #
    # .set( a post-processed value ) into [show], that is connected to GUI[Label]
    p5.set( "Hello, " + p4.get() )         
    #                                      # Always be carefull not to fire
    #                                      # an unstoppable chain-reaction ;)
    #                                      # of <<Tracer>>-related events
    #                                      # as more <<Tracer>>-s get used

#                                          # create <<Tracer>> / <<Handler>> pair
aWriteTraceID = name.trace_variable( "w", autoProcessAndPropagateOnNameVarCHANGE )

# -------------------------------------------------------------------------------
# test <<Tracer>>:
name.set( "Craig" )                        # <<Tracer>>-watched WRITE-ACCESS
# test <<Tracer>> result: GUI Label L shall show "Hello, Craig" -----------------

# -------------------------------------------------------------------------------
# erase all <<Tracer>>-s assigned:
name.trace_vinfo()                         # initial state of <<Tracer>>-s

for aTracerRECORD in name.trace_vinfo():
    name.trace_vdelete( aTracerRECORD[0], aTracerRECORD[1] )

# erase [[[DONE]]] --------------------------------------------------------------
name.trace_vinfo()                         # final   state of <<Tracer>>-s

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM