我正在使用 Python3(也使用 Tkinter)制作 mp3 付款器,但我正面临着死胡同 [英] I am making a mp3 payer in Python3 (also using Tkinter) but I am facing a dead end

查看:40
本文介绍了我正在使用 Python3(也使用 Tkinter)制作 mp3 付款器,但我正面临着死胡同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am making a menu func which adds songs to the player.

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)

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

Then afterwards I have a play button which is coded to play the song added -

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

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

So, the func, play()'s code is -

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无法打开和播放歌曲导致错误-

But here dong variable in play() is actually just the name of song as it is already split off in add_song().And pygame needs the entire path as the song is not in the same directory as the python file. So pygame cannot open and play the song resulting in the error -

  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 播放音乐创造任何问题??

So what can I do about this , is there another way where I can split off the path for displaying the song name creating no problems for pygame to play the music??

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

Also, I am using Windows 10 Pro , high end machine and using Python 3.

推荐答案

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

Since you are inserting the song on to the list box and play it from there, what you could do is, make a dictionary of index starting from 0 as key and values as list of song name and path, so its something like like song_dict = {idx:[song_name,song_path]}. So each idx will be your selection from the listbox. I have made an example with this, take a look:

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(),就像您在代码中所做的那样.

Just double click the song you want to play. You can also use a button instead of bind() like you do in your code.

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 文件并填充列表框.

Though I would also recommend to make a button to ask for directory and take all the mp3 files in that directory and populate the listbox.

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

If you want to use filedialog.askopenfilenames then you can edit the function as below:

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 循环中创建它们.

In this case you don't need the pre defined count variable, as we make them from the for loop.

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

Instead of using split, why not just use os.path, so you can get the basename from the path, like:

import os

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

这篇关于我正在使用 Python3(也使用 Tkinter)制作 mp3 付款器,但我正面临着死胡同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