Python脚本速成

9_进度条

# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import os # 地址

import pygame # 音乐
import time # 时间

# 安装 pygame:打开终端执行
# pip install pygame -i https://mirrors.aliyun.com/pypi/simple

# 初始化pygame的音频模块
pygame.mixer.init()

class GeneratedUI:
    """生成的Tkinter界面"""

    def __init__(self, master=None):
        # 创建主窗口
        self.master = master if master else tk.Tk()
        self.master.title("简易音乐播放器")
        self.master.geometry("300x650+700+100")
        self.master.configure(bg='white')

        # 全局变量:记录播放状态和进度
        self.播放状态 = "未播放"  # 未播放/播放中/暂停
        self.当前音乐路径 = ""
        self.开始播放时间 = 0
        self.暂停累计时长 = 0


        # 创建界面组件
        self.create_widgets()

        self.master.nametowidget("列表框_播放列表").delete(0, tk.END)

        # 指定目标文件夹路径(替换成你自己的文件夹路径)
        folder_path = r"./音乐"

        # 遍历文件夹,获取所有.mp3文件的完整路径
        mp3_paths = []
        for file_name in os.listdir(folder_path):
            # 判断文件是否以.mp3结尾
            if file_name.lower().endswith(".mp3"):
                # 拼接完整路径并添加到列表
                full_path = os.path.join(folder_path, file_name)
                mp3_paths.append(full_path)

        # 处理路径,移除指定前缀,只保留文件名(或相对路径)
        for path in mp3_paths:
            # 方法1:通用写法(推荐,跨系统兼容)
            # 只保留文件名(比如 "歌曲1.mp3")
            音乐的名称 = os.path.basename(path)

            self.master.nametowidget("列表框_播放列表").insert(tk.END, 音乐的名称)

        # 按钮点击事件

        self.master.nametowidget("按钮_播放").config(command=self.播放)
        self.master.nametowidget("按钮_暂停").config(command=self.暂停)
        self.master.nametowidget("按钮_继续").config(command=self.继续)

    def 获取播放进度(self):
        """获取当前播放进度(秒),返回:(已播放时长, 总时长)"""
        if self.播放状态 == "未播放":
            return (0, 0)

        # 获取音乐总时长
        总时长 = pygame.mixer.Sound(self.当前音乐路径).get_length()
        总时长 = round(总时长, 1)
        self.master.nametowidget("进度条_音乐").config(maximum=总时长)

        while True:
            # 计算已播放时长
            if self.播放状态 == "播放中":
                已播放时长 = time.time() - self.开始播放时间 + self.暂停累计时长
            else:  # 暂停状态
                已播放时长 = self.暂停累计时长

            # 防止进度超过总时长
            已播放时长 = min(已播放时长, 总时长)

            已播放时长 = round(已播放时长, 1)

            print("已播放时长:",已播放时长)

            self.master.after(0,self.更新进度,已播放时长)


            if 已播放时长 >= 总时长:
                self.master.nametowidget("进度条_音乐")["value"] = 0 # 重置进度条
                break # 跳出来

            time.sleep(0.2)

    def 更新进度(self,已播放时长):
        self.master.nametowidget("进度条_音乐")["value"] = 已播放时长


    def 播放(self):
        """播放指定路径的mp3文件"""
        选中索引 = self.master.nametowidget("列表框_播放列表").curselection()
        音乐名称 = self.master.nametowidget("列表框_播放列表").get(选中索引)

        播放地址 = f'./音乐/{音乐名称}'
        self.当前音乐路径 = 播放地址
        print( 播放地址)

        # 停止当前播放的音乐(如果有)
        pygame.mixer.music.stop()
        # 加载并播放音乐
        pygame.mixer.music.load(播放地址)
        pygame.mixer.music.play()
        # 更新状态
        self.播放状态 = "播放中"
        self.开始播放时间 = time.time()
        self.暂停累计时长 = 0

        #创建、启动线程
        import threading # 导入多线程库

        t = threading.Thread(target=self.获取播放进度)
        t.setDaemon(True)
        t.start()

    def 暂停(self):
        if self.播放状态 == "播放中":
            pygame.mixer.music.pause()
            self.暂停累计时长 += time.time() - self.开始播放时间
            self.播放状态 = "暂停"
            print("已暂停播放")

    def 继续(self):
        """继续播放暂停的音乐"""
        if self.播放状态 == "暂停":
            pygame.mixer.music.unpause()
            self.开始播放时间 = time.time()
            self.播放状态 = "播放中"
            print("已继续播放")

    def create_widgets(self):
        """创建所有界面组件"""

        # 列表框: 列表框_03604338 -> listbox_1
        self.listbox_1 = tk.Listbox(
            self.master,
            bg="white",
            fg="black",
            font=('微软雅黑', 10),
            name="列表框_播放列表"
        )
        self.listbox_1.place(
            x=8.0,
            y=67.0,
            width=284.0,
            height=542.0
        )
        self.listbox_1.insert(tk.END, "选项1")
        self.listbox_1.insert(tk.END, "选项2")
        self.listbox_1.insert(tk.END, "选项3")

        # 按钮: 按钮_9d693a25 -> btn_1
        self.btn_1 = tk.Button(
            self.master,
            text="播放",
            bg="#4CAF50",
            fg="white",
            font=('微软雅黑', 10),
            name="按钮_播放"
        )
        self.btn_1.place(
            x=21.0,
            y=20.0,
            width=70,
            height=25
        )

        # 按钮: 按钮_9530272a -> btn_2
        self.btn_2 = tk.Button(
            self.master,
            text="暂停",
            bg="#4CAF50",
            fg="white",
            font=('微软雅黑', 10),
            name="按钮_暂停"
        )
        self.btn_2.place(
            x=115.0,
            y=20,
            width=70,
            height=25
        )

        # 按钮: 按钮_cedcbbd1 -> btn_3
        self.btn_3 = tk.Button(
            self.master,
            text="继续",
            bg="#4CAF50",
            fg="white",
            font=('微软雅黑', 10),
            name="按钮_继续"
        )
        self.btn_3.place(
            x=211.0,
            y=20,
            width=70,
            height=25
        )

        # 进度条: 进度条_c2d3def9 -> progress_1
        self.progress_1 = ttk.Progressbar(
            self.master,
            name="进度条_音乐",
            length=285,
            maximum=100,
            value=0,
            mode="determinate"
        )
        self.progress_1.place(
            x=5.0,
            y=618.0,
            width=285,
            height=20
        )


def main():
    """主函数"""
    root = tk.Tk()
    app = GeneratedUI(root)
    root.mainloop()

if __name__ == "__main__":
    main()