0

for a project I'm trying to make a simple GUI which displays some basic information (like time, date, public transport info, some news etc.) To do this I want a Homepage that displays an overview of all these things and a special page for every subject with a detailed view. Python combined with Kivy seemed like the best/easiest solution that looks good and works quite easy. I am however getting a problem with displaying the time. When I try to update the text on the label that displays the time I get an AttributeError: 'super' object has no attribute '__getattr__', which does not give me much information as to where to look for a solution. Can anyone point out what's wrong?

main.py:

import feedparser
import time
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.anchorlayout import AnchorLayout
from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty, StringProperty
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.clock import Clock

# Declare widgets
class DateTime(Widget):
    curtime = StringProperty('')

    def update(self, dt):
        self.curtime = time.strftime("%H:%M:%S")
        print self.curtime
        self.ids["kv_timelabel"].text = str(self.curtime)

# Declare all screens
class HomeScreen(Screen):
    obj_datetime = DateTime()
    Clock.schedule_interval(obj_datetime.update, 1.0 / 10.0)

class NewsScreen(Screen):
    pass

class PublicTransportScreen(Screen):
    pass

class TrafficScreen(Screen):
    pass

class ScreenManagement(ScreenManager):
    pass

class MirrorApp(App):
    def build(self):
        # Create the screen manager
        render = ScreenManagement()
        render.add_widget(HomeScreen(name='home'))
        render.add_widget(TrafficScreen(name='traffic'))
        render.add_widget(PublicTransportScreen(name='public_transport'))
        render.add_widget(NewsScreen(name='news'))
        return render

if __name__ == '__main__':
    MirrorApp().run()

mirror.kv:

#:kivy 1.9.0

<HomeScreen>:
    name: 'home'
    obj_datetime: kv_datetime

    Button:
        on_release: app.root.current = 'news'
        text: 'News'
        size_hint: 0.5,0.15
        font_size: 50
        pos_hint: {"left":1, "top":0.15}

    Button:
        on_release: app.root.current = 'public_transport'
        text: 'Public Transport'
        size_hint: 0.5,0.15
        font_size: 50
        pos_hint: {"left":1, "top":0.3}

    Button:
        on_release: app.root.current = 'traffic'
        text: 'Traffic'
        size_hint: 0.5,0.15
        font_size: 50
        pos_hint: {"left":1, "top":0.45}

    DateTime:
        id: kv_datetime
        center: self.parent.center

<NewsScreen>:
    name: 'news'

    Button:
        on_release: app.root.current = 'home'
        text: 'back to the home screen'
        font_size: 50

<PublicTransportScreen>:
    name: 'public_transport'

    Button:
        on_release: app.root.current = 'home'
        text: 'back to the home screen'
        font_size: 50

<TrafficScreen>:
    name: 'traffic'

    Button:
        on_release: app.root.current = 'home'
        text: 'back to the home screen'
        font_size: 50

<DateTime>:
    Label:
        id: kv_timelabel
        text:
        font_size: 70  
        center_x: self.parent.center_x
        center_y: self.parent.center_y

The error I get when running main.py is (I think the last two lines or so of this error are enough, but you can never be thorough enough):

