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 ビットの場合、これを機能させるには 2 つのことを行う必要があります。

  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()

また、Play() 関数自体の呼び出しを除くすべての self.mc.Play() 呼び出しを削除することもできます (ファイルをロードすると再生されるため)。

また、一連の ID_XXX 定数を定義していることにも気付きましたが、メニュー ボタンをバインドするときに数値を使用しただけです。

于 2013-01-06T04:22:41.967 に答える