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

Kivy/KivyMD弹窗文本框输入获取与按钮触发函数的问题求助

Kivy/KivyMD弹窗文本框输入获取与按钮触发函数的问题求助

嘿,别慌!刚上手Kivy/KivyMD遇到这种控件引用的问题太正常了,我帮你捋清楚问题,然后一步步搞定它~

问题根源

你现在的get_user_input函数里,尝试通过self.root.ids.my_textfield_1.ids.user.text获取文本框内容,但这里有个关键误区:你用Factory.novy_test().open()创建的弹窗是独立于主屏幕testy的临时控件,它不会被加入到主屏幕的ids集合里,所以代码找不到这个弹窗实例,自然拿不到输入内容。

两种简单解决办法

办法一:直接在按钮点击时传递文本内容(最直观)

这种方法不用绕弯子,直接把文本框的内容传给get_user_input函数:

  1. 修改test.kv里的Štart按钮代码:
MDFlatButton:
    text: 'Štart'
    pos_hint: {'center_x': .5}
    # 直接把文本框的内容作为参数传给app的方法
    on_press: app.get_user_input(user.text)
  1. 修改main.py里的get_user_input函数:
def get_user_input(self, input_text):
    # 直接打印传入的文本内容
    print(input_text)

办法二:保存弹窗实例,通过实例获取内容(适合需要操作弹窗其他控件的场景)

如果之后你需要对弹窗做更多操作(比如关闭弹窗、修改其他控件),可以用这种方式:

  1. 在main.py的Test类里添加一个属性保存弹窗实例,再写一个打开弹窗的方法:
class Test(MDApp):
    Window.size = (1170 / 3, 2532 / 3)
    # 添加属性保存当前弹窗实例
    current_popup = None

    def build(self):
        self.theme_cls.material_style = "M3"
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = 'Gray'
        return testy()

    # 新增打开弹窗的方法,保存实例
    def open_novy_test(self):
        self.current_popup = Factory.novy_test()
        self.current_popup.open()

    def get_user_input(self):
        # 检查弹窗实例是否存在,然后获取文本内容
        if self.current_popup:
            print(self.current_popup.ids.user.text)
  1. 修改test.kv里的顶部导航栏按钮事件:
left_action_items: [["car", lambda x: app.open_novy_test(), '',"Nový test"]]

额外小提示

  • 你代码里testy类的novy_test = ObjectProperty()没有用到,可以删掉,避免冗余。
  • 如果CustomOverFlowMenu类没有自定义逻辑,也可以直接用默认的MDDropdownMenu,简化代码。

修改后的完整代码参考

main.py

from kivy.core.window import Window
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen, ScreenManager
from kivymd.uix.menu import MDDropdownMenu
from kivymd.uix.textfield import MDTextField
from kivy.properties import StringProperty

class testy(Screen):
    # 删掉没用的ObjectProperty
    pass

class Test(MDApp):
    Window.size = (1170 / 3, 2532 / 3)
    current_popup = None

    def build(self):
        self.theme_cls.material_style = "M3"
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = 'Gray'
        return testy()

    def open_novy_test(self):
        self.current_popup = Factory.novy_test()
        self.current_popup.open()

    def get_user_input(self):
        if self.current_popup:
            print(self.current_popup.ids.user.text)

    def callback(self, button):
        pass

class CustomOverFlowMenu(MDDropdownMenu):
    # 这里可以保留自定义逻辑,没有的话也可以删掉这个类
    pass

Test().run()

test.kv

#:import Factory kivy.factory.Factory
#:import CustomOverFlowMenu __main__.CustomOverFlowMenu

<testy>:
    name:'testy'
    id: testy

    MDBoxLayout:
        orientation: "vertical"

        MDTopAppBar:
            title: "MDTopAppBar"
            use_overflow: True
            overflow_cls: CustomOverFlowMenu()
            specific_text_color: .51,.51,.51,1
            md_bg_color: 0, 0, 0, 1
            left_action_items: [["car", lambda x: app.open_novy_test(), '',"Nový test"]]

        MDBottomNavigation:
            panel_color: "black"
            selected_color_background: "white"
            text_color_active: "lightgray"
            selected_color_background: 1, 1, 1, .4

            MDBottomNavigationItem:
                name: 'screen 1'
                text: 'Testy'
                icon: 'road-variant'

                MDLabel:
                    text: 'Test'
                    halign: 'center'

            MDBottomNavigationItem:
                name: 'screen 2'
                text: 'chyby'
                icon: 'alert-circle'

                MDLabel:
                    text: 'Chyby'
                    halign: 'center'

            MDBottomNavigationItem:
                name: 'screen 3'
                text: 'Settings'
                icon: 'cog'

                MDLabel:
                    text: 'LinkedIN'
                    halign: 'center'

<novy_test@Popup>:
    id:my_textfield_1
    size_hint: .8, .45
    title: 'Nový test'
    separator_color: 'black'
    title_align: 'center'

    BoxLayout:
        id: layout
        spacing: 10
        orientation:'vertical'

        MDTextField:
            id: user
            hint_text: "Číslo testu"
            mode: "round"
            pos_hint: {"top": 1}

        MDFlatButton:
            text: 'Štart'
            pos_hint: {'center_x': .5}
            on_press: app.get_user_input()

        MDFlatButton:
            pos_hint: {'center_x': .5}
            text:'test z nesprávnych'

        MDFlatButton:
            text:'test z neurobených'
            pos_hint: {'center_x': .5}

        MDFlatButton:
            text:'test z neurobených'
            pos_hint: {'center_x': .5}

        MDFlatButton:
            text:'test z neurobených'
            pos_hint: {'center_x': .5}

备注:内容来源于stack exchange,提问作者zochy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 07:13:14