Tkinter自动补全原型GUI问题:按下空格键无法获取输入内容
Fixing Tkinter Entry Content Retrieval on Spacebar Press
Hey there! Let's work through why you're struggling to grab the full entry content when pressing the spacebar. The core issues in your code stem from reinitializing widgets and variables unnecessarily every time you press space, which breaks the link between your input field and the StringVar used to track its content. Here's how to fix it:
Key Issues in Your Original Code
- Re-creating widgets/StringVar on space press: Your
kpfunction callscreate_widgets(1), which reinitializesself.search_vareach time. This new variable isn't bound to the original entry widget, soself.search_var.get()can't pull the real input content. - Unnecessary widget reconstruction: You don't need to rebuild the listbox or entry every time you want to update the list—just refresh the listbox's content instead.
Modified Working Code
import random from tkinter import * def getFromScript(text): # Placeholder for your actual implementation i = random.randint(1, 100) return ['hello'+str(i), 'helou'+text] class Application(Frame): def __init__(self, master=None): Frame.__init__(self, master) self.pack() # Initialize StringVar once here, not in create_widgets self.search_var = StringVar() self.create_widgets() # Bind StringVar changes to update the initial static list self.search_var.trace("w", lambda name, index, mode: self.update_list(0)) def create_widgets(self): # Create entry and listbox ONCE, store as instance attributes self.entry = Entry(self, textvariable=self.search_var, width=13) self.entry.grid(row=0, column=0, padx=10, pady=3) self.lbox = Listbox(self, width=45, height=15) self.lbox.grid(row=1, column=0, padx=10, pady=3) # Populate the initial list self.update_list(0) def update_list(self, mode): # Get the current entry content directly (either entry.get() or search_var.get() works) search_term = self.entry.get() # Load appropriate list based on mode if mode == 0: lbox_list = ['Excellent', 'Very Good', 'Shabby', 'Unpolite'] else: lbox_list = getFromScript(search_term) # Clear and repopulate the listbox self.lbox.delete(0, END) for item in lbox_list: if search_term.lower() in item.lower(): self.lbox.insert(END, item) def kp(event): # Trigger the dynamic list update when space is pressed app.update_list(1) # Optional: Prevent space from being added to the entry field return "break" root = Tk() root.title('Filter Listbox Test') # Bind space to root instead of bind_all to avoid affecting other widgets root.bind('<space>', kp) app = Application(master=root) app.mainloop()
What Changed & Why
- Moved initialization to
__init__: Thesearch_var, entry, and listbox are now created once when the app starts. This keeps the entry and its tracking variable linked permanently. - Simplified
create_widgets: This method now only sets up the UI layout once, no conditional re-creation. - Updated
kpfunction: Instead of rebuilding widgets, it directly callsupdate_list(1)to refresh the listbox with dynamic content fromgetFromScript, using the current entry text. - Optional
return "break": This stops the space character from being inserted into the entry. Remove this line if you want spaces to appear in your input while still triggering the update. - Direct entry content access: Using
self.entry.get()makes it explicit that we're grabbing the real input content, thoughself.search_var.get()would work too since they're bound.
Now when you type in the entry and press space, the full input content will be passed to getFromScript, and the listbox will update with your dynamic results!
内容的提问来源于stack exchange,提问作者a_parida
相关产品推荐
相关产品推荐

