首页 > 解决方案 > 显示哪个小部件具有焦点

问题描述

阅读之前:我是一个编程新手,更不用说 Python。我不期待解决方案。即使我只是得到一个正确方向的指针,我也会很感激。如果您觉得我请求帮助的方式不完善,请告诉我,以便下次我需要帮助时,我会做得更好。

目标:我正在制作一个程序来测试如何让程序根据必须关注的小部件做出响应。目前,我只是让它通过显示“什么”有焦点来响应。最终,一旦我弄清楚了这一点,我就可以将我学到的知识应用到我正在研究的另一个程序中,专注于输入字段将导致所有输入的字段清除。所以很自然,我希望这个程序不仅可以更改标签,还可以更改条目小部件。那将是以后。

进展:我已经设法让程序打印出哪个小部件在终端和标签小部件中都具有焦点。

问题:我的问题是消息很难看,我希望它看起来更整洁。

问题示例:它不是说“Entry has focus”,而是说“.!frame.!entry {has focus}”

我试过:检查其他人是否制作了类似的程序。我发现的唯一一个是我如何取得这么大的进步,但它并没有使文本更好。我还在各个网站上对 Python 如何处理我在该程序中使用的某些命令进行了研究。我是编程新手,所以我承认我不完全确定运行该程序的最佳方法是什么,因此尝试研究它对我来说很困难。

代码:

# Call tkinter tools
from tkinter import *
from tkinter import ttk

"""
TODO:
Add different widgets that can 'gain' focus.
Print in the terminal which widget has focus.
Change entry and label text depending on which widget has focus.
"""

# Develop the window and frame
root = Tk()
root.title("Focus Test")
root.columnconfigure(0, weight = 1)
root.rowconfigure(0, weight = 1)

frame = ttk.Frame(root, padding = "1 1 1 1")
frame.grid(column = 0, row = 0, sticky = (N, S, E, W))

# Resizes columns in frame
for col in range(1, 3):
    frame.columnconfigure(col, weight = 1)

# Resizes rows in frame
for row in range(1, 3):
    frame.rowconfigure(row, weight = 1)

# Add response label
foc_labvar = StringVar()
foc_labvar.set("No focus")
foc_lab = ttk.Label(frame, width = 7, textvariable = foc_labvar)
foc_lab.grid(column = 2, row = 2, sticky = (W, E))

# Add entry box
foc_entvar = StringVar()
foc_entvar.set("Entry widget")
foc_ent = ttk.Entry(frame, width = 7, textvariable = foc_entvar)
foc_ent.grid(column = 1, row = 1, sticky = (W, E))

# Add button
foc_butvar = StringVar()
foc_butvar.set("Button widget")
foc_but = ttk.Button(frame, width = 7, textvariable = foc_butvar)
foc_but.grid(column = 2, row = 1, sticky = (W, E))

# Focus commands
def focus(event):
    focused_widget = frame.focus_get()
    foc_labvar.set((focused_widget, "has focus"))
    print(focused_widget, "has focus")

# Bind mouse click to run focus command
root.bind("<Button-1>", focus)

# Resize widgets inside frame
for child in frame.winfo_children():
    child.grid_configure(padx = 5, pady = 5)


root.mainloop()

标签: pythontkinterttk

解决方案


您可以通过event处理小部件标识部分轻松完成此操作,例如:

def focus(event):
    focused_widget = event.widget.winfo_class()
    foc_labvar.set((focused_widget, "has focus")) # Or f'{focused_widget} has focus'
    print(focused_widget, "has focus")

这里event将为小部件提供widget方法,然后您可以在其上使用任何小部件方法,例如focus()insert()(如果它是条目小部件)等等。这里winfo_class应该可以工作,因为它是一种通用方法并且适用于所有小部件。

更多信息winfo_class,它将提供小部件的类,例如TButton按钮,因为这是tk引用它们的方式。如果您仍然想摆脱它,T那么只需event.widget.winfo_class()[1:]将“T”剪掉即可。


推荐阅读