Stopwatch Reset with sustained button press kivy

Question:

I am writing a program which will have a stopwatch screen in it. The stopwatch works as desired, and I am now trying to reduce the number of buttons on the screen for touch optimisation.

To do this, I am attempting to reduce the entire stopwatch to one single button. The button’s text changes as a display of elapsed time, and the button itself doubles as both a start and stop button depending on current state of stopwatch. However, I cannot implement the reset option into this single button. I would love it to work out so holding the button for say 2seconds would reset the timer. I have looked for options that accommodate this and am struggling to find any I can use.

This is my current python code for this screen:

class HomeScreen(Screen):
    elapsed_time = 0

    def update_time(self, dt):
        self.elapsed_time += dt
        mins, secs = divmod(round(self.elapsed_time), 60)
        self.ids.stopwatch_display.text = '{:02d}:{:02d}'.format(mins, secs)

    def start_stop(self):
        if self.ids.stopwatch_display.start_or_end == 'Start':
            Clock.schedule_interval(self.update_time, 0.1)
            self.ids.stopwatch_display.start_or_end = 'Stop'
        else:
            Clock.unschedule(self.update_time)
            self.ids.stopwatch_display.start_or_end = 'Start'

    def reset_time(self):
        self.elapsed_time = 0
        self.ids.stopwatch_display.text = '00:00'
        Clock.unschedule(self.update_time)
        self.ids.stopwatch_display.start_or_end = 'Start'



class TheApp(App):
    
    def build(self):
        # Create the screen manager
        sm = ScreenManager()
        sm.add_widget(HomeScreen(name='home_screen'))        

        return sm

def main():
    Builder.load_file('menu.kv')
    app = TheApp()
    app.run()

if __name__ == '__main__':
    main()

And the relevant .kv code:

<HomeScreen>:

    Button:
        id: reset_button
        text: "Reset"
        on_press: root.reset_time()


    Button:
        id: stopwatch_display
        text: 'initial'
        start_or_end: 'Start'
        on_press: root.start_stop()

I have noticed on_long_press whilst searching for a solution, but do not know how to use it properly in my .kv file. Whenever I try on_long_press: {do this} I am presented the AttributeError: long_press error.

Thanks in advance for the help 🙂

Asked By: Max Davies

||

Answers:

You can just time it yourself by including on on_release:. Add the on_release to your Button:

    Button:
        id: stopwatch_display
        text: 'initial'
        start_or_end: 'Start'
        on_press: root.start_stop()
        on_release: root.check_reset()

Then define the check_reset() method:

def check_reset(self):
    press_length = time.time() - self.button_press_time
    if press_length > 2:
        self.reset_time()

And define the button_press_time in the start_stop() method:

def start_stop(self):
    self.button_press_time = time.time()
    if self.ids.stopwatch_display.start_or_end == 'Start':
        Clock.schedule_interval(self.update_time, 0.1)
        self.ids.stopwatch_display.start_or_end = 'Stop'
    else:
        Clock.unschedule(self.update_time)
        self.ids.stopwatch_display.start_or_end = 'Start'
Answered By: John Anderson