【问题标题】:'super' object has no attribute '__getattr__' kivy [closed]'super' 对象没有属性 '__getattr__' kivy [关闭]
【发布时间】:2019-07-17 19:12:33
【问题描述】:

我正在使用 kivy 和 socket 编写一个聊天应用程序。但是,每当我的应用收到一条消息时,我总会收到一个 AttributeError:'super' object has no attribute '__getattr__'。

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivymd.dialog import MDDialog
from kivymd.theming import ThemeManager
from kivymd.navigationdrawer import NavigationLayout
from kivymd.list import OneLineAvatarListItem, ILeftBody
from kivymd.toast import toast
from kivymd.dialog import MDDialog
from kivy.uix.popup import Popup
from threading import Thread

import socket


sock = socket.socket()
sock.connect(('127.0.0.1', 6718))
sock.sendall(b"add_contact hello llo")

sock = socket.socket()
sock.connect(('127.0.0.1', 6718))

sock.sendall(b'new llo')


class MyLayout(BoxLayout):
    scr_mngr = ObjectProperty(None)

    def check_data_login(self):
        username = self.scr_mngr.screen1.username.text
        password = self.scr_mngr.screen1.password.text

        print(username)
        print(password)
        if username == "KivyMD" and password == "kivy":
            self.ids["wrongpass"].text = ""
            self.change_screen("screen2")
        else:
            self.ids["wrongpass"].text = "Wrong username or password, please try again"

    def change_screen(self, screen, *args):
        self.scr_mngr.transition.direction = 'left'
        self.scr_mngr.current = screen

    def back_to_chat(self):
        self.scr_mngr.transition.direction = 'right'
        self.scr_mngr.current = 'screen2'


class nav_layout(NavigationLayout):
    def print_text(self):
        print('hello')

    def check_data_login(self):
        username = self.ids.screen1.username.text
        password = self.ids.screen1.password.text

        print(username)
        print(password)
        if username == "KivyMD" and password == "kivy":
            self.change_screen("screen2")
            self.ids.wrongpass.text = ""
        else:
            self.ids.wrongpass.text = \
                "Wrong username or password, please try again"

    def change_screen(self, screen, *args):
        self.ids.scr_mngr.transition.direction = 'left'
        self.ids.scr_mngr.current = screen

    def back_to_chat(self):
        self.ids.scr_mngr.transition.direction = 'right'
        self.ids.scr_mngr.current = 'screen2'

    def logout(self):
        # logout function, returns to screen 1
        self.ids.scr_mngr.current = 'screen1'
    def oof(self, data):
        self.ids.Chat_String.text = data
class UploadPopup(Popup):
    def load(self, path, selection):
        print(path, selection) 


