Kivy app becoming unresponsive

59 views
Skip to first unread message

ASHISH CHUGH

unread,
Jan 22, 2018, 4:12:33 AM1/22/18
to kivy-...@googlegroups.com
Hi kivy users,

I have created a kivy app which interacts with Raspberry Pi to fetch data over SSH.

I have defined a Grid layout having 5 columns(ID, LoadType, Test, Status, Remarks) inside a ScrollView to show the result of all tests to the user. But sometimes when I press the "Update Test Result" button, the app goes in hang situation and finally it crashes.

When "Start Testing" button is pressed, start_testing() is called which will start the test for 15 minutes.

When "Update Test Result" button is pressed, execute_update_test_result() is called which will open a Popup for user to wait for output & finally call update_test_result() function.

Following is the screenshot of app screen:

Inline image 1

Following is the screenshot of app screen when it hangs:

Inline image 2

Code and Logs

kv file (teststart.kv) :
<TestStartScreen>:
    layout_content: layout_content
    lbl_remarks: lbl_remarks
    lbl_timer: lbl_timer
    lbl_teststart_remarks: lbl_teststart_remarks
    btn_report: btn_report
    btn_save_rpi: btn_save_rpi
    txt_comments: txt_comments
    btn_save: btn_save

    canvas:
        Color:
            rgb: (.8750, .9453, .9414)
        Rectangle:
            pos: self.pos
            size: self.size 
            
    BoxLayout:
        orientation: 'vertical'
        
        GridLayout:    
            size_hint_y: 0.19
            size_hint_x: 1
            rows: 1
            padding: 5, 10    
            canvas:
                Color:
                    rgb: (.2461, .3164, .7070)
                Rectangle:
                    pos: self.pos
                    size: self.size 

            Label:
                size_hint: None, None
                size: self.texture_size
                text: ' TroubleShoot-Zenatix'
                font_size: 40

            Label:                
                size: self.texture_size
                id: lbl_timer
                text: ''
                text_size: self.size
                halign: 'center'
                valign: 'middle'
                bold: True

        BoxLayout:
            orientation: 'vertical'
            padding: 10, 10

            ScrollView:
                size: self.size
                GridLayout:
                    id: layout_content
                    size_hint_y: None
                    size_hint_x: 1.3
                    cols: 5
                    row_default_height: '60dp'
                    row_force_default: True
                    canvas:
                        Color:
                            rgb: (1,1,1)
                        Rectangle:
                            pos: self.pos
                            size: self.size 

        GridLayout:
            cols: 2
            size_hint_y: 0.6
            padding: 5, 0
            spacing: 5, 5
            row_default_height: '50dp'
            row_force_default: True

            Label:
                id:lbl_teststart_remarks
                color: 0,0,0,1
                size: self.texture_size

            Label:
                id:lbl_remarks
                color: 0,0,0,1
                size: self.texture_size

            Button:
                text: 'Start Testing'
                id: btn_save_rpi
                on_press: root.execute_start_testing()

            Button:
                text: 'Update Test Result'
                on_press: root.execute_update_test_result()

            TextInput:
                hint_text: 'Any Comments'
                id: txt_comments
                multiline: False

            Button:
                text: 'Save'
                id: btn_save
                on_press: root.execute_save_comments()

        GridLayout:
            cols: 1
            size_hint_y: None
            padding: 5, 0
            spacing: 5, 5
            row_default_height: '50dp'
            row_force_default: True

            Button:
                text: 'Generate Report'
                id: btn_report
                on_press: root.execute_generate_report()
                background_color: 2,1,0,1

<PopupBoxTestStart>:
    pop_up_text: _pop_up_text
    size_hint: .5, .2
    auto_dismiss: False
    title: 'Status'   

    BoxLayout:
        orientation: "vertical"
        Label:
            id: _pop_up_text
            text: '' 

Python code (teststart.py):

class TestStartScreen(Screen): layout_content = ObjectProperty(None) def __init__(self, **kwargs): super(TestStartScreen, self).__init__(**kwargs) self.layout_content.bind(minimum_height=self.layout_content.setter('height')) self.d2 = None
    @mainthread
  def add_new_label(self, lbl_text, lbl_color): lbl = Label(markup=True, halign="center", valign="middle") lbl.bind(size=lbl.setter('text_size')) lbl.text = lbl_text lbl.color = lbl_color self.ids.layout_content.add_widget(lbl) def show_popup(self): self.pop_up = Factory.PopupBox() self.pop_up.update_pop_up_text('Wait....') self.pop_up.open()
