【问题标题】:AttributeError: 'NoneType' object has no attribute 'ids', in kivymdAttributeError: 'NoneType' 对象在 kivymd 中没有属性 'ids'
【发布时间】:2021-08-18 10:03:24
【问题描述】:

我创建了一个简单的 MDfieldwidget 我试图引用文本但我得到一个 AttributeError: 'NoneType' object has no attribute 'ids', in kivymd 这是我的 main.py 文件(提前感谢您的帮助)

from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen, ScreenManager


class LoginScreen(Screen):
    pass


class SecondScreen(Screen):
    pass


class LoginApp(MDApp):
    def build(self):

        users_name = self.root.ids.users_name
        my_label = self.root.ids.my_label
        my_label.text = users_name.text

        sm = ScreenManager()
        sm.add_widget(LoginScreen(name='Screen1'))
        sm.add_widget(SecondScreen(name='Screen2'))

        return sm


LoginApp().run()

这是我的 .kv 文件

<LoginScreen>
    MDScreen:
        name: 'Screen1'
        md_bg_color: (23/255, 31/255, 40/255, 1)

        MDCard:
            size_hint: None, None
            size: 320, 400
            pos_hint: {"center_x": .5, "center_y": .5}
            orientation: 'vertical'
            padding: '8dp'
            md_bg_color: (23/255, 31/255, 47/255, 1)
            elevation: 10
            spacing: 10

            MDLabel:
                text: 'LOGIN'
                font_style: 'Button'
                font_size: 45
                halign: 'center'
                size_hint_y: None
                height: self.texture_size[1]
                theme_text_color: 'Custom'
                text_color: (1, 1, 1, 1)
                padding_y: 15

            MDTextFieldRound:
                hint_text: 'enter username'
                icon_right: 'account'
                color_active: 1, 1, 1, 1
                pos_hint: {"center_x":.5}
                size_hint_x: None
                width: 220
                font_size: 16

            # MDSeparator:
            #         height: "1dp"

            MDTextFieldRound:
                hint_text: 'enter password'
                icon_right: 'eye-off'
                color_active: 1, 1, 1, 1
                size_hint_x: None
                width: 210
                font_size: 15
                pos_hint: {"center_x": .5}
                password: True

            MDTextField:
                id: users_name
                hint_text: "What's your name?"
                helper_text: "What your friends call you.."
                helper_text_mode: "on_focus"
                pos_hint: {"center_x": .5}
                size_hint_x: None
                width: 200

            MDRectangleFlatButton:
                text: 'LOGIN'
                pos_hint: {'center_x': .5}
                size_hint_x: None
                root_button_anim: True
                on_press:
                    # change direction to to non-movable
                    root.manager.transition.direction = 'left'
                    root.manager.current = 'Screen2'
        
            Widget:
                pos_hint_y: None
                height: 30


<SecondScreen>
    MDScreen:
        md_bg_color: (23/255, 31/255, 40/255, 1)
        name: 'Screen2'
        MDCard:
            md_bg_color: (23/255, 31/255, 47/255, 1)
            padding: 10
            elevation: 10
            orientation: 'vertical'
            spacing: 25
            pos_hint: {'center_x': .5, "center_y": .5}
            size_hint: None, None
            size: 340, 400

            MDTextButton:
                text: '< Back'
                padding_x: 0
                custom_color: (244/255, 246/255, 214/255, 1)
                pos_hint: {"center_y": .1}
                root_button_anim: True
                on_press:
                    # change direction to to non-movable
                    root.manager.transition.direction = 'right'
                    root.manager.current = 'Screen1'

            MDLabel:
                id: my_label
                text: f'Hello {my_label.text}'
                # halign: 'center'
                pos_hint: {'center_x': .5}
                size_hint_y: None
                font_style: 'Body1'
                theme_text_color: 'Custom'
                text_color: (1, 1, 1, 1)

                font_size: 20
                height: self.texture_size[1]
                padding_y: 15

            Widget:
                height: 10

【问题讨论】:

    标签: python kivy kivymd


    【解决方案1】:

    你的代码有几个问题:

    • 您正试图在用户有机会在MDTextField 中输入文本之前将文本从MDTextField 复制到MDLabel。此外,ids 尚未在 build() 方法中分配。
    • 您正在尝试使用self.root 访问ids,即ScreenManager,但ids 是在LoginScreenSecondScreen 中定义的。请参阅documentation

    您可以通过在用户输入名称时进行名称复制以及正确使用ids 来解决这些问题。在您的kv 中,使用text 属性触发复制:

            MDTextField:
                id: users_name
                hint_text: "What's your name?"
                helper_text: "What your friends call you.."
                helper_text_mode: "on_focus"
                pos_hint: {"center_x": .5}
                size_hint_x: None
                width: 200
                on_text: app.set_user_name(self.text)
    

    然后将set_user_name()方法添加到App

    def set_user_name(self, name):
        my_label = self.root.get_screen('Screen2').ids.my_label
        my_label.text = name
    

    当然,从build() 中删除这些行:

        users_name = self.root.ids.users_name
        my_label = self.root.ids.my_label
        my_label.text = users_name.text
    

    另一种方法,如果您不想删除 MDLabel 中已有的文本,则使用 MDRectangleFlatButton 作为触发器。在这种情况下,MDTextField 的 kv 变为:

            MDTextField:
                id: users_name
                hint_text: "What's your name?"
                helper_text: "What your friends call you.."
                helper_text_mode: "on_focus"
                pos_hint: {"center_x": .5}
                size_hint_x: None
                width: 200
    

    这是您的原始代码。将set_user_name()方法的触发器添加到Button

            MDRectangleFlatButton:
                text: 'LOGIN'
                pos_hint: {'center_x': .5}
                size_hint_x: None
                root_button_anim: True
                on_press:
                    # change direction to to non-movable
                    root.manager.transition.direction = 'left'
                    root.manager.current = 'Screen2'
                    app.set_user_name(users_name.text)  # trigger name copy
    

    并且set_user_name()方法必须调整为:

    def set_user_name(self, name):
        my_label = self.root.get_screen('Screen2').ids.my_label
        my_label.text += name  # append name rather than over-write
    

    【讨论】:

    • 非常感谢它的工作。但是它有一个问题,当它显示在第二个屏幕上时,删除它之前的单词。
    • 这是我的 MDLabel 代码:id: my_label **text: f'Hello {my_label.text}' pos_hint: {'center_x': .5} size_hint_y: 无 font_style: 'Body1' theme_text_color: '自定义' text_color: (1, 1, 1, 1) ...所以我的意思是它不会沿着用户输入打印你好。请问我该如何解决这个问题..提前谢谢你
    • 非常感谢,现在很好。如果你能推荐资源让我理解这个概念,我会很高兴。谢谢,感谢所有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    • 2020-09-05
    • 2019-01-01
    相关资源
    最近更新 更多