KV = """
#:import Toolbar kivymd.toolbar.Toolbar
#:import MDNavigationDrawer kivymd.navigationdrawer.MDNavigationDrawer
#:import NavigationLayout kivymd.navigationdrawer.NavigationLayout
#:import NavigationDrawerDivider kivymd.navigationdrawer.NavigationDrawerDivider
#:import NavigationDrawerToolbar kivymd.navigationdrawer.NavigationDrawerToolbar
#:import MDTextField kivymd.textfields.MDTextField
#:import MDSeparator kivymd.card.MDSeparator
#:import MDThemePicker kivymd.theme_picker.MDThemePicker
#:import CardTransition kivy.uix.screenmanager.CardTransition
#:import Factory kivy.factory.Factory


<MDCustomIconItem>:
    text: root.text

    AvatarSampleWidget:
        source: root.icon

<UploadPopup>:
    id: popup
    title: "Upload"
    BoxLayout:
        FileChooserIconView:
            id: FileChoose
            pos_hint_x: 0.5
            pos_hint_y: 0.5
            on_selection: root.load(FileChoose.path, FileChoose.selection)
        MDRaisedButton:
            text: "Upload"
            text_color: (0,0,0,1)
            on_release: root.load(FileChoose.path, FileChoose.selection)
            on_release: popup.dismiss()

        MDRaisedButton:
            text: "Close"
            text_color: (0,0,0,1)
            on_release: popup.dismiss()


nav_layout:
    id: nav_layout
    MDNavigationDrawer:
        id: nav_drawer
        drawer_logo: 'logo.png'
        NavigationDrawerToolbar:
            title: 'hello'
        NavigationDrawerIconButton:
            icon: 'settings'
            text: 'Account Settings'
            on_release: root.change_screen('screen3')
        NavigationDrawerIconButton:
            icon: 'face'
            text: 'Friends'
            on_release: root.print_text()
        NavigationDrawerIconButton:
            icon: 'logout'
            text: 'Logout'
            on_release: root.logout()
        NavigationDrawerDivider:
            height: dp(1)
    MyLayout:
        scr_mngr: scr_mngr
        orientation: 'vertical'


        ScreenManager:

            transition: CardTransition()
            id: scr_mngr
            screen1: screen1

            Screen:
                id: screen1
                name: 'screen1'
                username: username
                password: password

                BoxLayout:
                    size_hint: None, None
                    size: dp(520), dp(340)
                    pos_hint: {'center_x': 0.5, 'center_y': 0.5}

                    BoxLayout:
                        orientation:'vertical'
                        padding: dp(20)
                        spacing:20

                        MDLabel:
                            text: 'Chat App'
                            theme_text_color: 'Secondary'
                            font_style:"Title"
                            size_hint_y: None
                            height: dp(36)

                        MDSeparator:
                            height: dp(1)

                        MDTextField:
                            id: username
                            hint_text: "Username "
                            size_hint_y: 0.9
                            helper_text_mode: "on_focus"

                        MDTextField:
                            id: password
                            hint_text: "Password "
                            helper_text_mode: "on_focus"
                            size_hint_y: 0.9
                            password: True

                        MDFlatButton:
                            text: "Login"
                            pos_hint: {'center_x': 0.5}
                            on_release: root.check_data_login()

                        MDLabel:
                            id: wrongpass
                            color: 1,0,1,1
                            text: ""



            Screen:
                name: 'screen2'
                id: screen2

                Toolbar:
                    id: toolbar
                    title: "Welcome ! "
                    pos_hint: {'center_x': 0.5, 'center_y': 0.96}
                    md_bg_color: app.theme_cls.primary_color
                    background_palette: 'DeepPurple'
                    background_hue: 'A400'
                    left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer() ]]
                    right_action_items: [['animation', lambda x: MDThemePicker().open()], ['camera', lambda x: print('hello')]]

                MDLabel:
                    font_style: 'Title'
                    theme_text_color: 'Primary'
                    text: "Data :"
                    height: self.texture_size[1] + dp(3)
                    halign: 'center'
                    pos_hint: {'center_x': 0.5, 'center_y': 0.5}



            Screen:
                name: 'screen3'
                id: 'screen3'

                Toolbar:
                    id: tools
                    title: "Your Profile"
                    pos_hint: {'center_x': 0.5, 'center_y': 0.96}
                    md_bg_color: app.theme_cls.primary_color
                    background_palette: 'DeepPurple'
                    background_hue: 'A400'
                    left_action_items: [['arrow-left', lambda x: root.back_to_chat()]]
                MDLabel:
                    id: 'Profile_String'
                    font_size: 90
                    text: "XXX"
                    halign: 'center'
                    pos_hint: {'center_x': 0.5, 'center_y': 0.85}

            Screen:
                name: 'screen4'
                id: 'screen4'

                Toolbar:
                    id: tools
                    title: "XXX"
                    pos_hint: {'center_x': 0.5, 'center_y': 0.96}
                    md_bg_color: app.theme_cls.primary_color
                    background_palette: 'DeepPurple'
                    background_hue: 'A400'
                    left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer() ]]
                    right_action_items: [['animation', lambda x: MDThemePicker().open()], ['camera', lambda x: print('hello')]]
                ScrollView:
                    pos_hint: {'center_x': .55, 'y': .35}
                    MDLabel:
                        id: 'Chat_String'
                        font_size: 40
                        text: "XXX"


                MDTextField:
                    id: 'Input_String'
                    hint_text: 'Enter Your Message...'
                    helper_text_mode: 'on_focus'
                    pos_hint: {'center_x': 0.35, 'center_y': 0.2}
                    size_hint_x: 0.6
                    multiline: True


                MDRaisedButton:
                    id: 'Send_Button'
                    text: 'Send'
                    pos_hint: {'center_x': 0.75, 'center_y': 0.2}

                MDRaisedButton:
                    id: 'Choose_Image'
                    text: 'Attach File'
                    pos_hint: {'center_x': 0.9, 'center_y': 0.2}
                    on_release: Factory.UploadPopup().open()
"""


