AttributeError: объект «NoneType» не имеет атрибута «setDelegate_», как я могу это исправить?

По сути, я новичок в python и kivy и пытался создать приложение-таймер, которое выдает уведомление через 20 минут, чтобы глаза отдохнули. Я использовал plyer, чтобы настроить уведомление, и я на Mac. Обычно уведомление не работает из-за ошибки pyobjus, но я обошел это. Но теперь я остался с этой новой ошибкой.

runfile('/Users/oats/Downloads/LEAF 1.0/Исходный код/LEAF 0.6 .py', wdir='/Users/oats/Downloads/LEAF 1.0/Исходный код') Отслеживание (последний последний вызов):

Файл /Users/oats/Downloads/LEAF 1.0/Исходный код/LEAF 0.6 .py, строка 218, в классе LeafApp(MDApp):

Файл /Users/oats/Downloads/LEAF 1.0/Исходный код/LEAF 0.6 .py, строка 240, в LeafApp notifyMe(Эй, ты! Сделай перерыв!!, Ты должен следовать правилу 20-20-20, чтобы не терять глаза здоровый)

Файл /Users/oats/Downloads/LEAF 1.0/Исходный код/LEAF 0.6 .py, строка 231, в уведомлении notifyMe.notify(

Файл /Users/oats/opt/anaconda3/lib/python3.8/site-packages/plyer/facades/notification.py, строка 79, в уведомлении self._notify(

Файл /Users/oats/opt/anaconda3/lib/python3.8/site-packages/plyer/platforms/macosx/notification.py, строка 38, в notify usrnotifctr.setDelegate(self)

AttributeError: объект «NoneType» не имеет атрибута «setDelegate_»

полное сообщение об ошибке. Мой код ниже.

'''

from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.picker import MDDatePicker
from kivymd.uix.picker import MDThemePicker
from kivy.config import Config
from kivy.uix.boxlayout import BoxLayout
from kivymd.theming import ThemableBehavior
from kivymd.uix.list import MDList
from kivy.properties import ObjectProperty
from kivymd.uix.navigationdrawer import MDNavigationDrawer
from kivy.properties import StringProperty, ListProperty
from kivy.lang import Builder
from kivy.core.window import Window
from plyer import notification
import time
import plyer


Config.set('graphics', 'width', '1600')
Config.set('graphics', 'height', '1200')


KV = '''
<Box@BoxLayout>:
    bg: .65, .48, .35, 1 
       
             

BoxLayout:
    Rectangle:    
        size: 1600, 1200

    Box:
        bg: app.theme_cls.bg_light
    Box:
        bg: app.theme_cls.bg_normal
    Box:
        bg: app.theme_cls.bg_dark
    Box:
        bg: app.theme_cls.bg_darkest
            
'''
            
screen_helper = """
ScreenManager:
    MenuScreen:
    HomeScreen:
    BreakScreen:
    SettingsScreen
        
<MenuScreen>:
    name: 'menu'
    
  
        
    MDLabel:
        rectangle:
        background_color: .65, .48, .35, 1           
        size: 300, 700
        pos_hint: {'center_x':0.1, 'center_y':0.0}
        
                
    MDLabel:
        text: "Welcome to"
        font_style: 'H2'
        size:500, 500
        pos_hint: {'center_x':0.95,'center_y':0.84}
        
    MDLabel:
        text: "LEAF"
        font_style: 'H3'
        size:500, 500
        pos_hint: {'center_x':1.045,'center_y':0.7}
        
        
    MDFlatButton:
        text: 'Calendar'
        font_style: 'H6'
        pos_hint: {'center_x':0.091,'center_y':0.65}
        on_release: app.show_date_picker()
            
            
    MDFlatButton:
        text: 'Home'
        font_style: 'H6'
        pos_hint: {'center_x':0.076,'center_y':0.57}
        on_press: root.manager.current = 'home'
        
    MDFlatButton:
        text: 'Settings'
        font_style: 'H6'
        pos_hint: {'center_x':0.09,'center_y':0.49}
        on_press: root.manager.current = 'settings'
        
            
    MDRectangleFlatButton:
        text: 'Continue'
        font_style: 'H6'
        pos_hint: {'center_x':0.61,'center_y':0.345}
        on_press: root.manager.current = 'home'
   


    
<HomeScreen>:
    name: 'home'    
                
        
    MDToolbar:
        id: toolbar
        title: "Home
        pos_hint: {"top": 1}
        elevation: 5
        left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
        
    Widget:

        MDNavigationDrawer:
            id: nav_drawer
    
            ContentNavigationDrawer:
                orientation: 'vertical'
                padding: "8dp"
                spacing: "8dp"
                

                MDFlatButton:
                    text: 'Return to menu'
                    font_style: 'Subtitle1'
                    on_release: root.manager.current = 'menu'

                MDFlatButton:
                    text: 'Open Calendar'
                    font_style: 'Subtitle1'
                    on_release: app.show_date_picker()
                    
                MDFlatButton:
                    text: 'Open Settings'
                    font_style: 'Subtitle1'
                    on_press: root.manager.current = 'settings'



    
                    
                    
                            
                
                
            
    
<BreakScreen>:
    name: 'break'
    
<SettingsScreen>:
    name: 'settings'
    
    
    MDFlatButton:
        text: 'Return to menu'
        font_style: 'H6'
        pos_hint: {'center_x':0.1,'center_y':0.05}
        on_press: root.manager.current = 'menu'
        
    MDFlatButton:
        text: 'Change Theme'
        font_style: 'H6'
        pos_hint: {'center_x':0.85,'center_y':0.95}
        on_release: app.show_theme_picker() 
        
    MDFloatingActionButton:
        icon: 'moon-waning-crescent'
        theme_text_color: "Custom"
        md_bg_color: 0, 0.039, 0.867, 0.557
        pos_hint: {'center_x':0.9,'center_y':0.3}
        on_press: self.theme_cls.theme_style = "Dark"  # "Light"
        
    MDFloatingActionButton:
        icon: 'MDFloatingActionButton'
        icon: 'lightbulb'
        pos_hint: {'center_x':0.9,'center_y':0.1}
        on_press: self.theme_cls.theme_style = "Light"  # "Dark"
        
        
"""  

class MenuScreen(Screen):
    pass


class HomeScreen(Screen):
    pass


class BreakScreen(Screen):
    pass

class SettingsScreen(Screen):
    pass

class ContentNavigationDrawer(BoxLayout):
    pass

class DrawerList(ThemableBehavior, MDList):
    pass


    
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(HomeScreen(name='profile'))
sm.add_widget(BreakScreen(name='upload'))
sm.add_widget(SettingsScreen(name='settings'))



class LeafApp(MDApp):
    
    def show_date_picker(self):
        date_dialog = MDDatePicker()
        date_dialog.open()

    def show_theme_picker(self):
        theme_dialog = MDThemePicker()
        theme_dialog.open()



    def notifyMe(ttle, msg):
        notification.notify(
            title = ttle,
            message = msg,
            timeout = 10,
    )


    if __name__ == '__main__':
        while True:
            notifyMe("Hey You! take a break now !!", "You should follow the 20-20-20 rule to keep your eyes healthy")
            time.sleep(1200)
            



    def build(self):
        screen = Builder.load_string(screen_helper)
        return screen
    
LeafApp().run()
'''

Еще раз спасибо всем, кто обратился. Я совсем запутался и мне нужна помощь!


person Oats.KV    schedule 14.05.2021    source источник
comment
Не уверен, почему вы получаете эту ошибку, но ваш LeafApp никогда не запустится, потому что ваш код переходит в бесконечный цикл (while True) еще до того, как приложение может быть запущено.   -  person John Anderson    schedule 14.05.2021
comment
Понимаешь, чувак, я так и думал, но почему-то не понимаю, почему, если я уберу таймер, он отлично работает. Я-я даже не знаю   -  person Oats.KV    schedule 14.05.2021


Ответы (1)


Попробуйте небольшой рефакторинг вашего кода, например:

def notifyMe(self, ttle, msg):  # added "self" arg
    notification.notify(
        title=ttle,
        message=msg,
        timeout=10,
    )

def timer_loop(self):
    while True:
        self.notifyMe("Hey You! take a break now !!", "You should follow the 20-20-20 rule to keep your eyes healthy")
        time.sleep(1200)

def build(self):
    # run timer as a separate thread
    threading.Thread(target=self.timer_loop, daemon=True).start()

    screen = Builder.load_string(screen_helper)
    return screen
person John Anderson    schedule 14.05.2021
comment
Добавьте import threading. - person John Anderson; 14.05.2021
comment
Новая ошибка! Код теперь работает благодаря вашему рефакторингу (tsym). То есть код работает, а уведомление нет? Довольно застрял на этом. /oats/opt/anaconda3/lib/python3.8/site-packages/plyer/platforms/macosx/notification.py, строка 38, в notify usrnotifctr.setDelegate_(self) AttributeError: объект «NoneType» не имеет атрибута 'setDelegate' [INFO] [Base] Запустить основной цикл приложения - person Oats.KV; 14.05.2021
comment
Эй, чувак, я полностью изменил код, и он работает. Теперь мне просто нужно сделать какой-то таймер, в котором уведомление воспроизводится через двадцать минут, но двадцатиминутный таймер запускается при нажатии кнопки. Надеюсь разберусь. Еще раз спасибо, чувак! - person Oats.KV; 15.05.2021
comment
class LeafApp(MDApp): def show_theme_picker(self): theme_dialog = MDThemePicker() theme_dialog.open() def notify(title, text): os.system(osascript -e 'отображать уведомление {} с заголовком {}' .format( text, title)) notify(LEAF, Эй, прошло двадцать минут, отдохни?) def build(self): screen = Builder.load_string(screen_helper) return screen LeafApp().run() - person Oats.KV; 15.05.2021