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

Kivy问卷App整合ScrollView与DropDown时App.root无效实例错误解决

Kivy问卷App开发问题解决:Invalid instance in App.root错误

问题背景

本人具备Python和SQLite使用经验,目前正在学习Kivy框架并开发问卷App,用于提问并收集数据供后续处理。已通过YouTube教程分别掌握GridLayout、ScrollView、DropDown等组件用法,现尝试整合实现问卷功能,完整代码如下:

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.lang import Builder
from kivy.uix.scrollview import ScrollView
from kivy.core.window import Window

Builder.load_string("""
<CustomDropDown>
    Button:
        text: "1st item"
        size_hint_y: None
        height: 30
        on_release: root.select("1st item")
    Button:
        text: "2nd item"
        size_hint_y: None
        height: 30
        on_release: root.select("2nd item")
    Button:
        text: "3rd item"
        size_hint_y: None
        height: 30
        on_release: root.select("3rd item")
    Button:
        text: "4th item"
        size_hint_y: None
        height: 30
        on_release: root.select("4th item")
""")

class CustomDropDown(DropDown):
    pass

class QuestionnaireApp(App):

    def build(self):
        self.layout = GridLayout(cols = 1, spacing = 10, size_hint_y = None, padding = (200,50))
        self.layout.bind(minimum_height = self.layout.setter("height"))

        Window.clearcolor = (1,1,1,1)

        self.ttl = Label(text = "Title",
                          height = 50,
                          font_size = 24,
                          color = "black")
        self.layout.add_widget(self.ttl)

        self.code_ask = Label(text = "Code?", size_hint_y = None,
                              height = 30, color = "black")
        self.layout.add_widget(self.code_ask)

        self.code_in = TextInput(size_hint_y = None, height = 30)
        self.layout.add_widget(self.code_in)

        self.main = Button(text = "Select item", size_hint_y = None, height = 30)
        dropdown = CustomDropDown()
        self.main.bind(on_release = dropdown.open)
        dropdown.bind(on_select = self.select_text)

        self.click = Button(text = "Submit", size_hint_y = None, height = 30, on_release = self.submit)
        self.layout.add_widget(self.click)
        
        self.root = ScrollView(size_hint = (1, None), size = (Window.width, Window.height))
        self.root.add_widget(self.layout)

        return self.root, self.main
    
    def select_text(self, instance, x):
        self.main.text = x

    def submit(self, obj):
        teach_code = self.code_in.text

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

期望App运行后显示含标题、标签、文本输入框、下拉菜单、提交按钮的窗口并具备滚动功能,但运行时出现错误:

Exception has occurred: Exception
Invalid instance in App.root
  File "C:\...\try.py", line 79, in <module>
    QuestionnaireApp().run()
Exception: Invalid instance in App.root

单独使用ScrollView功能正常,移除滚动功能时仅显示下拉按钮,请问该如何解决?

错误原因分析

  1. App.build()返回值错误:Kivy要求build()方法只能返回一个Widget实例作为应用的根组件,当前代码返回了self.root(ScrollView)和self.main(下拉按钮)组成的元组,这直接触发了Invalid instance in App.root错误。
  2. 下拉按钮未添加到布局:self.main按钮没有被添加到GridLayout中,所以移除滚动功能返回self.main时,只会显示这个按钮,其他控件都无法在界面上展示。

修复后的完整代码

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.lang import Builder
from kivy.uix.scrollview import ScrollView
from kivy.core.window import Window

Builder.load_string("""
<CustomDropDown>
    Button:
        text: "1st item"
        size_hint_y: None
        height: 30
        on_release: root.select("1st item")
    Button:
        text: "2nd item"
        size_hint_y: None
        height: 30
        on_release: root.select("2nd item")
    Button:
        text: "3rd item"
        size_hint_y: None
        height: 30
        on_release: root.select("3rd item")
    Button:
        text: "4th item"
        size_hint_y: None
        height: 30
        on_release: root.select("4th item")
""")

class CustomDropDown(DropDown):
    pass

class QuestionnaireApp(App):

    def build(self):
        self.layout = GridLayout(cols = 1, spacing = 10, size_hint_y = None, padding = (200,50))
        self.layout.bind(minimum_height = self.layout.setter("height"))

        Window.clearcolor = (1,1,1,1)

        # 添加标题
        self.ttl = Label(text = "Title",
                          height = 50,
                          font_size = 24,
                          color = "black")
        self.layout.add_widget(self.ttl)

        # 添加代码输入相关控件
        self.code_ask = Label(text = "Code?", size_hint_y = None,
                              height = 30, color = "black")
        self.layout.add_widget(self.code_ask)

        self.code_in = TextInput(size_hint_y = None, height = 30)
        self.layout.add_widget(self.code_in)

        # 添加下拉按钮并绑定下拉菜单
        self.main = Button(text = "Select item", size_hint_y = None, height = 30)
        dropdown = CustomDropDown()
        self.main.bind(on_release = dropdown.open)
        dropdown.bind(on_select = self.select_text)
        # 将下拉按钮添加到布局中
        self.layout.add_widget(self.main)

        # 添加提交按钮
        self.click = Button(text = "Submit", size_hint_y = None, height = 30, on_release = self.submit)
        self.layout.add_widget(self.click)
        
        # 配置滚动视图
        self.root = ScrollView(size_hint = (1, 1))
        self.root.add_widget(self.layout)

        # 只返回滚动视图作为根组件
        return self.root
    
    def select_text(self, instance, x):
        self.main.text = x

    def submit(self, obj):
        teach_code = self.code_in.text
        # 可扩展为保存到SQLite的逻辑
        print(f"提交的代码: {teach_code}, 下拉选择项: {self.main.text}")

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

关键修改点

  • 修正返回值:build()方法仅返回self.root(ScrollView实例),符合Kivy对根组件的要求。
  • 添加下拉按钮到布局:调用self.layout.add_widget(self.main),让下拉按钮显示在界面的正确位置。
  • 优化ScrollView配置:将size_hint设置为(1,1),让滚动视图自动适配窗口大小,无需手动指定固定尺寸。
  • 补充提交逻辑示例:在submit方法中添加打印语句,方便测试数据收集功能,后续可扩展为SQLite存储逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:44:57