class MDCustomIconItem(OneLineAvatarListItem):
    icon = StringProperty('')
    text = StringProperty()

    def _set_active(self, active, list):
        pass


class AvatarSampleWidget(ILeftBody, Image):
    pass


class MyApp(App):
    theme_cls = ThemeManager()
    theme_cls.primary_palette = 'Blue'
    title = "Navigation Drawer"
    main_widget = None
    def __getattr__(self, attr):
        return super().__getattr__(attr)
    def build(self):
        self.main_widget = Builder.load_string(KV)
        return self.main_widget

    def callback(self, instance, value):
        self.main_widget.ids.scr_mngr.current = 'screen4'

    def recover_data(self):
        print('started')
        while True:
            data = sock.recv(1024)
            data = data.decode()
            if data:
                print(data)
                data = data.split()
                data = data[-1] + ": " + ' '.join(data[:-1])
                r = data + '\n'
                open('chat1.txt', 'a+').write(r)
                e = open('chat1.txt', 'r').readlines()
                nav_layout().oof('\n\r'.join(e))
                print(data)

    def on_start(self):
        Thread(target=self.recover_data).start()
        for i in range(15):
            self.main_widget.ids.nav_drawer.add_widget(
                MDCustomIconItem(
                    text="Item menu %d" % i,
                    icon='logo.png',
                    on_release=lambda x, y=i: self.callback(x, y)))


MyApp().run()

我知道这个问题之前在 StackOverflow 上被问过多次,但没有一个能解决我的问题。
任何帮助将不胜感激,谢谢!

**编辑:**我的完整错误信息在这里

Exception has occurred: AttributeError
'super' object has no attribute '__getattr__'
  File "/Users/grace/Desktop/Android_APP/kivy/properties.pyx", line 841, in kivy.properties.ObservableDict.__getattr__
  File "/Users/grace/Desktop/Android_APP/app.py", line 81, in oof
    self.ids.Chat_String.text = data
  File "/Users/grace/Desktop/Android_APP/app.py", line 334, in recover_data
    nav_layout().oof('\n\r'.join(e))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 869, in run
    del self._target, self._args, self._kwargs
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 885, in _bootstrap
    self._bootstrap_inner()

【问题讨论】:

  • 你为什么有那个__getattr__?没有可委托给超类__getattr__ 的方法,也没有理由编写一个仅委托给超类方法的方法,即使超类方法存在。
  • 请将完整的错误回溯添加到您的问题中。
  • 错字:ID 不是字符串,所以将:id: 'foo' 更改为 id: foo

标签: python python-3.x kivy kivy-language python-sockets


【解决方案1】:

原因

错误是由于在 kv 文件中将字符串值分配给 id

解决方案

从 kv 文件中的所有 id 中删除单引号。

Kv Language » Referencing Widgets

为 id 赋值时,请记住该值不是字符串。 没有引号:good -> id: value, bad -> id: 'value'

示例

main.py

​​>
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivymd.dialog import MDDialog
from kivymd.theming import ThemeManager
from kivymd.navigationdrawer import NavigationLayout
from kivymd.list import OneLineAvatarListItem, ILeftBody
# from kivymd.toast import toast
from kivymd.dialog import MDDialog
from kivy.uix.popup import Popup
from threading import Thread

import socket


# sock = socket.socket()
# sock.connect(('127.0.0.1', 6718))
# sock.sendall(b"add_contact hello llo")
#
# sock = socket.socket()
# sock.connect(('127.0.0.1', 6718))
#
# sock.sendall(b'new llo')


class MyLayout(BoxLayout):
    scr_mngr = ObjectProperty(None)

    def check_data_login(self):
        username = self.scr_mngr.screen1.username.text
        password = self.scr_mngr.screen1.password.text

        print(username)
        print(password)
        if username == "KivyMD" and password == "kivy":
            self.ids["wrongpass"].text = ""
            self.change_screen("screen2")
        else:
            self.ids["wrongpass"].text = "Wrong username or password, please try again"

    def change_screen(self, screen, *args):
        self.scr_mngr.transition.direction = 'left'
        self.scr_mngr.current = screen

    def back_to_chat(self):
        self.scr_mngr.transition.direction = 'right'
        self.scr_mngr.current = 'screen2'


