如何在 Kivy 屏幕小部件中初始化实例
Posted
技术标签:
【中文标题】如何在 Kivy 屏幕小部件中初始化实例【英文标题】:How can you initialise an instance in a Kivy screen widget 【发布时间】:2020-05-08 16:06:43 【问题描述】:我试图在我的 kivy 屏幕中访问一个名为 self.localId 的实例变量,它一直说在我初始化后实例不存在。我知道我的代码中有一个错误,但我很难识别它。在 kivy 屏幕中初始化实例有不同的方法吗?但这是我的代码。我会很感激任何帮助
mainfile.py
from kivy.app import App
import requests
import json
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.lang import Builder
from firebase import firebase
class LoginWindow(Screen):
pass
class ProfileWindow(Screen):
def __init__(self):
self.localId = None
def sign_in_existing_user(self, email, password):
signin_url = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=" + self.wak
signin_payload = "email": email, "password": password, "returnSecureToken": True
signin_request = requests.post(signin_url, data=signin_payload)
sign_up_data = json.loads(signin_request.content.decode())
app = App.get_running_app()
print(signin_request.ok)
print(signin_request.content.decode())
if signin_request.ok == True:
refresh_token = sign_up_data['refreshToken']
self.localId = sign_up_data['localId']
idToken = sign_up_data['idToken']
# Save refreshToken to a file
with open(app.refresh_token_file, "w") as f:
f.write(refresh_token)
print(sign_up_data['localId'])
app.root.current = "page"
elif signin_request.ok == False:
error_data = json.loads(signin_request.content.decode())
error_message = error_data["error"]['message']
app.root.ids.login.ids.login_message.text = error_message.replace("_", " ")
def print_localId(self):
print(self.localId.text)
def __init__(self, **kwargs):
super(ProfileWindow, self).__init__(**kwargs)
window = ProfileWindow()
class MyApp(App):
refresh_token_file = "refresh_token.txt"
def build(self):
self.page = ProfileWindow()
self.refresh_token_file = self.user_data_dir + self.refresh_token_file
return sm
class WindowManager(ScreenManager):
pass
sm = Builder.load_file("kivy.kv")
#sm = WindowManager()
if __name__ == '__main__':
MyApp().run()
kivy.kv
WindowManager:
id: window manager
LoginWindow:
id: login
name: "login"
ProfileWindow:
id: page
name: "page"
<LoginWindow>
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
TextInput:
id: email
hint_text: "Email"
multiline: False
pos_hint: "center_x": 0.2 , "center_y":0.9
size_hint: 0.4, 0.10
TextInput:
id: password
hint_text: "Password"
multiline: False
pos_hint: "center_x": 0.2, "center_y": 0.8
size_hint: 0.4, 0.10
password: True
Button:
pos_hint:"x":0.3,"y":0.05
size_hint: 0.4, 0.1
text: "Login"
font_size: (root.width**2 + root.height**2) / 14**4
background_color: (0.082, 0.549, 0.984, 1.0)
background_normal: ''
on_release:
app.page.sign_in_existing_user(email.text, password.text)
<ProfileWindow>:
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
Button:
pos_hint:"x":0.3,"y":0.05
size_hint: 0.4, 0.1
text: "Print localId"
font_size: (root.width**2 + root.height**2) / 14**4
background_color: (0.082, 0.549, 0.984, 1.0)
background_normal: ''
on_release:
root.print_localId()
追溯
[INFO ] [Base ] Leaving application in progress...
Traceback (most recent call last):
File "/Users/temitayoadefemi/PycharmProjects/test6/mainfile.py", line 109, in <module>
MyApp().run()
File "/Users/temitayoadefemi/PycharmProjects/test6/venv/lib/python3.7/site-packages/kivy/app.py", line 855, in run
runTouchApp()
File "/Users/temitayoadefemi/PycharmProjects/test6/venv/lib/python3.7/site-packages/kivy/base.py", line 504, in runTouchApp
EventLoop.window.mainloop()
File "/Users/temitayoadefemi/PycharmProjects/test6/venv/lib/python3.7/site-packages/kivy/core/window/window_sdl2.py", line 747, in mainloop
self._mainloop()
File "/Users/temitayoadefemi/PycharmProjects/test6/venv/lib/python3.7/site-packages/kivy/core/window/window_sdl2.py", line 479, in _mainloop
EventLoop.idle()
File "/Users/temitayoadefemi/PycharmProjects/test6/venv/lib/python3.7/site-packages/kivy/base.py", line 342, in idle
self.dispatch_input()
File "/Users/temitayoadefemi/PycharmProjects/test6/venv/lib/python3.7/site-packages/kivy/base.py", line 327, in dispatch_input
post_dispatch_input(*pop(0))
File "/Users/temitayoadefemi/PycharmProjects/test6/venv/lib/python3.7/site-packages/kivy/base.py", line 293, in post_dispatch_input
wid.dispatch('on_touch_up', me)
File "kivy/_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
File "/Users/temitayoadefemi/PycharmProjects/test6/venv/lib/python3.7/site-packages/kivy/uix/behaviors/button.py", line 179, in on_touch_up
self.dispatch('on_release')
File "kivy/_event.pyx", line 703, in kivy._event.EventDispatcher.dispatch
File "kivy/_event.pyx", line 1214, in kivy._event.EventObservers.dispatch
File "kivy/_event.pyx", line 1098, in kivy._event.EventObservers._dispatch
File "/Users/temitayoadefemi/PycharmProjects/test6/venv/lib/python3.7/site-packages/kivy/lang/builder.py", line 64, in custom_callback
exec(__kvlang__.co_value, idmap)
File "/Users/temitayoadefemi/PycharmProjects/test6/kivy.kv", line 86, in <module>
root.print_localId()
File "/Users/temitayoadefemi/PycharmProjects/test6/mainfile.py", line 73, in print_localId
print(self.localId.text)
AttributeError: 'ProfileWindow' object has no attribute 'localId'
【问题讨论】:
你为什么老是用不同的账户问同样的问题,然后又删除了其他的? @RandomUser 问题越近,得到的关注越多 关注标签的人很烦。即便如此,给它一些时间,耐心一点。今天也只问了同样的问题。删除它是对回答并试图提供帮助的人的不尊重。 请添加您的kv文件的竞争,因为它在错误消息中提到。 您的回溯表明您的test5/kivy.kv
文件中有错误,但您尚未提供该文件。不查看该文件就无法判断问题所在。
【参考方案1】:
ProfileWindow
中有两个 __init__()
方法。第二个重新定义,覆盖第一个,并且不创建localId
属性。 ProfileWindow
中唯一的 __init__()
方法应该是:
def __init__(self, **kwargs):
super(ProfileWindow, self).__init__(**kwargs)
self.localId = None
下一个问题是您要创建 3 个 ProfileWindow
实例。你只需要一个。所以删除该行:
window = ProfileWindow()
并从App
中的build()
方法中删除:
self.page = ProfileWindow()
ProfileWindow
由您的代码中的行创建:
sm = Builder.load_file("kivy.kv")
ProfileWindow()
的任何其他用途都会创建一个不属于您的 GUI 的 ProfileWindow
的新实例。
接下来,当您按下Login
Button
时,您需要访问ProfileWindow
的正确实例。为此,请使用 kv
文件中的 ids
:
on_release:
app.root.ids.page.sign_in_existing_user(email.text, password.text)
而且,我认为是最后一个错误,您的print_localId()
方法试图打印localId
的text
属性,但它没有这样的属性。只需将该方法更改为:
def print_localId(self):
print(self.localId)
【讨论】:
爱你的兄弟,感谢所有帮助【参考方案2】:与我的代码进行比较时,您错过了 kivy.kv 中 localId 的定义,并且您没有将对象作为属性启动。 所以应该是:
代码:
class ProfileWindow(Screen):
localId = NumericProperty()
def __init__(self):
self.localId = None
test5.kv
<ProfileWindow>:
name: "page"
localId: localId
【讨论】:
以上是关于如何在 Kivy 屏幕小部件中初始化实例的主要内容,如果未能解决你的问题,请参考以下文章