在Python TkInter中更新标签文本

时间:2014-09-28 08:28:27

标签: python tkinter

有没有办法创建一个使用字符串和变量作为文本的TkInter标签?

例如:

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

但是,不是只在标签创建时将标签的文本设置为上面的内容,而是在" name"之后更新文本。无需引用标签实例本身即可进行更改。

有人知道这是否可行?

3 个答案:

答案 0 :(得分:3)

您无法准确地完成您的要求 - 您无法同时将静态字符串和变量与标签相关联。你可以采取一些措施来获得理想的效果,但你所做的只是增加复杂性而没有真正的收获。例如,您可以将StringVar的实例分配给textvariable小部件的Label属性。执行此操作时,对变量的任何更新都将更新标签。但是,您最终必须进行函数调用才能更新变量,因此您不必通过函数调用直接更新标签。

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

另一种选择是使用StringVar的两个实例 - 一个用于标签,另一个用于名称。您可以对name变量进行跟踪,以便在更改时,使用静态字符串和name变量的值自动更新另一个变量,这将导致标签自动更新。但是,您需要再次进行函数调用以使所有内容处于运动状态

因此,正如您所看到的,有一些选项,但它们都会增加代码的复杂性,而不会直接更新标签。这些其他方法唯一获得优势的是当值需要同时出现在多个小部件中时。在这种情况下,您可以将变量与两个或多个小部件相关联,单个函数调用将更新所有关联的小部件。

答案 1 :(得分:2)

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

这里有一个例子。标签的文字是一个文本变量text,定义为StringVar,可以随时随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()

答案 2 :(得分:0)

是 - 标准Tkinter< 变量> -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

标签文字在&lt; 变量&gt;

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

仅供参考:高级&lt; 变量&gt; -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