Python用tkinter库写一个音乐播放器的进度条

我用tkinter库写了一个音频播放器,用Scale弄了一个进度条滑块,我把音乐播放的路径存到了musiclist列表里面了,怎么能让滑块随着音乐的播放而往前走呢?

你可以使用set()函数来设置Scale组件的值。在音乐播放时,你可以在每一秒钟取当前的音乐播放时间,再将其除以总时长,然后将计算出的比例值传递给set()函数即可实现滑块随着音乐进度的移动。


import tkinter as tk
import pygame

class MusicPlayer:
    def __init__(self, master, music_list):
        self.music_list = music_list
        self.current_music_index = -1
        self.is_playing = False

        master.title("音乐播放器")
        master.geometry("400x200")

        self.scale = tk.Scale(master, from_=0, to=100, orient=tk.HORIZONTAL, length=300)
        self.scale.pack()

        self.play_pause_button = tk.Button(master, text="播放", command=self.play_pause_music)
        self.play_pause_button.pack()

        self.load_music()

    def load_music(self):
        if self.current_music_index < len(self.music_list) - 1:
            self.current_music_index += 1
        else:
            self.current_music_index = 0

        pygame.mixer.music.load(self.music_list[self.current_music_index])

    def play_pause_music(self):
        if not self.is_playing:
            pygame.mixer.music.play()
            self.is_playing = True
            self.play_pause_button.config(text="暂停")
            self.update_scale()
        else:
            pygame.mixer.music.pause()
            self.is_playing = False
            self.play_pause_button.config(text="播放")

    def update_scale(self):
        if self.is_playing:
            current_time = pygame.mixer.music.get_pos() / 1000
            total_time = pygame.mixer.Sound(self.music_list[self.current_music_index]).get_length()
            progress = (current_time / total_time) * 100
            self.scale.set(progress)
            self.scale.after(1000, self.update_scale)
        else:
            self.scale.set(0)

def main():
    pygame.mixer.init()

    music_list = ["music1.mp3", "music2.mp3", "music3.mp3"]

    root = tk.Tk()
    MusicPlayer(root, music_list)
    root.mainloop()

    pygame.mixer.quit()

if __name__ == "__main__":
    main()

在这段代码中,update_scale()是用来更新Scale组件滑块位置的函数。它首先获取当前音乐播放的时间和总时间,然后计算出比例值。最后使用set()函数来设置Scale组件的值。我们使用after()函数来调度下一次更新,这样可以保证滑块的更新系数与音乐播放的更新系数一致,从而实现滑块随着音乐进度的移动。最后需要注意的是,在关闭程序前需要调用pygame.mixer.quit()来释放音频资源。


import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
from pygame import mixer
from mutagen.mp3 import MP3


# 初始化Tkinter窗口
window = tk.Tk()
window.title("Music Player")
window.geometry("600x400")
file_path = None
# 初始化音乐播放器
mixer.init()


# 选择音乐文件
def choose_file():
    global file_path
    file_path = filedialog.askopenfilename()
    if file_path:
        play_music(file_path)


# 播放音乐
def play_music(file_path):
    mixer.music.load(file_path)
    mixer.music.play()

# 暂停音乐
def pause_music():
    mixer.music.pause()

# 继续播放音乐
def resume_music():
    mixer.music.unpause()

# 停止音乐
def stop_music():
    mixer.music.stop()

# 创建进度条
progress_bar = ttk.Progressbar(window, orient="horizontal", length=300, mode="determinate")

# 控制按钮
btn_choose = tk.Button(window, text="选择音乐", command=choose_file)
btn_play = tk.Button(window, text="播放", command=play_music)
btn_pause = tk.Button(window, text="暂停", command=pause_music)
btn_resume = tk.Button(window, text="继续", command=resume_music)
btn_stop = tk.Button(window, text="停止", command=stop_music)

# 布局控件
progress_bar.pack(pady=10)
btn_choose.pack(pady=5)
btn_play.pack(pady=5)
btn_pause.pack(pady=5)
btn_resume.pack(pady=5)
btn_stop.pack(pady=5)


# 更新进度条
def update_progress():
    if mixer.music.get_busy():
        global file_path
        duration = MP3(file_path).info.length
        current_position = mixer.music.get_pos() / 1000  # 获取当前播放位置(单位:秒)
        progress_bar['value'] = current_position * 100 / duration
    else:
        progress_bar['value'] = 0
    window.after(500, update_progress)  # 每半秒更新一次进度条


update_progress()

# 运行Tkinter事件循环
window.mainloop()