'super' 对象没有属性 '__getattr__' kivy
'super' object has no attribute '__getattr__' kivy
我正在使用 kivy 和套接字编写一个聊天应用程序。但是,每当我的应用程序收到消息时,我总是会收到 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()
我知道这个问题之前在 Whosebug 上被问过多次,但是 none 解决了我的问题。
任何帮助将不胜感激,谢谢!
**编辑:**我的完整错误信息在这里
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()
原因
错误是由于将字符串值分配给 kv 文件中的 id
。
解决方案
从 kv 文件中的所有 id
中删除单引号。
Kv Language » Referencing Widgets
When assigning a value to id, remember that the value isn’t a string.
There are no quotes: 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()
输出
我正在使用 kivy 和套接字编写一个聊天应用程序。但是,每当我的应用程序收到消息时,我总是会收到 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()
我知道这个问题之前在 Whosebug 上被问过多次,但是 none 解决了我的问题。
任何帮助将不胜感激,谢谢!
**编辑:**我的完整错误信息在这里
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()
原因
错误是由于将字符串值分配给 kv 文件中的 id
。
解决方案
从 kv 文件中的所有 id
中删除单引号。
Kv Language » Referencing Widgets
When assigning a value to id, remember that the value isn’t a string. There are no quotes: 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()