猫咪音乐播放器——使用python tkinter库制作精美GUI

本文介绍了如何使用Python的Tkinter库构建一个包含多种功能的图形用户界面,包括音乐播放控制、进度条和文件选择。通过Tkinter简单实现了一个带有太阳、小鸟、蜗牛等元素的界面,可以播放、暂停、切换歌曲和调整播放进度。
摘要由CSDN通过智能技术生成

Tkinter简介

Tkinter是Python中一个标准的图形用户界面(GUI)工具包,它提供了创建GUI应用程序的功能。Tkinter基于Tk图形库,它可以用来创建各种元素的窗口应用程序,如按钮、标签、文本框、复选框和菜单等。

Tkinter库简单易用,适合初学者入门GUI编程。它可以在几行代码内创建基本的GUI界面,并支持各种布局管理器,如pack、grid和palce,以便更灵活地设计界面。Tkinter支持事件处理和绑定,使用户能够在用户与界面元素交互时,执行特定的操作。

总的来说,Tkinter是Python中一个功能强大且易于学习和使用的GUI库,适用于开发简单的GUI应用程序。

功能介绍

程序运行结果如下

97bceb69dcf24fb9861de147647ef8d6.png

GUI界面为圆形,主要由猫咪(大),猫咪(小),梅花,太阳,草地,蜗牛,鸟(黄色),鸟(最右侧)组成。图中点击每个元素可实现播放器的一部分功能,程序功能如下:

4abde7354b6646b5950b3c3f5fce41db.png

  1. 太阳:点击太阳出现对话框,找到本地音乐储存位置,点击选取想要播放的音乐
  2. 猫咪(小):点击实现暂停播放功能;
  3. 鸟(最右侧):点击实现继续播放;
  4. 梅花:点击实现从头开始播放,或者打开应用时直接点击可播放上次选择的音乐;
  5. 蜗牛:进度条功能,显示播放进度,可拖动改变播放进度;
  6. 鸟(黄色):点击左右分别实现上一首,下一首;
  7. 草地:点击退出程序
  8. 鼠标中键按住拖动界面

代码与功能实现

import os
import sys
import pygame
from mutagen.mp3 import MP3
from tkinter import *
from tkinter import filedialog as fl
import win32gui
import win32con
import keyboard

def min_max_window():
    hwnd = win32gui.FindWindow(None, win.title())
    if hwnd:
        # 检查窗口当前是否最小化
        if win32gui.IsIconic(hwnd):
            win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
        else:
            win32gui.ShowWindow(hwnd, win32con.SW_SHOWMINIMIZED)

# 拖动界面
def drag(self):
    x = win.winfo_pointerx()
    y = win.winfo_pointery()
    win.geometry('+{x}+{y}'.format(x=x - 190, y=y - 100))


# 资源管理器
def find_one(self):
    root = Tk()
    root.withdraw()

    global first_path
    first_path = fl.askopenfilename()
    first_path = first_path.replace("/", "\\")
    # print(first_path)

    global first_path_1
    first_path_1 = os.path.split(first_path)[0]
    # print(first_path_1)

    global first_path_2
    first_path_2 = os.path.split(first_path)[1]
    # print(first_path_2)

    global file_list
    file_list = os.listdir(first_path_1)
    file_list = [file for file in file_list if file[-4:] in ['.mp3', '.flac']]
    # print(file_list)

    radio_play(self=None)


# 播放音乐的主函数
def radio_play(self):
    canvas.moveto(bgid_8, 100, 380)  # 蜗牛复位
    global now_path
    now_path = first_path
    pygame.init()
    pygame.mixer.init()  # 只初始化音频部分
    # 载入的音乐不会全部放到内容中,而是以流的形式播放的,即在播放的时候才会一点点从文件中读取。
    track = pygame.mixer.music.load(now_path)
    # 播放载入的音乐。该函数立即返回,音乐播放在后台进行。
    pygame.mixer.music.play(loops=1, start=0.0)
    print("已播放" + " " + now_path)
    get_timedata()  # 获取音乐时长
    try:
        win.after_cancel(solve)
    except:
        pass
    create_worm()
    # win.after_cancel(solve) 取消solve

    # 准备播放下一首
    # over_next(self)


