You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kivy开发中如何获取动态添加的TextInput等控件的内容

解决方案

Kivy的ids字典是kv文件解析阶段自动生成的,仅收录kv语法中明确定义了id:属性的控件,Python代码动态添加的控件不会自动录入该字典,也没必要强行往ids里塞,自己维护独立的控件引用存储即可,实现成本很低。

具体修改逻辑

  • 在布局类初始化时新增独立存储结构,专门存动态生成的输入控件,推荐用嵌套列表/字典按人员序号分组,避免和kv原生生成的id混淆。
  • 动态创建TextInput控件时,把生成的控件对象存入上述存储结构,不要丢失控件引用。
  • 后续需要读取输入内容时,直接遍历存储结构,取对应控件的text属性即可。
  • 可选优化:每次生成新的人员输入项前,先清空之前动态添加的控件和旧引用,避免用户重复触发生成时页面堆积冗余控件。

修改后的可运行代码

Python部分

import sys, os, pyautogui
from kivy.app import App
from kivy.resources import resource_add_path
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput

class MeuLayout(ScrollView):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # 独立存储动态生成的人员输入控件,格式:[{字段名: 输入框对象}, ...]
        self.dynamic_inputs = []

    def criar_pessoa(self, numero):
        # 清空之前生成的动态控件:kv中固定写死的grid直接子节点共8个,仅删除索引8之后的动态内容
        while len(self.ids.grid.children) > 8:
            child = self.ids.grid.children[8]
            self.ids.grid.remove_widget(child)
        self.dynamic_inputs.clear()

        if numero.isnumeric():
            if int(numero) > 20:
                pyautogui.alert('Excedeu o valor limite!')
            else:
                person_count = int(numero)
                for i in range(1, person_count+1):
                    # 添加字段标签
                    self.ids.grid.add_widget(Label(text= f'Nome da {i}° pessoa:', size_hint_y= None, height= 100))
                    self.ids.grid.add_widget(Label(text=f'Sobrenome da {i}° pessoa:', size_hint_y=None, height=100))
                    # 创建姓名输入框
                    nome_input = TextInput(write_tab= False, multiline=False, size_hint_y=None, height=30)
                    self.ids.grid.add_widget(nome_input)
                    sobrenome_input = TextInput(write_tab= False,multiline=False, size_hint_y=None, height=30)
                    self.ids.grid.add_widget(sobrenome_input)
                    # 添加联系方式标签
                    self.ids.grid.add_widget(Label(text=f'Email da {i}° pessoa:', size_hint_y=None, height=100))
                    self.ids.grid.add_widget(Label(text=f'Telefone da {i}° pessoa:', size_hint_y=None, height=100))
                    # 创建联系方式输入框
                    email_input = TextInput(write_tab= False,multiline=False, size_hint_y=None, height=30)
                    self.ids.grid.add_widget(email_input)
                    telefone_input = TextInput(write_tab= False,multiline=False, size_hint_y=None, height=30)
                    self.ids.grid.add_widget(telefone_input)
                    # 添加分割线
                    self.ids.grid.add_widget(Label(text='___________________________________________________________', size_hint_y=None, height=100))
                    self.ids.grid.add_widget(Label(text='___________________________________________________________', size_hint_y=None, height=100))

                    # 将当前人员的所有输入框存入结构
                    self.dynamic_inputs.append({
                        'nome': nome_input,
                        'sobrenome': sobrenome_input,
                        'email': email_input,
                        'telefone': telefone_input
                    })
        else:
            pyautogui.alert('Coloque apenas números!')
        self.ids.numero_pessoas.text = ''

    # 示例:读取所有动态输入框的值
    def get_all_data(self):
        res = []
        for person in self.dynamic_inputs:
            res.append({
                'nome': person['nome'].text,
                'sobrenome': person['sobrenome'].text,
                'email': person['email'].text,
                'telefone': person['telefone'].text
            })
        # 此处可替换为后续数据处理逻辑
        print(res)
        return res

class AppCadastro(App):
    def build(self):
        return MeuLayout()


if __name__ == '__main__':
    if hasattr(sys, '_MEIPASS'):
        resource_add_path(os.path.join(sys._MEIPASS))
    AppCadastro().run()

KV部分

原有KV代码无需改动,如果需要触发数据读取,可在GridLayout末尾新增提交按钮绑定上述方法:

Button:
    text: '提交信息'
    size_hint_y: None
    height: 50
    on_press: root.get_all_data()
Label:
    size_hint_y: None
    height: 100

补充说明

如果习惯用id访问的形式,也可以在创建控件后手动将对象塞入self.ids字典,例如self.ids[f'nome_{i}'] = nome_input,后续可通过self.ids['nome_1'].text的形式取值。但这种方式会将动态id和kv原生id混在同一字典中,项目规模变大后容易出现命名冲突,单独维护存储结构的可维护性更高。


内容的提问来源于stack exchange,提问作者Marckson Assis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:01:10