class nav_layout(NavigationLayout):
    def print_text(self):
        print('hello')
        print("self.ids.Chat_String.text=", self.ids.Chat_String.text)

    def check_data_login(self):
        username = self.ids.screen1.username.text
        password = self.ids.screen1.password.text

        print(username)
        print(password)
        if username == "KivyMD" and password == "kivy":
            self.change_screen("screen2")
            self.ids.wrongpass.text = ""
        else:
            self.ids.wrongpass.text = \
                "Wrong username or password, please try again"

    def change_screen(self, screen, *args):
        self.ids.scr_mngr.transition.direction = 'left'
        self.ids.scr_mngr.current = screen

    def back_to_chat(self):
        self.ids.scr_mngr.transition.direction = 'right'
        self.ids.scr_mngr.current = 'screen2'

    def logout(self):
        # logout function, returns to screen 1
        self.ids.scr_mngr.current = 'screen1'

    def oof(self, data):
        self.ids.Chat_String.text = data


class UploadPopup(Popup):
    def load(self, path, selection):
        print(path, selection)


KV = """
#:import Toolbar kivymd.toolbar.Toolbar
#:import MDNavigationDrawer kivymd.navigationdrawer.MDNavigationDrawer
#:import NavigationLayout kivymd.navigationdrawer.NavigationLayout
#:import NavigationDrawerDivider kivymd.navigationdrawer.NavigationDrawerDivider
#:import NavigationDrawerToolbar kivymd.navigationdrawer.NavigationDrawerToolbar
#:import MDTextField kivymd.textfields.MDTextField
#:import MDSeparator kivymd.card.MDSeparator
#:import MDThemePicker kivymd.theme_picker.MDThemePicker
#:import CardTransition kivy.uix.screenmanager.CardTransition
#:import Factory kivy.factory.Factory


<MDCustomIconItem>:
    text: root.text

    AvatarSampleWidget:
        source: root.icon

<UploadPopup>:
    id: popup
    title: "Upload"
    BoxLayout:
        FileChooserIconView:
            id: FileChoose
            pos_hint_x: 0.5
            pos_hint_y: 0.5
            on_selection: root.load(FileChoose.path, FileChoose.selection)
        MDRaisedButton:
            text: "Upload"
            text_color: (0,0,0,1)
            on_release: root.load(FileChoose.path, FileChoose.selection)
            on_release: popup.dismiss()

        MDRaisedButton:
            text: "Close"
            text_color: (0,0,0,1)
            on_release: popup.dismiss()


nav_layout:
    id: nav_layout
    MDNavigationDrawer:
        id: nav_drawer
        drawer_logo: 'logo.png'
        NavigationDrawerToolbar:
            title: 'hello'
        NavigationDrawerIconButton:
            icon: 'settings'
            text: 'Account Settings'
            on_release: root.change_screen('screen3')
        NavigationDrawerIconButton:
            icon: 'face'
            text: 'Friends'
            on_release: root.print_text()
        NavigationDrawerIconButton:
            icon: 'logout'
            text: 'Logout'
            on_release: root.logout()
        NavigationDrawerDivider:
            height: dp(1)
    MyLayout:
        scr_mngr: scr_mngr
        orientation: 'vertical'


        ScreenManager:

            transition: CardTransition()
            id: scr_mngr
            screen1: screen1

            Screen:
                id: screen1
                name: 'screen1'
                username: username
                password: password

                BoxLayout:
                    size_hint: None, None
                    size: dp(520), dp(340)
                    pos_hint: {'center_x': 0.5, 'center_y': 0.5}

                    BoxLayout:
                        orientation:'vertical'
                        padding: dp(20)
                        spacing:20

                        MDLabel:
                            text: 'Chat App'
                            theme_text_color: 'Secondary'
                            font_style:"Title"
                            size_hint_y: None
                            height: dp(36)

                        MDSeparator:
                            height: dp(1)

                        MDTextField:
                            id: username
                            hint_text: "Username "
                            size_hint_y: 0.9
                            helper_text_mode: "on_focus"

                        MDTextField:
                            id: password
                            hint_text: "Password "
                            helper_text_mode: "on_focus"
                            size_hint_y: 0.9
                            password: True

                        MDFlatButton:
                            text: "Login"
                            pos_hint: {'center_x': 0.5}
                            on_release: root.check_data_login()

                        MDLabel:
                            id: wrongpass
                            color: 1,0,1,1
                            text: ""



            Screen:
                name: 'screen2'
                id: screen2

                Toolbar:
                    id: toolbar
                    title: "Welcome ! "
                    pos_hint: {'center_x': 0.5, 'center_y': 0.96}
                    md_bg_color: app.theme_cls.primary_color
                    background_palette: 'DeepPurple'
                    background_hue: 'A400'
                    left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer() ]]
                    right_action_items: [['animation', lambda x: MDThemePicker().open()], ['camera', lambda x: print('hello')]]

                MDLabel:
                    font_style: 'Title'
                    theme_text_color: 'Primary'
                    text: "Data :"
                    height: self.texture_size[1] + dp(3)
                    halign: 'center'
                    pos_hint: {'center_x': 0.5, 'center_y': 0.5}



            Screen:
                name: 'screen3'
                id: screen3

                Toolbar:
                    id: tools
                    title: "Your Profile"
                    pos_hint: {'center_x': 0.5, 'center_y': 0.96}
                    md_bg_color: app.theme_cls.primary_color
                    background_palette: 'DeepPurple'
                    background_hue: 'A400'
                    left_action_items: [['arrow-left', lambda x: root.back_to_chat()]]
                MDLabel:
                    id: Profile_String
                    font_size: 90
                    text: "XXX"
                    halign: 'center'
                    pos_hint: {'center_x': 0.5, 'center_y': 0.85}

            Screen:
                name: 'screen4'
                id: screen4

                Toolbar:
                    id: tools
                    title: "XXX"
                    pos_hint: {'center_x': 0.5, 'center_y': 0.96}
                    md_bg_color: app.theme_cls.primary_color
                    background_palette: 'DeepPurple'
                    background_hue: 'A400'
                    left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer() ]]
                    right_action_items: [['animation', lambda x: MDThemePicker().open()], ['camera', lambda x: print('hello')]]
                ScrollView:
                    id: sv
                    pos_hint: {'center_x': .55, 'y': .35}
                    MDLabel:
                        id: Chat_String
                        font_size: 40
                        text: "XXX"


                MDTextField:
                    id: Input_String
                    hint_text: 'Enter Your Message...'
                    helper_text_mode: 'on_focus'
                    pos_hint: {'center_x': 0.35, 'center_y': 0.2}
                    size_hint_x: 0.6
                    multiline: True


                MDRaisedButton:
                    id: Send_Button
                    text: 'Send'
                    pos_hint: {'center_x': 0.75, 'center_y': 0.2}

                MDRaisedButton:
                    id: Choose_Image
                    text: 'Attach File'
                    pos_hint: {'center_x': 0.9, 'center_y': 0.2}
                    on_release: Factory.UploadPopup().open()
"""


