4

我正在制作一个音乐播放器,一切顺利,除了当我点击下一个按钮时,它会加载下一首歌曲,但除非用户按下播放按钮,否则它不会播放。无论如何,只需点击下一个按钮就可以自动播放,而不必在之后按下播放按钮。我尝试将播放功能和加载功能绑定到按钮,但不起作用,我也尝试在我的加载功能中包含 mc.Play() ,但这也不起作用。

这是我的代码:

import wx
import wx.media
import os

class MainWindow(wx.Frame):

    def __init__(self,parent,id):
        wx.Frame.__init__(self,parent,id,'Music Player',size=(900,670),style=wx.MINIMIZE_BOX|wx.SYSTEM_MENU|wx.CAPTION|wx.CLOSE_BOX|wx.CLIP_CHILDREN)
        wx.Frame.CenterOnScreen(self)
        bg = wx.Image('bg.png', wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        self.bitmap1 = wx.StaticBitmap(self, -1, bg, (0,0))
        panel = wx.Panel(self,style=wx.STAY_ON_TOP)

        ##MENU AND STATUS BAR
        self.status = self.CreateStatusBar()
        self.status.SetStatusText('Ready')
        menubar = wx.MenuBar()
        file_menu = wx.Menu()
        view_menu = wx.Menu()
        controls_menu = wx.Menu()
        help_menu = wx.Menu()

        #MENU ID'S
        ID_FILE_LOAD = 2
        ID_FILE_EXIT = 3

        ID_VIEW_SHOW_STATUSBAR = 4

        ID_CONTROLS_PLAY = 5
        ID_CONTROLS_PAUSE = 6
        ID_CONTROLS_STOP = 7

        ID_HELP_ABOUT = 8

        ##FILE MENU
        file_menu.Append(ID_FILE_LOAD, "&Load...\tCtrl+L", "This will let you choose a song to load")
        file_menu.AppendSeparator()
        file_menu.Append(ID_FILE_EXIT,"Exit","This will exit the program")

        ##VIEW MENU
        self.check_statusbar = view_menu.Append(ID_VIEW_SHOW_STATUSBAR,'Show Stat&usbar\tCtrl+U', "This will disable the statusbar", kind=wx.ITEM_CHECK)
        view_menu.Check(self.check_statusbar.GetId(), True)

        ##CONTROLS MENU
        controls_menu.Append(ID_CONTROLS_PLAY,"&Play\tEnter", "Play the selected song")
        controls_menu.Append(ID_CONTROLS_PAUSE,"&Pause\tSpace", "Pause the selected song")

        ##MENUBAR APPEND
        menubar.Append(file_menu,"File")
        menubar.Append(view_menu,"View")
        menubar.Append(controls_menu,"Controls")
        menubar.Append(help_menu,"Help")
        self.SetMenuBar(menubar)

        ##MENU ACTION BINDING
        self.Bind(wx.EVT_MENU, self.Load, None, 2)        
        self.Bind(wx.EVT_MENU, self.Close, None, 3)
        self.Bind(wx.EVT_MENU, self.ToggleStatusBar, self.check_statusbar)
        self.Bind(wx.EVT_MENU, self.Play, None, 5)
        self.Bind(wx.EVT_MENU, self.Pause, None, 6)
        self.Bind(wx.EVT_MENU, self.About, None, 8)

        ##FONTS
        font1 = wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.BOLD)
        font2 = wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.BOLD)

        try:
            self.mc = wx.media.MediaCtrl(self)
        except NotImplementedError:
            raise

        ##BUTTONS

        bttnprt = self.bitmap1

        loadButton = wx.Button(bttnprt, -1, "Load File...", pos=(308,435), size=(281,31))
        self.Bind(wx.EVT_BUTTON, self.Load, loadButton)

        playButton = wx.Button(bttnprt, -1, "Play", pos=(458,491), size=(57,57))
        self.Bind(wx.EVT_BUTTON, self.Play, playButton)

        pauseButton = wx.Button(bttnprt, -1, "Pause", pos=(383,491), size=(57,57))
        self.Bind(wx.EVT_BUTTON, self.Pause, pauseButton)

        volumeUpButton = wx.Button(bttnprt, -1, "Up", pos=(400,299), size=(95,52))
        self.Bind(wx.EVT_BUTTON, self.onSetVolumeUp, volumeUpButton)

        volumeDownButton = wx.Button(bttnprt, -1, "Down", pos=(400,363), size=(95,52))
        self.Bind(wx.EVT_BUTTON, self.onSetVolumeDown, volumeDownButton)

        backButton = wx.Button(bttnprt, -1, "Back", pos=(308,491), size=(57,57))
        self.Bind(wx.EVT_BUTTON, self.previousSong, backButton)

        nextButton = wx.Button(bttnprt, -1, "Next", pos=(533,491), size=(57,57))
        self.Bind(wx.EVT_BUTTON, self.nextSong, nextButton)

        self.volumeCtrl = wx.Slider(bttnprt, value=50, minValue=0, maxValue=100, style=wx.SL_VERTICAL|wx.SL_INVERSE, pos=(300,300))
