-1

I am at a very beginner level with Python and I have a simple project for myself. My goal is to build a simple timer with only two functions using tkinter and python. The first button starts the countdown timer at 30 seconds. And the second button stops it. However, I would like each additional press of the first button to add an additional 30 seconds to whatever time is currently left on the countdown clock. The first two elements have proven not too difficult using this prior thread, but adding additional time to the active timer is something I cannot reach.

Essentially, the goal is to recreate the functionality of the "+30 seconds" button on a microwave, with an updating display, where the initial press both adds 30 seconds and starts the timer, each subsequent press adds an additional 30 seconds to the countdown timer, and the second button stops the timer.

Here's what I've been using for the basic timer logic.

def countdown(t=30):
    while t:
        mins, secs = divmod(t, 60)
        timer = '{:02d}:{:02d}'.format(mins, secs)
        print(timer, end="\r")
        time.sleep(1)
        t -= 1
    print('Done!')
Alan
  • 45,915
  • 17
  • 113
  • 134
  • Are you using any async library? (like asycio or thread) – Edher Carbajal Jan 15 '22 at 19:56
  • How exactly was it that was too much of a reach? Please [edit] your question and show your attempt. – martineau Jan 15 '22 at 20:17
  • Off-topic: `time.sleep()` is largely incompatible with `tkinter`. A common workaround is to use the universal [`after()`](https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/universal.html) widget method to update to the timer at regular intervals. – martineau Jan 15 '22 at 20:20
  • 1
    I think you need to define a `class Timer` that encapsulates the state of one and methods to change it (such as `start()`, `stop()`, `pause()`, and `add_30_secs()`). – martineau Jan 15 '22 at 20:24

1 Answers1

1

The problem is a little bit more complex than it appears for the following reasons:

  1. If you are not using any library for parallel events, then, the function countdown() will block the main loop and you will not be able to do anything (including click the button again to add more time) while the countdown is running

  2. If you want to add time with the same button, you have to check if there's already a countdown print on screen, if you don't check it, for each click a new clock will appear.

I suggest to use asyncio lib as follow:

import asyncio

# Create a global variable for the time
secs = 0 

#This function adds +30secs
def addTime():
    global secs
    secs+=30

#This is the func that gather the addTime function and the async clock
async def timerAction():
    #This "while" is used to simulate multiple cliks on your button. 
    # If you implement this as a callback delete the "while"
    while True: 
        j = 0 #Counter if a clock is already running
        addTime() #Add time
        for task in asyncio.all_tasks(): #This loop checks if there's a countdown already running
            if task.get_name()=='countdown':
                j+=1
        if j == 0: #If no running countdown, j==0, and fires the countdown
            taskCountdown = asyncio.create_task(countdown(), name='countdown')
        await asyncio.sleep(10) #Wait 10secs between each call to the func (each call simulate a click)
    

async def countdown():
    global secs
    while secs>0:
        mins, secs = divmod(secs, 60)
        timer = '{:02d}:{:02d}'.format(mins, secs)
        print(timer, end="\r")
        await asyncio.sleep(1)
        secs -= 1
    print('Done!')

asyncio.run(timerAction())

Output:

On the fisrt call:

00:30

after 10secs:

00:50

after 10secs:

01:10

and so on...

Edher Carbajal
  • 534
  • 3
  • 8