# 设置蜗牛移动
def create_worm():
    try:
        if pygame.mixer.music.get_busy() == True:  # 检测有无歌曲播放
            one_time = int(duration_ / 0.23)
            canvas.move(bgid_8, 1, 0)
        else:
            one_time = 1000000
            pygame.time.wait(10)
            canvas.move(bgid_8, 500, 0)

        global solve
        solve = win.after(one_time, func=create_worm)
    except Exception:
        create_worm()


# 暂停播放
def btn_pause(self):
    print("已暂停" + " " + now_path)
    pygame.mixer.music.pause()
    canvas.move(bgid_8, -500, 0)


# 继续播放
def btn_unpause(self):
    print("已播放" + " " + now_path)
    pygame.mixer.music.unpause()
    create_worm()


# 播放下一首
def next_one(self):
    try:
        global first_path_2
        # print(first_path_2)
        index_1 = file_list.index(first_path_2)
        first_path_2 = file_list[index_1 + 1]
        # print(first_path_2)
        global first_path
        first_path = first_path_1 + "\\" + first_path_2
        radio_play(first_path)
    except:
        first_path_2 = file_list[0]
        # print(first_path_2)
        first_path = first_path_1 + "\\" + first_path_2
        radio_play(first_path)


# 播放上一首
def last_one(self):
    try:
        global first_path_2
        # print(first_path_2)
        index_1 = file_list.index(first_path_2)
        first_path_2 = file_list[index_1 - 1]
        # print(first_path_2)
        global first_path
        first_path = first_path_1 + "\\" + first_path_2
        radio_play(first_path)
    except:
        pass


# 获取音乐总时长
def get_timedata():
    global duration_
    duration = MP3(first_path_1 + "\\" + first_path_2)
    duration_ = float(duration.info.length)
    return duration_


# 获取音乐已经播放的时长
def get_nowpos():
    if pygame.mixer.music.get_busy() == True:
        music_pos = pygame.mixer.music.get_pos()
        return float(music_pos / 1000)
    else:
        return 1


# 拖动蜗牛改变进度
def drag_worm(self):
    pos_0 = canvas.coords(bgid_8) # 起始位置
    position_x = canvas.winfo_pointerx()  # 检测蜗牛上的鼠标位置
    pygame.time.wait(25)  # 15ms延时
    add_x = canvas.winfo_pointerx()  # 再次检测鼠标位置
    xx = add_x - position_x  # 计算两次移动距离
    canvas.move(bgid_8, xx, 0)  # 移动蜗牛到指定位置
    global position_
    position_ = canvas.coords(bgid_8)  # 检测蜗牛的位置

def change_musicpos(self):
    global musicpos  # 歌曲播放位置
    musicpos = int(((position_[0] - 100) / 230) * duration_)
    try:
        # pygame.mixer.music.set_pos(musicpos)
        pygame.mixer.music.play(loops=1, start=musicpos)
    except Exception as ee:
        print(ee)
        print(duration_)
        print(musicpos) 
 

def position_detect_next():
    position_ = canvas.coords(bgid_8)  # 检测蜗牛的位置
    if position_[0] > 490:
        next_one(self=None)
    else:
        pass
    win.after(100, position_detect_next)


# 蜗牛回到原点
def wrom_back():
    canvas.moveto(bgid_8, 100, 380)


# 结束程序
def t_close(self):
    with open("diary.txt", "w+", encoding="utf-8") as diary:
        diary.write(now_path + "\n")
    sys.exit(0)