#        self.volumeCtrl.Bind(wx.EVT_SLIDER, self.onSetVolume)
        self.volumeCtrl.Hide()

        songlist = os.listdir('songs')
        self.myListBox = listbox = wx.ListBox(bttnprt, -1, (301,80), (296,206), songlist, wx.LB_SINGLE)

        self.Bind(wx.EVT_LISTBOX, self.selLoadFile, listbox)

#        self.st_file = wx.StaticText(bttnprt, -1, "Blank", pos=(30,30))

        def newWin(self, event):
            self.new = NewWindow(parent=self, id=-1)
            self.new.Show()

    def Close(self, event):
        box=wx.MessageDialog(None, 'Are you sure you want to exit?', 'Exit program?', wx.YES_NO)
        answer=box.ShowModal()
        if answer==wx.ID_YES:
            self.Destroy()

    def About(self, event):
        self.new = AboutWindow(parent=self, id=-1)
        self.new.Show()

    def selLoadFile(self, event):
            my_selection = self.myListBox.GetStringSelection()
            file_path = os.path.join(os.getcwd(),"songs",my_selection)
            self.doLoadFile2(file_path)

    def Load(self, event):
        dlg = wx.FileDialog(self, "Choose a media file", "songs", "", "*.*", wx.OPEN)
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            self.doLoadFile(path)
            dlg.Destroy() 

    def load2(self):
            my_selection = self.myListBox.GetStringSelection()
            file_path = os.path.join(os.getcwd(),"songs",my_selection)
            self.doLoadFile2(file_path)
            self.mc.Play()

    def doLoadFile(self, path):
        if not self.mc.Load(path):
            wx.MessageBox("Unable to load %s: Unsupported format?" % path, "ERROR", wx.ICON_ERROR | wx.OK)

        else:
            folder, filename = os.path.split(path)
            self.mc.SetBestFittingSize()
            self.mc.Play()

    def doLoadFile2(self, file_path):
        if not self.mc.Load(file_path):
            wx.MessageBox("Unable to load %s: Unsupported format?" % file_path, "ERROR", wx.ICON_ERROR | wx.OK)

        else:
            folder, filename = os.path.split(file_path)
            #self.st_file.SetLabel('%s' % filename)
            self.status.SetStatusText("Now Playing: " +'%s' % filename)
            self.mc.SetBestFittingSize()
            self.mc.Play()

    def Play(self, event):
        self.mc.Play()

    def Pause(self, event):
        self.mc.Pause()

    def onSetVolumeUp(self, event):

        self.currentVolume = self.volumeCtrl.GetValue()
        self.newVolumeAdd = self.currentVolume + 1.5
        self.volumeCtrl.SetValue(self.newVolumeAdd)

        self.mc.SetVolume(float(self.currentVolume) / 100)

    def onSetVolumeDown(self, event):
        self.currentVolume = self.volumeCtrl.GetValue()
        self.newVolumeSub = self.currentVolume - 1.5
        self.volumeCtrl.SetValue(self.newVolumeSub)

        self.mc.SetVolume(float(self.currentVolume) / 100)

    def previousSong(self, event):
        current = self.myListBox.GetSelection()
        new = current - 1
        self.myListBox.SetSelection(new)
        self.mc.Stop()
        self.load2()

    def nextSong(self, event):
        current = self.myListBox.GetSelection()
        new = current + 1
        self.myListBox.SetSelection(new)
        self.mc.Stop()
        self.load2()

    def ToggleStatusBar(self, e):
        if self.check_statusbar.IsChecked():
            self.status.Show()
            self.status.SetStatusText('Ready')
        else:
            self.status.Hide()

        ##RUN##

if __name__=='__main__':
        app=wx.PySimpleApp()
        frame=MainWindow(parent=None,id=-1)
        frame.Show()
        app.MainLoop()
4

1 回答 1

2

如果这是 Windows,可能特别是 Win 7、64 位,你需要做两件事才能让它工作。

  1. 正如 JF Sebastian 所提到的,您需要从绑定到 EVT_MEDIA_LOADED 事件的方法中调用 play。文档实际上提到了这一点。
  2. 创建 MediaCtrl 时指定后端。我不确定为什么需要它,但在我这样做之前它对我不起作用。

因此,请尝试以下更改:

...
#change this existing line
self.mc = wx.media.MediaCtrl(self, szBackend=wx.media.MEDIABACKEND_WMP10)
...
# add this new line
self.Bind(wx.media.EVT_MEDIA_LOADED, self.song_is_loaded)
...
# add this new method
def song_is_loaded(self, event):
    self.mc.Play()

您现在还可以删除所有 self.mc.Play() 调用,除了 Play() 函数本身中的调用(因为现在加载文件将导致它播放)。

我还注意到您已经定义了一堆 ID_XXX 常量,但是在绑定菜单按钮时只使用了数字。

于 2013-01-06T04:22:41.967 回答