def start_testing(self):
self.d2 = datetime.datetime.now() + datetime.timedelta(minutes=15)
def execute_update_test_result(self): self.show_popup() mythread = threading.Thread(target=self.update_test_result) mythread.start() def update_test_result(self): try: self.ids.layout_content.clear_widgets() d1 = datetime.datetime.now() if self.d2==None: self.lbl_remarks.text = 'First Start Testing' else: self.lbl_remarks.text = '' diff = self.d2 - d1 left_time = '%.2f'%(diff.total_seconds()/60) if diff.total_seconds() <= 0: self.lbl_timer.text = 'Testing completed' else: self.lbl_timer.text = str(left_time)+' minutes left' self.cmd = "sudo python /home/pi/zenatix_testing_controller/control_testing.py -H health" data, returncode = self.cmd_run() if returncode: output = json.loads(data.replace('\'', '"')) for i in output: for test in output[i]: self.add_new_label('Health', (0, 0, 0, 1)) self.add_new_label('Health', (0, 0, 0, 1)) self.add_new_label(test, (0, 0, 0, 1)) if 'FAILED' in output[i][test]['STATUS']: self.add_new_label(str(output[i][test]['STATUS']), (1, 0, 0, 1)) else: self.add_new_label(str(output[i][test]['STATUS']), (0, 1, 0, 1)) self.add_new_label(str(output[i][test]['REMARKS']), (0, 0, 0, 1)) self.pop_up.dismiss() except Exception as e: print e self.pop_up.dismiss() class TestStartApp(App): def build(self): return TestStartScreen() if __name__ == '__main__': TestStartApp().run()

Crash Logs:

[INFO   ] [Base        ] Leaving application in progress...
 Traceback (most recent call last):
   File "/home/ashish/PyCharm Workspace/TT-App/main.py", line 168, in <module>
     LoginApp().run()
   File "/usr/lib/python2.7/dist-packages/kivy/app.py", line 828, in run
     runTouchApp()
   File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 504, in runTouchApp
     EventLoop.window.mainloop()
   File "/usr/lib/python2.7/dist-packages/kivy/core/window/window_sdl2.py", line 663, in mainloop
     self._mainloop()
   File "/usr/lib/python2.7/dist-packages/kivy/core/window/window_sdl2.py", line 405, in _mainloop
     EventLoop.idle()
   File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 348, in idle
     Clock.tick_draw()
   File "/usr/lib/python2.7/dist-packages/kivy/clock.py", line 588, in tick_draw
     self._process_events_before_frame()
   File "kivy/_clock.pyx", line 405, in kivy._clock.CyClockBase._process_events_before_frame (kivy/_clock.c:8093)
   File "kivy/_clock.pyx", line 445, in kivy._clock.CyClockBase._process_events_before_frame (kivy/_clock.c:7965)
   File "kivy/_clock.pyx", line 443, in kivy._clock.CyClockBase._process_events_before_frame (kivy/_clock.c:7887)
   File "kivy/_clock.pyx", line 167, in kivy._clock.ClockEvent.tick (kivy/_clock.c:3211)
   File "/usr/lib/python2.7/dist-packages/kivy/uix/gridlayout.py", line 511, in do_layout
     c = children[i]
 IndexError: list index out of range


Please anyone help me in resolving this issue.


Thank you,

Ashish Chugh

ZenCODE

unread,
Jan 23, 2018, 11:09:16 AM1/23/18
to Kivy users support
This is probably the result of threading. You cannot update the kivy gui on a thread. Try using the @mainthread decorator or use the Clock schedule ...

ASHISH CHUGH

unread,
Jan 24, 2018, 7:24:52 AM1/24/18
to Kivy users support
Thanks for replying.
As you mentioned in your reply "Try using the @mainthread decorator or use the Clock schedule ..." But when I press Update Test Result button, update_test_result() method is called in another thread which is simply querying the Raspberry Pi for test result & based on the result the app gui is updated through add_new_label() method for which I have already used @mainthread decorator. But the app sometimes still hangs & finally crashes.
Correct me if I am wrong.

ZenCODE

unread,
Jan 24, 2018, 1:28:01 PM1/24/18
to Kivy users support
    self.ids.layout_content.clear_widgets()

occurs in it's own thread. Although that may not be the problem, it's probably a good idea
to try it without threads just to see whether that is the problem or not
Reply all
Reply to author
Forward
0 new messages