Kivy中如何访问GridLayout内动态创建的TextInput内容
Hey there! No worries at all being new to Kivy/Python—we’ve all been there. Let’s break down how to fix your issue with getting text from those dynamically generated TextInputs.
The Core Problem
Your current code runs into two main issues:
- Variable Overdue in Loops: The
testtextfunction you define inside the loop doesn’t capture the currentextimeinstance—it ends up referencing the last one created because of how Python handles closures in loops. - Duplicate Widgets: Every time you enter the
EditWorkoutScreen,setupscreen()adds a new set of widgets without clearing the old ones, which will get messy fast.
Fixes & Modified Code
Here’s how to adjust your EditWorkoutScreen class to solve both problems, plus add a way to get all input values at once:
class EditWorkoutScreen(Screen): def setupscreen(self): global exercisedf # Clear existing widgets first to avoid duplicates on screen re-entry self.ids.exercisestoverify.clear_widgets() for index, row in exercisedf.iterrows(): grid = GridLayout(rows=1, spacing=2) exname = Label(text=str(row.exercise)) exfocus = Label(text=str(row.focus)) exequip = Label(text=str(row.equip)) extime = TextInput(text=str(row.deftime), size_hint=(None,None), size=(25,30),font_size=11, multiline=False) # Add a custom attribute to link the TextInput to its exercise extime.exercise_name = row.exercise # Define a callback that uses the TextInput instance directly def on_text_validate(instance): print(f"Exercise: {instance.exercise_name}, Updated Time: {instance.text}") extime.bind(on_text_validate=on_text_validate) grid.add_widget(exname) grid.add_widget(exfocus) grid.add_widget(exequip) grid.add_widget(extime) self.ids.exercisestoverify.add_widget(grid) # Optional: Get all updated workout times at once def collect_all_times(self): workout_data = {} # Loop through each GridLayout in the ScrollView for grid in self.ids.exercisestoverify.children: # Find the TextInput in each GridLayout for widget in grid.children: if isinstance(widget, TextInput): workout_data[widget.exercise_name] = widget.text break print("All workout times:", workout_data) return workout_data
Key Changes Explained
- Clear Existing Widgets:
self.ids.exercisestoverify.clear_widgets()ensures you don’t stack duplicate training rows every time you open the screen. - Custom Attribute for Linking: Adding
extime.exercise_name = row.exerciseties each TextInput directly to its corresponding exercise, so you always know which input belongs to which workout. - Instance-Based Callback: The
on_text_validatefunction takes theinstanceparameter (the TextInput that triggered the event), so it always accesses the correct input’s text and linked exercise name—no more variable overlap.
Add a Button to Collect All Values
To use the collect_all_times function, add a button to your EditWorkoutScreen in the .kv file:
<EditWorkoutScreen>: name:'editworkout' on_enter: root.setupscreen() FloatLayout: Label: text: 'Verify/Edit Workout' pos: 0, 550 font_size: 20 Button: text: 'Save All Times' size_hint: .2, .1 pos_hint: {"x":.4, "y":.05} on_release: root.collect_all_times() ScrollView: pos_hint: {"x":.160, "y":-.15} GridLayout: id: exercisestoverify size_hint_y: None size_hint_x: .80 orientation: "vertical" height: self.minimum_height row_default_height: 30 spacing: 0 cols:1
This setup will let you either get individual input values when the user presses Enter on a TextInput, or collect all updated times at once with the button.
内容的提问来源于stack exchange,提问作者TKuam
相关产品推荐
相关产品推荐

