最近学习python,打算做一个小demo入门,于是利用wxPython GUI组件做了一个音乐播放器,遇到很多问题(每次切换歌曲都会卡一下,求大佬指教~~~~~~)
界面图:
代码如下
# 程序的界面设置类
import os
import wx
from wx.media import MediaCtrl
from MusicThread import MusicThread
class MusicPlayerGUI:
app = None
window = None
panel = None
# 音量滑块组件
sld = None
# 播放按钮
btn_play = None
# 下一首按钮
btn_next = None
# 上一首按钮
btn_pre = None
# 当前状态 默认为暂停状态 False : 暂停 True : 播放
status = False
# 播放组件
mc = None
# music 扫描路径
scanpath = "E:\music\\"
# 扫描组件页面组件框
scanpath_text = None
# load歌曲库按钮
btn_load = None
# 文件列表的数组
fileList = []
# 歌曲列表展示
lbl = None
# 当前歌曲播放下标
playindex = -1
# 播放线程
musicthread = None
first = True
def __init__(self):
self.InitView()
self.BindEvent()
self.LoadView()
# 初始化视图组件
def InitView(self):
self.app = wx.App()
self.window = wx.Frame(None, title="music player", size=(450, 700))
self.panel = wx.Panel(self.window)
self.btn_play = wx.Button(self.panel, label="播放")
self.btn_load = wx.Button(self.panel, label="load")
self.sld = wx.Slider(self.panel, value=50, minValue=1, maxValue=100, style=wx.SL_HORIZONTAL | wx.SL_LABELS)
self.mc = MediaCtrl(parent=self.panel, style=wx.SIMPLE_BORDER, szBackend=wx.media.MEDIABACKEND_WMP10)
self.btn_next = wx.Button(self.panel, label="下一首")
self.btn_pre = wx.Button(self.panel, label="上一首")
# 绑定事件
def BindEvent(self):
self.btn_play.Bind(wx.EVT_BUTTON, self.OnClicked)
self.sld.Bind(wx.EVT_SLIDER, self.OnSliderScroll)
self.btn_load.Bind(wx.EVT_BUTTON, self.LoadMusic)
self.btn_pre.Bind(wx.EVT_BUTTON, self.Pre)
self.btn_next.Bind(wx.EVT_BUTTON, self.Next)
self.mc.Bind(wx.media.EVT_MEDIA_LOADED, self.OnMediaLoaded)
self.mc.Bind(wx.media.EVT_MEDIA_PLAY, self.onPlay)
self.mc.Bind(wx.media.EVT_MEDIA_PAUSE, self.onPause)
# 组装视图
def LoadView(self):
boxSizer = wx.BoxSizer(wx.VERTICAL)
boxSizerH1 = wx.BoxSizer(wx.HORIZONTAL)
boxSizerH = wx.BoxSizer(wx.HORIZONTAL)
scanlbl = wx.StaticText(self.panel, -1, style=wx.ALIGN_CENTER)
scanlbl.SetLabel("输入歌曲库地址 : ")
self.scanpath_text = wx.TextCtrl(self.panel, value=self.scanpath)
boxSizerH1.Add(scanlbl)
boxSizerH1.Add(self.scanpath_text)
boxSizerH1.Add(self.btn_load)
boxSizerH.Add(self.btn_pre)
boxSizerH.Add(self.btn_play)
boxSizerH.Add(self.btn_next)
boxSizerH.Add(self.sld)
boxSizer.Add(boxSizerH1)
boxSizer.Add(boxSizerH)
boxSizerV = wx.BoxSizer(wx.VERTICAL)
self.lbl = wx.StaticText(self.panel, -1, style=wx.ALIGN_CENTER)
font = wx.Font(18, wx.ROMAN, wx.ITALIC, wx.NORMAL)
self.lbl.SetFont(font)
# self.lbl.SetLabel("")
boxSizerV.Add(self.lbl)
boxSizer.Add(boxSizerV)
self.panel.SetSizer(boxSizer)
# 上一首
def Pre(self, event):
# 我的歌单里有歌曲
if len(self.fileList) != 0 and self.playindex != -1:
# 如果当前是第一首
if self.playindex <= 0:
self.playindex = len(self.fileList) - 1
else:
self.playindex = self.playindex - 1
# self.musicthread.SetFileName(self.fileList[self.playindex])
self.musicthread.SetMessage(3)
print(self.mc.Load(self.fileList[self.playindex]))
# 下一首
def Next(self, event):
# 我的歌单里有歌曲
if len(self.fileList) != 0 and self.playindex != -1:
print(self.playindex)
# 如果当前是最后
if self.playindex >= len(self.fileList)-1:
self.playindex = 0
else:
self.playindex = self.playindex + 1
# self.musicthread.SetFileName(self.fileList[self.playindex])
self.musicthread.SetMessage(3)
print(self.mc.Load(self.fileList[self.playindex]))
print( self.playindex)
# 播放按钮点击事件的方法
def OnClicked(self, event):
print("play btn")
# 如果当前是播放状态
if self.status:
print("播放状态变成暂停")
self.status = False
self.btn_play.SetLabel("播放")
# self.mc.Pause()
if self.musicthread is not None:
self.musicthread.SetMessage(2)
else:
# 当前还未有播放下标
if self.playindex == -1 and len(self.fileList) >= 1:
self.playindex = 0
if self.playindex != -1:
# _thread.start_new_thread(self.MyPlayMusic, ())
if self.first:
print(self.mc.Load(self.fileList[self.playindex]))
self.first = False
else:
self.musicthread.SetMessage(1)
# self.MyPlayMusic()
print("暂停状态变成播放")
self.status = True
self.btn_play.SetLabel("暂停")
else:
self.MyPlayMusic()
# self.onPlay2()
# 子线程播放音乐
def MyPlayMusic(self):
print("子线程启动播放音乐")
print(self.mc)
if self.playindex != -1:
filename = self.fileList[self.playindex]
self.musicthread = MusicThread(self.mc, filename)
self.musicthread.SetMessage(1)
self.musicthread.start()
# print(self.mc.Load(self.fileList[self.playindex]))
# 音量的滑动触发方法
def OnSliderScroll(self, e):
obj = e.GetEventObject()
val = obj.GetValue()
# print(val)
self.mc.SetVolume(val/100)
def OnMediaLoaded(self, event):
print("onLoad event")
# print(self.mc.SetVolume(0.5))
self.MyPlayMusic()
# print(self.mc.Play())
# 播放音乐的方法
def onPlay(self, event):
print("play event ")
# 音乐暂停
def onPause(self, event):
print("pause event")
# 遍历文件下的所有歌曲
def listAllMusicInDir(self, filePath):
fileList = []
splitStr = []
for top, dirs, nondirs in os.walk(filePath):
for item in nondirs:
splitStr = item.split(".")
# 默认只需要mp3格式的文件名字
if "mp3" == splitStr[1]:
fileList.append(os.path.join(top, item))
return fileList
# 根据文件路径加载歌曲列表
def LoadMusic(self, event):
filePath = self.scanpath_text.GetValue()
self.fileList = self.listAllMusicInDir(filePath)
musicStr = ""
for item in self.fileList:
musicStr += item.split(".")[0].replace(filePath, "")
musicStr += "\n"
self.lbl.SetLabel(musicStr)
# 启动的方法
def start(self):
self.window.Show(True)
self.app.MainLoop()
if __name__ == '__main__':
musicPlayer = MusicPlayerGUI()
musicPlayer.start()
import threading
import wx
import time
class MusicThread(threading.Thread):
# 音乐播放组件
mc = None
# 音乐文件路径
filename = None
# 线程指令
message = 0
def __init__(self, mc, filename):
threading.Thread.__init__(self)
self.mc = mc
self.filename = filename
def SetMessage(self, message):
self.message = message
def SetFileName(self, filename):
self.filename = filename
def run(self):
try:
while True:
# 播放
if self.message == 1:
self.mc.Play()
# 暂停
elif self.message == 2:
self.mc.Pause()
# 切歌
elif self.message == 3:
self.mc.Stop()
break
print("歌曲结束")
except:
print("exit")