首页 文章

从Entry Widgets TKinter不断更新标签小部件

提问于
浏览
0

我正在尝试使用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()

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

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()

先感谢您 . 六

1 回答

  • 3

    while True 将无效,因为 mainloop() 是某种 while True 循环,它一直有效,直到你停止程序 .


    您必须使用 after(time_in_millisecond, function_name)function_name 添加到特殊队列, mainloop() 将在 time_in_millisecond 之后运行它(仅一次) . 在 time_in_millisecond 之后,执行的函数可以使用 after() 再次运行 .


    第二种解决方案:您可以将 StringVarEntry 一起使用,并且可以将功能分配给 StringVar (使用 trace() ),并且每次更改 StringVar 时都将执行此功能 .


    第三种解决方案:您可以将事件( <Key> )绑定到 Entry ,当您在Entry中按键时将调用某个函数 .


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


    见Tkinterbook:
    The Tkinter Entry Widget
    Events and Bindings
    The Variable Classes (BooleanVar, DoubleVar, IntVar, StringVar)


    EDIT:

    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()
    
    #------------------------------------
    

    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()
    
    #------------------------------------
    

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

    在将char放入 Entry 之前调用绑定函数,以便在 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()
    
    #------------------------------------
    

    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()
    
    #------------------------------------
    

相关问题