class MDCustomIconItem(OneLineAvatarListItem):
    icon = StringProperty('')
    text = StringProperty()

    def _set_active(self, active, list):
        pass


class AvatarSampleWidget(ILeftBody, Image):
    pass


class MyApp(App):
    theme_cls = ThemeManager()
    theme_cls.primary_palette = 'Blue'
    title = "Navigation Drawer"
    main_widget = None

    def __getattr__(self, attr):
        return super().__getattr__(attr)

    def build(self):
        self.main_widget = Builder.load_string(KV)
        return self.main_widget

    def callback(self, instance, value):
        self.main_widget.ids.scr_mngr.current = 'screen4'

    def recover_data(self):
        print('started')
        while True:
            data = sock.recv(1024)
            data = data.decode()
            if data:
                print(data)
                data = data.split()
                data = data[-1] + ": " + ' '.join(data[:-1])
                r = data + '\n'
                open('chat1.txt', 'a+').write(r)
                e = open('chat1.txt', 'r').readlines()
                nav_layout().oof('\n\r'.join(e))
                print(data)

    def on_start(self):
        Thread(target=self.recover_data).start()
        for i in range(15):
            self.main_widget.ids.nav_drawer.add_widget(
                MDCustomIconItem(
                    text="Item menu %d" % i,
                    icon='logo.png',
                    on_release=lambda x, y=i: self.callback(x, y)))


MyApp().run()

输出

【讨论】:

    猜你喜欢
    • 2016-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多