Abacito
Abacito

Reputation: 151

'Nonetype' object has no attribute ids error

I am trying to make the user input the message of the push a notification. I want the user to receive this notification at a certain time(eg. 5 secs interval). When I run the app, it runs, everything else works fine but the notifications do not show and I receive an error only when I close the app. Error:

   File "C:/Users/Dell/PycharmProjects/MantraApp/main.py", line 55, in <module>
     schedule.run_pending()
   File "C:\Users\Dell\AppData\Local\Programs\Python\Python37\lib\site-packages\schedule\__init__.py", line 563, in run_pending
     default_scheduler.run_pending()
   File "C:\Users\Dell\AppData\Local\Programs\Python\Python37\lib\site-packages\schedule\__init__.py", line 94, in run_pending
     self._run_job(job)
   File "C:\Users\Dell\AppData\Local\Programs\Python\Python37\lib\site-packages\schedule\__init__.py", line 147, in _run_job
     ret = job.run()
   File "C:\Users\Dell\AppData\Local\Programs\Python\Python37\lib\site-packages\schedule\__init__.py", line 466, in run
     ret = self.job_func()
   File "C:/Users/Dell/PycharmProjects/MantraApp/main.py", line 49, in show_notification
     plyer.notification.notify(title='test', message=self.root.ids.mantra_text.text)
 AttributeError: 'NoneType' object has no attribute 'ids'

Process finished with exit code 1

Here is my main.py

from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.button import ButtonBehavior
from kivy.uix.image import Image
from kivy.properties import StringProperty, ObjectProperty,NumericProperty
from kivy.uix.popup import Popup
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.clock import Clock
import plyer
import time
import schedule



class MainScreen(Screen, FloatLayout):
    mantra_text = ObjectProperty(None)

    def printMantra(self):
        print(self.ids.mantra_text.text)

    def icon_popup(self):
        popup = Popup(title="Profile Icon", content=Popup_Content(), size_hint=(0.8, 0.3))
        popup.open()


class Popup_Content(RelativeLayout):
    pass # contents in kv file. contains grid of profile icons.


class MainApp(App):
    def build(self):
        return MainScreen()

    def set_profile_icon(self, image):
        self.root.ids.profile_icon.source = image.source
        
    def show_notification(self):
        plyer.notification.notify(title='test', message=self.root.ids.mantra_text.text) # mantra_ text is text input id
        


schedule.every(5).seconds.do(MainApp().show_notification)
while 1:
    schedule.run_pending()
    time.sleep(1)
    MainApp().run()

Upvotes: 0

Views: 117

Answers (1)

John Anderson
John Anderson

Reputation: 38822

When you call MainApp().show_notification, you are creating a new instance of MainApp (not the one you are running) and calling the show_notification(). Since you have not called the run() method of that new instance of MainApp, it has no root.

I suggest you use kivy.clock to schedule your notifications. Something like this:

class MainApp(App):
    def build(self):
        schedule.every(5).seconds.do(self.show_notification)
        Clock.schedule_interval(lambda dt: schedule.run_pending(), 1)
        return MainScreen()

    def set_profile_icon(self, image):
        self.root.ids.profile_icon.source = image.source
        
    def show_notification(self, *args):
        plyer.notification.notify(title='test', message=self.root.ids.mantra_text.text) # mantra_ text is text input id
        
if __name__ == '__main__':
    MainApp().run()

Upvotes: 1

Related Questions