Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
468 views
in Technique[技术] by (71.8m points)

python - How can you initialise an instance in a Kivy screen widget

I am trying to access an instance variable named self.localId in my kivy screen and it keeps saying the saying the instance doesn't exist after i have initialised it. I know I have an error In my code but im having a hard time identifying it. is there a different way to initialising instances in a kivy screen? but here is my code. I would appreciate any help

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


Traceback

[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'
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You have two __init__() methods in ProfileWindow. The second redefines, overwriting the first, and does not create the localId attribute. Your one and only __init__() method in ProfileWindow should be:

   def __init__(self, **kwargs):
       super(ProfileWindow, self).__init__(**kwargs)
       self.localId = None

The next problem is that you are creating 3 instances of ProfileWindow. You only need one. So remove the line:

window = ProfileWindow()

and from your build() method in the App, remove:

self.page = ProfileWindow()

The ProfileWindow is created by the line in your code:

sm = Builder.load_file("kivy.kv")

any other use of ProfileWindow() creates a new instance of ProfileWindow that is not part of your GUI.

Next, you need to access the correct instance of ProfileWindow when you press the Login Button. To do that, make use of the ids in your kv file as:

    on_release:
        app.root.ids.page.sign_in_existing_user(email.text, password.text)

And, what I think is the final error, your print_localId() method tries to print the text attribute of localId, but it does not have such an attribute. Just change that method to:

   def print_localId(self):
       print(self.localId)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...