不断更新来自入口小部件 TKinter 的标签小部件

Six*_*ged 0 python tkinter widget

我正在尝试使用 TKinter 制作一个表单,该表单从一个/多个条目小部件获取信息并将它们用作文本小部件的值。例如,这可以工作:

import Tkinter
from Tkinter import *
top = Tk()


e1 = Entry(top)
e2 = Entry(top)
t = Label(top, text = e1.get() + e2.get())
e1.pack()
e2.pack()
t.pack()

top.mainloop()
Run Code Online (Sandbox Code Playgroud)

问题是这不会自动更新。我知道可以使用按钮来完成,但我希望在用户输入 Entry 小部件时在 Label 小部件中计算/更新信息。最好的做法是什么?当程序进入 top.mainloop() 并且不退出时,while 循环的以下实现不起作用:

import Tkinter
from Tkinter import *
top = Tk()


e1 = Entry(top)
e2 = Entry(top)
t = Label(top, text = e1.get() + e2.get())
e1.pack()
e2.pack()

while True:

    t = Label(top, text = e1.get() + e2.get())
    t.pack()
    top.mainloop()
Run Code Online (Sandbox Code Playgroud)

先感谢您。六

fur*_*ras 5

while True不会工作,因为这mainloop()是某种while True循环,它一直工作,直到你停止程序。


您必须使用after(time_in_millisecond, function_name)which add function_nameto special queue 并将mainloop()time_in_millisecond. 执行后的函数可以用来after()再次运行自己time_in_millisecond


第二种解决方案:您可以使用StringVarwithEntry并且可以将函数分配给StringVar(using trace()),并且每次StringVar更改时都会执行此函数。


第三种解决方案:您可以绑定事件(<Key>),Entry当您在Entry中按下键时会调用一些函数。


最后的解决方案:当条目中的文本将被更改时,您可以使用validatecommand=with validate=inEntry调用某些函数。


请参阅 Tkinterbook:
Tkinter 条目小部件
事件和绑定
变量类(BooleanVar、DoubleVar、IntVar、StringVar)


编辑:

例如用validatecommand=validate=

并非所有小部件都有 validatecommand=

from Tkinter import *

#------------------------------------

def my_validater():
    new_text = e1.get() + e2.get()

    # different method to set label text (without StringVar)
    #t['text'] = new_text
    t.config(text=new_text)

    # validater have to return True or False
    return True 

#------------------------------------

top = Tk()

#---

t = Label(top)
t.pack()

#---

e1 = Entry(top, validate='key', validatecommand=my_validater) # validate every key
e1.pack()

#---

e2 = Entry(top, validate='key', validatecommand=my_validater) # validate every key
e2.pack()

#---

top.mainloop()

#------------------------------------
Run Code Online (Sandbox Code Playgroud)

用实施例StringVartrace

可能是大多数小部件的最佳解决方案。

from Tkinter import *

#------------------------------------

def my_tracer(a, b, c): # trace send 3 arguments to my_tracer
    #print a, b, c

    # using StringVar to get and set text
    new_text = e1_var.get() + e2_var.get()
    t_var.set(new_text)

#------------------------------------

top = Tk()

#---

t_var = StringVar() # or StringVar(top) 

t = Label(top, textvariable=t_var)
t.pack()

#---

e1_var = StringVar() # or StringVar(top) 
e1_var.trace('w', my_tracer) # run my_tracer if value was changed (w = write)

e1 = Entry(top, textvariable=e1_var)
e1.pack()

#---

e2_var = StringVar() # or StringVar(top) 
e2_var.trace('w', my_tracer) # run my_tracer if value was changed (w = write)

e2 = Entry(top, textvariable=e2_var)
e2.pack()

#---

top.mainloop()

#------------------------------------
Run Code Online (Sandbox Code Playgroud)

示例与 bind(<Key>, ...)

在放置 char 之前调用绑定函数,Entry因此您可以获得没有最后一个字符的文本 in Entry。这种方法不适合这种情况,但我保留了它。最终,您可以获得event.char并将缺少的字符添加到文本中。

from Tkinter import *

#------------------------------------

def my_bind(event): # bind send 1 argument to my_bind
    # different type of event can have different atributes
    #print event, event.widget, event.char, event.keysym, event.keycode

    new_text = e1.get() + e2.get()
    t.config(text=new_text)

#------------------------------------

top = Tk()

#---

t = Label(top)
t.pack()

#---

e1 = Entry(top)
e1.pack()

e1.bind('<Key>', my_bind)

#---

e2 = Entry(top)
e2.pack()

e2.bind('<Key>', my_bind)

#---

top.mainloop()

#------------------------------------
Run Code Online (Sandbox Code Playgroud)

以 为例after()

用于不同的重复作业。

from Tkinter import *

#------------------------------------

def my_after(): 
    new_text = e1.get() + e2.get()

    t.config(text=new_text)

    # call again after 100 ms
    top.after(100, my_after)

#------------------------------------

top = Tk()

#---

t = Label(top)
t.pack()

#---

e1 = Entry(top)
e1.pack()

#---

e2 = Entry(top)
e2.pack()

#---

# call first time 
my_after()

# call first time after 100 ms
#top.after(100, my_after)


#---

top.mainloop()

#------------------------------------
Run Code Online (Sandbox Code Playgroud)