微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我正在使用 Python3也使用 Tkinter制作 mp3 付款器,但我正面临着死胡同

如何解决我正在使用 Python3也使用 Tkinter制作 mp3 付款器,但我正面临着死胡同

我正在制作一个向播放器添加歌曲的菜单功能

def add_song():
    song = filedialog.askopenfilename(initialdir='C:\\Users\\Soham\\Music',title="Choose a 
    song!",filetypes=(("mp3 Files","*.mp3"),))
    song_name = song.split("/")[-1].split(".")[0]
    song_list.insert(END,song_name)

然后我有一个播放按钮,它被编码来播放添加的歌曲 -

play_button = Button(controls_frame,image=play_button_img,borderwidth=0,command = play)
play_button.grid(row=0,column=2,padx=5)

所以,函数 play()代码是 -

def play():
    song = song_list.get(ACTIVE)
    pygame.mixer.music.load(song)
    pygame.mixer.music.play(loops=0)

但是这里 play() 中的 dong 变量实际上只是歌曲的名称,因为它已经在 add_song() 中分开了。而且 pygame 需要整个路径,因为歌曲与 python 文件不在同一目录中。所以pygame无法打开和播放歌曲导致错误-

  Exception in Tkinter callback
  Traceback (most recent call last):
       File "C:\Users\Soham\AppData\Local\Programs\Python\python39\lib\tkinter\__init__.py",line 
       1885,in __call__
       return self.func(*args)
       File "c:\Users\Soham\Desktop\HM MP.py",line 26,in play
  pygame.mixer.music.load(song)
  pygame.error: Couldn't open 'Avicii - The Nights'

那么我能做些什么呢,有没有另一种方法可以让我分开显示歌曲名称的路径,从而不会为 pygame 播放音乐造成任何问题??

另外,我使用的是 Windows 10 Pro、高端机器和 Python 3。

解决方法

您可以创建具有 dict

{'song name': 'file path'} ,

由于您将歌曲插入列表框并从那里播放,您可以做的是,制作一个索引字典,索引从 0 开始作为键,值作为歌曲名称和路径列表,所以它类似于像song_dict = {idx:[song_name,song_path]}。因此,每个 idx 都将是您从列表框中选择的。我用这个做了一个例子,看看:

from tkinter import *
from tkinter import filedialog
import pygame

root = Tk()
pygame.mixer.init()

song_dict = {} # Empty dict to assign values to it
count = 0 # An idx number to it increase later
def add_song():
    global count
    
    song_path = filedialog.askopenfilename(initialdir='C://Users//Soham//Music',title="Choose a song!",filetypes=(("mp3 Files","*.mp3"),))
    song_name = song_path.split("/")[-1].split(".")[0]
    song_dict[count] = [song_name,song_path] # Create the desired dictionary 
    song_list.insert(END,song_name) # Insert just the song_name to the Listbox

    count += 1 # Increase the idx number 

def play_song(*args):
    idx = song_list.curselection()[0] # Get the index of the selected item
    song = song_dict[idx][1] # Get the corresponding song from the dictionary 
    pygame.mixer.music.load(song) # Load the song
    pygame.mixer.music.play(loops=0) # Play the song


song_list = Listbox(root,width=50)
song_list.pack(pady=10)

choose = Button(root,text='Choose song',command=add_song)
choose.pack(pady=10)

song_list.bind('<Double-Button-1>',play_song) # Just double click the desired song to play

root.mainloop()

只需双击您要播放的歌曲。您也可以使用按钮代替 bind(),就像您在代码中所做的那样。

song_dict 的结构示例如下:

{0: ['Shawn Mendes - Perfectly Wrong','C:/PyProjects/sONGS/Shawn Mendes - Perfectly Wrong.mp3'],1: ['Lil Nas X - Old Town Road (feat','C:/PyProjects/sONGS/Lil Nas X - Old Town Road (feat. Billy Ray Cyrus) - Remix.mp3'],2: ['NF - Time - Edit','C:/PyProjects/sONGS/NF - Time - Edit.mp3']}

虽然我也建议制作一个按钮来询问目录并获取该目录中的所有 mp3 文件并填充列表框。

如果你想使用 filedialog.askopenfilenames 那么你可以编辑函数如下:

import os

def add_song():
    songs_path = filedialog.askopenfilenames(initialdir='C://Users//Soham//Music',title="Choose a song!")

    for count,song in enumerate(songs_path):
        song_name = os.path.basename(song)
        song_dict[count] = [song_name,song] # Create the desired dictionary 
        song_list.insert(END,song_name) # Insert just the song_name to the Listbox

在这种情况下,您不需要预定义的 count 变量,因为我们是从 for 循环中创建的。

编辑: 与其使用 split,不如使用 os.path,这样您就可以从路径中获取基本名称,例如:

import os

song_name = os.path.basename(song_path) # If its tuple then loop through and follow

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。