Hi, so I'm in the process of writing a music player with a GUI. I would like to be able to print a statement after I am done playing a song. I originally through I could just get away with getting the song's length and time.sleep'ing for that long. Since my GUI has a pause button, I think just using time.sleep is out of the question, as the song and the sleep function would become out of sync. So, how would I be able to accomplish my goal? Hopefully my question is clear enough...just ask if you need more information.

By the way, I am using tkSnack as my sound library.

Thanks in advance.

Dani AI

Generated

solved the immediate problem with a background timer thread, and 's point about shorter intervals is relevant — but the cleanest, safest pattern in a Tkinter app is to avoid blocking the main loop and avoid touching widgets from other threads. Two practical options that work reliably across older audio bindings (like tkSnack) are shown below.

Use the Tk event loop to poll elapsed time (no separate thread). Record a monotonic start time, update a GUI label with after, and detect completion by comparing elapsed to the known track length. This keeps all GUI work on the main thread and handles pause/resume deterministically.

import time
import tkinter as tk

track_length = 215.3  # seconds from the audio library
playing = False
start_time = 0.0
paused_accum = 0.0

def start_play():
    global playing, start_time, paused_accum
    start_time = time.monotonic()
    paused_accum = 0.0
    playing = True
    root.after(100, update_position)

def pause_play():
    global playing, paused_accum
    if playing:
        paused_accum += time.monotonic() - start_time
        playing = False

def resume_play():
    global playing, start_time
    if not playing:
        start_time = time.monotonic()
        playing = True
        root.after(100, update_position)

def update_position():
    if not playing:
        return
    elapsed = paused_accum + (time.monotonic() - start_time)
    if elapsed >= track_length:
        print("Finished!")
    else:
        # update a label or progress bar here
        root.after(100, update_position)

root = tk.Tk()
# wire start_play, pause_play, resume_play to buttons
root.mainloop()

Notes and tradeoffs: choose polling intervals based on UI needs — 50–200 ms is usually fine; 10 ms gives higher responsiveness but more CPU. For shortest code and minimal polling, schedule a single after for the remaining ms and cancel/reschedule it on pause/resume. If a background thread is required (for example, to query the audio backend), never update widgets directly from that thread — communicate via queue.Queue and call root.after to apply GUI changes. Prefer retrieving playback position or using an audio-library end callback when the library exposes those for sample-accurate completion detection (these are better than wall-clock timing). Relevant Python docs: tkinter, time.monotonic, threading.

Recommended Answers

All 4 Replies

I guess your audio toolkit of choice have state for checking status of playing stream. If true, then simple if will do the job on the timer event

if MY_AUDIO_STREAM_RUNNING== mytoolkit.FINISHED_PLAYING:
    print "Finished!" #here you print

so it will skip it each time until it finds stream have ended. Since I'm not sure if you are still using TkSnack then That is for now (I'm zero in TkSnack so sorry :))

Well, thanks for the suggestion, but tkSnack does not have anything close to that.

Okay, I've found my solution and I thought I would share it. Even though tkSnack cannot tell you if the stream is active or not, it does tell you how long a track is. Using that information, I used a thread to keep the elapsed time of a song (by sleeping for 0.5 seconds then updating the elapsed time).

Problem solved.

I think 10ms is the best for time accuracy :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.