我正在使用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()
答案 0 :(得分:2)
该错误是由于在kv文件中为id
分配了字符串值。
从kv文件中的所有id
中删除单引号。
Kv Language » Referencing Widgets
为ID分配值时,请记住该值不是字符串。 没有引号:好-> id:值,差-> id:“值”
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()