'super'对象没有属性'__getattr__'kivy

时间:2019-02-24 02:59:41

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

我正在使用kivy和socket编写聊天应用程序。但是,每当我的应用收到消息时,我总是会得到AttributeError:'super'对象没有属性'__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()

1 个答案:

答案 0 :(得分:2)

原因

该错误是由于在kv文件中为id分配了字符串值。

解决方案

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

Kv Language » Referencing Widgets

  

为ID分配值时,请记住该值不是字符串。   没有引号:好-> id:值,差-> id:“值”

示例

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()

输出

KivyMD Navigation Drawer