AttributeError: 'NoneType' object has no attribute 'ids', in kivymd

AttributeError: 'NoneType' object has no attribute 'ids', in kivymd

我在 kivymd 中创建了一个简单的 MDfieldwidget 我试图引用文本但是我得到了一个 AttributeError: 'NoneType' object has no attribute 'ids', 这是我的 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

您的代码有几个问题:

  • 您正试图在用户有机会将文本输入 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