[INFO   ] [Logger      ] Record log in /home/matthias/.kivy/logs/kivy_16-04-17_97.txt
[INFO   ] [Kivy        ] v1.9.0
[INFO   ] [Python      ] v2.7.10 (default, Oct 14 2015, 16:09:02) 
[GCC 5.2.1 20151010]
[INFO   ] [Factory     ] 173 symbols loaded
[INFO   ] [Image       ] Providers: img_tex, img_dds, img_gif, img_sdl2, img_pil (img_ffpyplayer ignored)
[INFO   ] [Text        ] Provider: sdl2
[INFO   ] [OSC         ] using <multiprocessing> for socket
[INFO   ] [Window      ] Provider: sdl2(['window_egl_rpi'] ignored)
[INFO   ] [GL          ] OpenGL version <3.0 Mesa 11.0.2>
[INFO   ] [GL          ] OpenGL vendor <Intel Open Source Technology Center>
[INFO   ] [GL          ] OpenGL renderer <Mesa DRI Intel(R) Ivybridge Mobile >
[INFO   ] [GL          ] OpenGL parsed version: 3, 0
[INFO   ] [GL          ] Shading version <1.30>
[INFO   ] [GL          ] Texture max size <8192>
[INFO   ] [GL          ] Texture max units <16>
[INFO   ] [Window      ] auto add sdl2 input provider
[INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
[INFO   ] [ProbeSysfs  ] device match: /dev/input/event5
[INFO   ] [MTD         ] Read event from </dev/input/event5>
[INFO   ] [Base        ] Start application main loop
[INFO   ] [GL          ] NPOT texture support is available
19:39:33
[INFO   ] [Base        ] Leaving application in progress...
 Traceback (most recent call last):
   File "main.py", line 49, in <module>
     MirrorApp().run()
   File "/usr/lib/python2.7/dist-packages/kivy/app.py", line 824, in run
 Exception in thread Thread-1:
     runTouchApp()
 Traceback (most recent call last):
   File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 487, in runTouchApp
     EventLoop.window.mainloop()
   File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
   File "/usr/lib/python2.7/dist-packages/kivy/core/window/window_sdl2.py", line 525, in mainloop
     self.run()
     self._mainloop()
   File "/usr/lib/python2.7/threading.py", line 763, in run
   File "/usr/lib/python2.7/dist-packages/kivy/core/window/window_sdl2.py", line 290, in _mainloop
     self.__target(*self.__args, **self.__kwargs)
     EventLoop.idle()
   File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 327, in idle
   File "/usr/lib/python2.7/dist-packages/kivy/input/providers/mtdev.py", line 197, in _thread_run
     Clock.tick()
   File "/usr/lib/python2.7/dist-packages/kivy/clock.py", line 483, in tick
     self._process_events()
     _device = Device(_fn)
   File "/usr/lib/python2.7/dist-packages/kivy/clock.py", line 615, in _process_events
   File "/usr/lib/python2.7/dist-packages/kivy/lib/mtdev.py", line 131, in __init__
     self._fd = os.open(filename, os.O_NONBLOCK | os.O_RDONLY)
 OSError: [Errno 13] Permission denied: '/dev/input/event5'

     event.tick(self._last_tick, remove)
   File "/usr/lib/python2.7/dist-packages/kivy/clock.py", line 374, in tick
     ret = callback(self._dt)
   File "main.py", line 19, in update
     self.ids["kv_timelabel"].text = str(self.curtime)
 KeyError: 'kv_timelabel'

When I replace self.ids["kv_timelabel"].text = str(self.curtime) with self.ids.kv_timelabel.text = str(self.curtime) I get:

[INFO   ] [Logger      ] Record log in 
/home/matthias/.kivy/logs/kivy_16-04-17_98.txt
[INFO   ] [Kivy        ] v1.9.0
[INFO   ] [Python      ] v2.7.10 (default, Oct 14 2015, 16:09:02) 
[GCC 5.2.1 20151010]
[INFO   ] [Factory     ] 173 symbols loaded
[INFO   ] [Image       ] Providers: img_tex, img_dds, img_gif, img_sdl2, img_pil (img_ffpyplayer ignored)
[INFO   ] [Text        ] Provider: sdl2
[INFO   ] [OSC         ] using <multiprocessing> for socket
[INFO   ] [Window      ] Provider: sdl2(['window_egl_rpi'] ignored)
[INFO   ] [GL          ] OpenGL version <3.0 Mesa 11.0.2>
[INFO   ] [GL          ] OpenGL vendor <Intel Open Source Technology Center>
[INFO   ] [GL          ] OpenGL renderer <Mesa DRI Intel(R) Ivybridge Mobile >
[INFO   ] [GL          ] OpenGL parsed version: 3, 0
[INFO   ] [GL          ] Shading version <1.30>
[INFO   ] [GL          ] Texture max size <8192>
[INFO   ] [GL          ] Texture max units <16>
[INFO   ] [Window      ] auto add sdl2 input provider
[INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
[INFO   ] [ProbeSysfs  ] device match: /dev/input/event5
[INFO   ] [MTD         ] Read event from </dev/input/event5>
[INFO   ] [Base        ] Start application main loop
[INFO   ] [GL          ] NPOT texture support is available
19:42:01
[INFO   ] [Base        ] Leaving application in progress...
 Traceback (most recent call last):
   File "main.py", line 49, in <module>
 Exception in thread Thread-1:
 Traceback (most recent call last):
   File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
     self.run()
   File "/usr/lib/python2.7/threading.py", line 763, in run
     MirrorApp().run()
     self.__target(*self.__args, **self.__kwargs)
   File "/usr/lib/python2.7/dist-packages/kivy/app.py", line 824, in run
   File "/usr/lib/python2.7/dist-packages/kivy/input/providers/mtdev.py", line 197, in _thread_run
     runTouchApp()
     _device = Device(_fn)
   File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 487, in runTouchApp
   File "/usr/lib/python2.7/dist-packages/kivy/lib/mtdev.py", line 131, in __init__
     EventLoop.window.mainloop()
     self._fd = os.open(filename, os.O_NONBLOCK | os.O_RDONLY)
   File "/usr/lib/python2.7/dist-packages/kivy/core/window/window_sdl2.py", line 525, in mainloop
 OSError: [Errno 13] Permission denied: '/dev/input/event5'
     self._mainloop()

   File "/usr/lib/python2.7/dist-packages/kivy/core/window/window_sdl2.py", line 290, in _mainloop
     EventLoop.idle()
   File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 327, in idle
     Clock.tick()
   File "/usr/lib/python2.7/dist-packages/kivy/clock.py", line 483, in tick
     self._process_events()
   File "/usr/lib/python2.7/dist-packages/kivy/clock.py", line 615, in _process_events
     event.tick(self._last_tick, remove)
   File "/usr/lib/python2.7/dist-packages/kivy/clock.py", line 374, in tick
     ret = callback(self._dt)
   File "main.py", line 19, in update
     self.ids.kv_timelabel.text = str(self.curtime)
   File "kivy/properties.pyx", line 720, in kivy.properties.ObservableDict.__getattr__ (kivy/properties.c:10938)
 AttributeError: 'super' object has no attribute '__getattr__'

Note that the code works just fine when I delete the line it mentions in the error.

Liveshort
  • 3
  • 1
  • 2

1 Answers1

0

Move the loading of the kv file before the widgets. So call the Builder.loadfile("mirror.kv") and then declare your classes DateTime and HomeScreen (since it uses DateTime). The key error you get is probably because this widget doesn't have a child with that id yet.

illright
  • 3,991
  • 2
  • 29
  • 54
  • That does fix the error, it does however still not display the time when I run it. The code in main.py now looks like this (right under the inputs): `render = Builder.load_file("mirror.kv") # Declare widgets class DateTime(Widget): def update(self, dt): self.ids.kv_timelabel.text = str(time.strftime("%H:%M:%S")) print time.strftime("%H:%M:%S")` The time is displayed in the terminal (so the update function gets called, but the label still stays empty. – Liveshort Apr 17 '16 at 18:52
  • I think the problem is that you update the obj_datetime widget in the HomeScreen declaration, but you never use it. Your HomeScreen displays a different instance of DateTime, the one declared in the kv file, that's not scheduled for updating. To fix that, add a DateTime widget that is scheduled for updating in the __init__ of HomeScreen and remove it from kv or schedule the correct widget for updating. – illright Apr 17 '16 at 19:39