if __name__ == "__main__":
    os.chdir("E:\\Project\\work_else_data\\猫咪播放器\\猫咪播放器")

    # 主窗口循环
    win = Tk()
    win.title("猫咪播放器")
    win.geometry('490x490+300+100')
    win.resizable(False, False)  # 窗口禁止拉伸
    win.overrideredirect(True)  # 窗体边框消失 
    win.wm_attributes("-transparentcolor", "blue")  # 蓝色部分透明

    # 使用画布显示图像
    canvas = Canvas(width=500, height=500)
    canvas.place(x=-1.5, y=-1.5)

    image_2 = PhotoImage(file='T2.png')
    canvas.create_image(250, 250, image=image_2)
    # 草:关闭界面
    image_3 = PhotoImage(file='Tw2.png')
    bgid_1 = canvas.create_image(120, 375, image=image_3, anchor='nw')
    # 图像绑定事件
    canvas.tag_bind(bgid_1, '<Button-1>', t_close)  #
    # 花:播放音乐
    image_4 = PhotoImage(file='xing.png')
    bgid_2 = canvas.create_image(170, 40, image=image_4, anchor='nw')
    canvas.tag_bind(bgid_2, '<Button-1>', radio_play)
    # 跑的鸟:继续播放
    image_5 = PhotoImage(file='paoniao.png')
    bgid_3 = canvas.create_image(400, 280, image=image_5, anchor='nw')
    canvas.tag_bind(bgid_3, '<Button-1>', btn_unpause)
    # 左侧猫:暂停
    image_6 = PhotoImage(file='mao2.png')
    bgid_4 = canvas.create_image(30, 180, image=image_6, anchor='nw')
    canvas.tag_bind(bgid_4, '<Button-1>', btn_pause)
    # 选取歌曲
    image_7 = PhotoImage(file="icon_2.png")
    bgid_5 = canvas.create_image(200, 20, image=image_7, anchor='nw')
    canvas.tag_bind(bgid_5, '<Button-1>', find_one)
    # 左侧鸟:切换为上一首歌曲
    image_8 = PhotoImage(file='niao.png')
    bgid_6 = canvas.create_image(185, 370, image=image_8, anchor='nw')
    canvas.tag_bind(bgid_6, '<Button-1>', last_one)
    # 右侧鸟:切换为下一首歌曲
    image_9 = PhotoImage(file='niao.png')
    bgid_7 = canvas.create_image(265, 370, image=image_9, anchor='nw')
    canvas.tag_bind(bgid_7, '<Button-1>', next_one)
    # 蜗牛:进度条
    image_10 = PhotoImage(file='woniu2.png')
    bgid_8 = canvas.create_image(100, 380, image=image_10, anchor='nw')
    canvas.tag_bind(bgid_8, '<B1-Motion>', drag_worm)
    canvas.tag_bind(bgid_8, '<ButtonRelease-1>', change_musicpos)


    # 绘制圆形
    canvas.create_oval(0, 490, 490, 0, fill="", outline="blue", width=25)

    
    # 添加右键移动功能
    win.offsetx = 0
    win.offsety = 0
    win.bind("<B2-Motion>", drag)
    
    # 绑定Alt + m快捷键到minimize_window函数
    keyboard.add_hotkey('Alt+w', min_max_window)

    try:
        with open("diary.txt", "r", encoding="utf-8") as diary:
            first_path = diary.read()[0:-1:1]

        global now_path
        now_path = first_path

        global first_path_1
        first_path_1 = os.path.split(first_path)[0]
        # print(first_path_1)

        global first_path_2
        first_path_2 = os.path.split(first_path)[1]
        # print(first_path_2)

        global file_list
        file_list = os.listdir(first_path_1)
        file_list = [file for file in file_list if file[-4:] in ['.mp3', '.flac']]
        # print(file_list)
    except:
        pass
    position_detect_next()
    win.mainloop()

代码如上,供学习使用,须在正确环境下运行;

所需图片以及源码放在压缩包中自取!

本项目为作者在大一时的娱乐作品,确有诸多不足之处还望包涵!

如无基础,可使用压缩包中的.exe执行文件

最后,欢迎大家来到我的小店办理流量卡Someity的小店

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值