Tkinter 检查哪个条目最后有焦点 [英] Tkinter check which Entry last had focus
问题描述
我正在开发一个具有我使用 Tkinter 创建的虚拟键盘的程序.启用了键盘的页面具有用户需要输入数据的条目小部件.我使用 pyautogui
作为虚拟键盘的一部分来模拟键盘按下,但我的问题是当用户按下键盘上的任何按钮时聚焦的小部件.由于每个键盘按钮在他们按下按键时都是一个 ttk.Button
,因此该按钮具有焦点,而不是他们选择的他们试图将数据放入的 Entry 小部件.
I am working on a program that has a virtual keyboard I created using Tkinter. The pages that have the keyboard enabled have entry widgets where the users need to input data. I am using pyautogui
as part of the virtual keyboard to simulate the keyboard presses, but my issue is the widget that is focused when a user presses on any of the buttons on the keyboard. Since each keyboard button is a ttk.Button
when they press the keys, the button has the focus, and not the Entry widget they had selected they were trying to put data in.
因此,现在我有运行按键的方法,在按键之前调用特定的小部件以成为焦点.这是我现在拥有的代码:
As such right now I have the method which runs the keypresses, calling a specific widget to become the focus before it does the key press. Here's the code I have right now:
import tkinter as tk
from tkinter import ttk
import pyautogui
def drawKeyboard(parent):
keyboardFrame = tk.Frame(parent)
keyboardFrame.pack()
keys = [
[ ("Alpha Keys"),
[ ('q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'),
(' ', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'),
('capslock', 'z', 'x', 'c', 'v', 'b', 'n', 'm'),
('delete', 'backspace', 'home', 'end')
]
],
[ ("Numeric Keys"),
[ ('7', '8', '9'),
('4', '5', '6'),
('1', '2', '3'),
(' ', '0', ' ')
]
]
]
for key_section in keys:
sect_vals = key_section[1]
sect_frame = tk.Frame(keyboardFrame)
sect_frame.pack(side = 'left', expand = 'yes', fill = 'both', padx = 10, pady = 10, ipadx = 10, ipady = 10)
for key_group in sect_vals:
group_frame = tk.Frame(sect_frame)
group_frame.pack(side = 'top', expand = 'yes', fill = 'both')
for key in key_group:
key = key.capitalize()
if len(key) <= 1:
key_button = ttk.Button(group_frame, text = key, width = 4)
else:
key_button = ttk.Button(group_frame, text = key.center(5, ' '))
if ' ' in key:
key_button['state'] = 'disable'
key_button['command'] = lambda q=key.lower(): key_command(q)
key_button.pack(side = 'left', fill = 'both', expand = 'yes')
def key_command(event):
entry1.focus()
pyautogui.press(event)
return
root = tk.Tk()
entry1 = tk.Entry(root)
entry1.pack()
entry2 = tk.Entry(root)
entry2.pack()
drawKeyboard(root)
root.mainloop()
如果我想将数据输入到 entry2
中,显然手动调用 entry1.focus()
对我没有好处.如果我想将数据放入 entry1
,调用 entry2.focus()
并没有什么好处.那么有没有办法让我每次按下我的一个按钮时检查哪个 Entry Widget 最后获得焦点?
Obviously manually calling entry1.focus()
does me no good if I want to input data into entry2
. And calling entry2.focus()
does no good if I want to put data into entry1
. So is there a way for me to every time one of my buttons is pressed check to see which Entry Widget last had focus?
我需要专门检查条目小部件,因为最终屏幕也会有一些单选按钮等.感谢您的时间
I need to check for specifically entry widgets as the final screen will also have some radio buttons and such. Thanks for your time
我对代码进行了快速更改,将 Shift
键替换为 Capslock
键.我意识到我的代码工作方式 Shift 永远不会真正工作,因为你不能完全按住它并按下另一个按钮.
I made a quick change to the code, exchanging the Shift
key for the Capslock
key. I realized that the way my code worked Shift would never actually work since you couldn't exactly hold it down and press another button.
推荐答案
您可以将属性 takefocus
设置为 False
以防止按钮获得焦点.这具有无法使用键盘遍历按钮的不幸副作用(这可能没问题,因为您处于无键盘的情况)
You can set the attribute takefocus
to False
to prevent the buttons from taking focus. This has the unfortunate side effect of not being able to traverse the buttons using the keyboard (which might be ok, since you're in a no-keyboard situation)
...
key_button = ttk.Button(..., takefocus=False)
...
def key_command(event):
entry = root.focus_get()
entry.insert("end", event)
pyautogui.press(event)
return
另一种解决方案是在 <FocusIn>
事件上添加绑定,您可以在其中将小部件保存在全局变量中.
Another solution is to add a binding on the <FocusIn>
event where you can save the widget in a global variable.
def key_command(event):
focused_entry.insert("end", event)
pyautogui.press(event)
return
def remember_focus(event):
global focused_entry
focused_entry = event.widget
entry1.bind("<FocusIn>", remember_focus)
entry2.bind("<FocusIn>", remember_focus)
如果你有很多入口小部件,你可以在 Entry
类上做一个类绑定:
If you have many entry widgets, you can do a class binding on the Entry
class instead:
root.bind_class("Entry", "<FocusIn>", remember_focus)
这篇关于Tkinter 检查哪个条目最后有焦点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!