54754

Tkinter check which Entry last had focus

<h3>Question</h3>

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

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

EDIT: 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.


<h3>Answer1:</h3>

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

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)

If you have many entry widgets, you can do a class binding on the Entry class instead:

root.bind_class("Entry", "<FocusIn>", remember_focus)
<h3>Answer2:</h3>

Hi you will find two methods useful and they are described in this post:

How do you check if a widget has focus in Tkinter?

<ol><li>

Bind your entry boxes to Enter key. When enter is pressed call the handling function and store which entry has a focus in a globally accessible variable like self.entry_focus in case you are buildng a class or just entry_focus which will be declared at the beginning of the script in the module scope level. When handling the event you can get info which widget called it by accessing event object which is being passed to the handler. Use event.widget and root.focus_get method for that.

</li> <li>

Bind Enter to the root item. Then use focus_get method to check where the focus is every time enter was pressed no matter where the mouse cursor or focus really is.

</li> </ol>

See the code in the post above. Everything will be clear.

Good luck!

来源:https://stackoverflow.com/questions/45237883/tkinter-check-which-entry-last-had-focus

Recommend

  • Excel formula to match multiple dates across 2 columns, returning Yes or No
  • Build project for Wix installer
  • Should I declare system call functions in C?
  • C++ standard input from file when debugging from IDE
  • XPATH: select subset of xml file
  • ThreadPoolExecutor: how to limit the queue maxsize?
  • Runtime exception when calling dll function with parameter in Inno Setup
  • How can i show text with html tag in primefaces
  • Java JIT loop unrolling policy?
  • How to style a Slider on Android with React Native
  • Missing “Run as JUnit Test”
  • Android - Playing Youtube Videos using Youtube Player API in ListView
  • cuBLAS cublasSgemv “Segmentation fault\"
  • Can't copy sqlite database from assets folder in Android
  • uploading images in codeigniter, is userfile required?
  • What is the common solution for multiple datasources?
  • React Native 'require' gotcha? Works for local image file, but not csv file in same direct
  • Inno Setup: Checking existence of a file in 32-bit System32 (Sysnative) folder
  • matplotlib and transparency figure
  • Identify File Type in Java
  • How to delete first 7 characters of folder name by using batch script?
  • mssql script data insert or update
  • jQuery colorbox breaks postbacks in ASP.NET Web Forms
  • Dynamically run java code with Process
  • Load php page results into div with ajax with link?
  • Allowing audio files in Spring MVC 3.0?
  • How to display converted time zones in a 'generic week' (Sunday thru Saturday)?
  • opencv deskewing a contour
  • time column in sqlite using gorm
  • How can i move Clearcase dyamic/snapshot views to another host (Linux)
  • Google Spreadsheet Script to Blink a range of Cells
  • Drag and drop unicode TText in DelphiXe4