python tkinter中返回光标所在的entry,返回值与定义的entry不一致这是为什么?

代码如下,创建两个entry: entry1 entry2
查看光标所在的entry
光标在entry1上返回的是.!frame.!entry,为什么不是.!frame.!entry1
在entry2上返回的又是.!frame.!entry2

还有为什么不是定义的frame1而是frame?


from tkinter import *

root = Tk()
root.title('Toolbox')
root.geometry('400x400')

frame1 = tk.Frame(root,height=398,width=398, bd=2, relief="groove")
frame1.place(x=2,y=2)

lab1 = ttk.Label(frame1,text = "aaa:")
lab1.place(x=40,y=50)
var1 = tk.StringVar()
entry1 = tk.Entry(frame1, width=6, textvariable=var1)
entry1.place(x=80,y=50)

lab2 = ttk.Label(frame1,text = "bbb:")
lab2.place(x=240,y=50)
var2 = tk.StringVar()
entry2 = tk.Entry(frame1, width=6, textvariable=var2)
entry2.place(x=280,y=50)

var3 = tk.StringVar()
lab3 = tk.Label(frame1,bg='#d3fbfb',fg='blue',width=30,height=3,textvariable=var3)
var3.set("光标在Entry对象上")
lab3.place(x=40,y=150)
# lab3 = ttk.Label(frame1,text='第一个标签',bg='#d3fbfb',fg='blue',font=('华文新魏', 20),width=30,height=3)
# lab3.place(x=40,y=150)
def hhh(*args):
    print("光标在Entry对象上" + str(frame1.focus_get()))
    var3.set("光标在Entry对象上"+ str(frame1.focus_get()))
    
var1.trace('w',hhh)
var2.trace('w',hhh)
root.mainloop()

img

在Tkinter中,每个小部件都有一个名称,称为小部件的路径名。路径名由小部件的父级和小部件的名称组成,用句点分隔。在这个例子中,entry1和entry2是frame1的子级,因此它们的路径名是.!frame.!entry1和.!frame.!entry2。当你调用frame1.focus_get()时,它返回当前具有焦点的小部件的路径名。因此,当光标在entry1上时,它返回.!frame.!entry,因为entry1是frame1的子级,而不是frame1本身。同样,当光标在entry2上时,它返回.!frame.!entry2。

至于为什么不是定义的frame1而是frame,这是因为在代码中使用了Tkinter的缩写方式导入模块,即from tkinter import *。这意味着所有Tkinter模块中的函数和类都被导入到全局命名空间中,因此你可以直接使用Frame而不是tk.Frame。因此,当你在代码中使用Frame时,它实际上是指Tkinter中的Frame类。

  • 以下回答由chatgpt基于相关博客总结生成:

    因为在python tkinter中,每一个控件在生成后都有一个内部名称,因此在使用.winfo_containing()函数获取当前光标在哪个entry时,返回的就是该entry控件的内部名称。内部名称是由父控件名称、控件类型和控件在该父控件中的位置组成,并用"."连接起来。所以当你获取到.!frame.!entry时,表示该entry控件是在名为frame的父控件中,并且是该父控件下的第一个entry控件。

    要解决这个问题,可以考虑使用绑定事件函数,来动态获取当前光标所在的entry。具体步骤如下:

    1.创建两个Entry控件,并为它们绑定事件函数。

    import tkinter as tk
    
    def get_focus(event):
        # 获取当前光标在哪个entry
        event.widget.focus_on()
        print(event.widget)
    
    root = tk.Tk()
    e1 = tk.Entry(root)
    e2 = tk.Entry(root)
    
    # 绑定获取焦点事件
    e1.bind("<FocusIn>", get_focus)
    e2.bind("<FocusIn>", get_focus)
    
    e1.pack()
    e2.pack()
    root.mainloop()
    
    1. 实现事件函数,获取当前光标所在的Entry。
    def get_focus(event):
        # 获取当前光标在哪个entry
        event.widget.focus_on()
        print(event.widget)
    

    这个函数的作用是获取当前控件的焦点,并打印出当前控件的名称。

    1. 将获取到的entry控件名称与你所定义的entry控件名称进行比较。
    def get_focus(event):
        # 获取当前光标在哪个entry
        event.widget.focus_on()
        if event.widget == e1:
            print("光标在entry1上")
        elif event.widget == e2:
            print("光标在entry2上")
    

    在这个示例中,我们将获取到的entry控件名称与e1和e2进行比较,如果相等,则打印出光标所在的entry控件名称。

    总结:

    我们可以通过在Entry控件上绑定事件函数,并在事件函数中获取当前控件的名称,从而查看光标所在的Entry。可以通过与你所定义的entry控件的名称进行比较,来判断光标所在的entry控件是哪一个。