代码之家  ›  专栏  ›  技术社区  ›  Psionman

如何在tkinter中获取被跟踪变量的引用

  •  0
  • Psionman  · 技术社区  · 6 月前

    我有一个tkinter应用程序,它有可变数量的条目,我想检测内容的变化,特别是哪个条目被更改了

    import tkinter as tk
    from tkinter import ttk
    
    DOGS = 3
    
    def main() -> None:
        root = tk.Tk()
        root.title('')
        root.geometry('400x400')
    
        dogs = {}
        entries = {}
    
        for row in range(DOGS):
            dogs[row] = tk.StringVar()
            dogs[row].trace_add('write', dog_changed)
            entries[row] = ttk.Entry(root, textvariable=dogs[row])
            entries[row].grid(row=row, column=0)
    
        root.mainloop()
    
    def dog_changed(*args):
        print(args)
    
    if __name__ == '__main__':
        main()
    

    我可以在args中看到,我将StringVar的名称作为字符串(例如“PY_VAR0”),但是否有一种更优雅的方法来获取已更改条目的引用,而不是在此处使用substr。

    我试过这个lambda函数,但当然它只显示行的当前值

        dogs[row].trace_add('write', lambda *args: dog_changed(row, *args))
    
    1 回复  |  直到 6 月前
        1
  •  1
  •   JRiggles    6 月前

    我不确定这是否有帮助,但您可以指定 name 你的 StringVar 实例:

    dogs[row] = tk.StringVar(name=f'dog{row}')  # you can set this to whatever you likez
    

    打印此内容:

    ('dog0', '', 'write')
    ('dog1', '', 'write')
    ('dog2', '', 'write')
    

    您还可以在 Entry 小部件本身,例如 '<Key>' 每当在小部件内按下按键时,它就会触发。然后,您可以从传递的 event (你可能根本不需要 trace 如果你这样做,绑定):

    # put this in your for loop
    entries[row].bind('<Key>', lambda e: print(e.widget))
    

    请注意,您不必使用 lambda 这里-您可以将其绑定到函数;该函数只需要接受传入 事件 参数。