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

Kivy调用DropDown.open报已存在父对象错误及代码简化问题咨询

问题解答

初始报错原因

你在KV文件中将DropDown组件直接声明为CustomDropDown的子控件,而DropDown.open()方法执行时会自动将下拉列表挂载到全局窗口根节点上,此时DropDown实例已经存在父级(即你声明的CustomDropDown),因此抛出了无法重复添加到窗口的错误。

最简实现方案

无需额外子类化DropDown和选项控件,直接通过事件绑定即可实现需求,完整代码如下:

main.py

import kivy
kivy.require('2.0.0')

from kivy.app import App
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.dropdown import DropDown
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput


class CustomDropDown(TextInput):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # 直接创建DropDown实例,不作为自身子控件
        self.dropdown = DropDown()
        # 批量生成选项
        for opt in ['Option 1', 'Option 2', 'Option 3']:
            item = Label(text=opt, size_hint_y=None, height=30)
            # 绑定点击事件,选中后更新输入框内容并关闭下拉
            item.bind(on_touch_down=lambda touch, item=item: self._select_item(item, touch))
            self.dropdown.add_widget(item)
        # 绑定下拉选中事件同步输入框内容
        self.dropdown.bind(on_select=lambda instance, x: setattr(self, 'text', x))

    def _select_item(self, item, touch):
        if item.collide_point(*touch.pos):
            self.dropdown.select(item.text)
            return True
        return False

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            self.dropdown.open(self)
            # 阻止默认事件避免触发输入框光标跳转
            return True
        return super().on_touch_down(touch)


class MainApp(AnchorLayout):
    pass


class MyApp(App):
    def build(self):
        return MainApp()


if __name__ == '__main__':
    MyApp().run()

my.kv

<MainApp>:
    CustomDropDown:
        text: 'Select an option..'
        size_hint_y: None
        height: 30

仅保留CustomDropDown一个子类即可实现全部需求,代码量大幅降低,逻辑也更清晰。

内容的提问来源于stack exchange,提问作者Hannes Ziegler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 10:24:01