Reputation: 71
Right, a back story. For my university project I am creating a rhythm teacher for the drums. So what the program will do is load up a drum notation, and an audio file matching that drum notation. The user presses the "Play" button, and it plays a short drum beat that matches the notation. So far I've got a button to play a loaded Wav. file, and another button to load up an image. I hope I'm making sense.
So my question is, does anyone have a function that will do this? As in, a button to load an image and an audio file together. And if the button is pressed again, it'll load another image and audio file, overwriting whatever was loaded before. I'll have a fair amount of images and audio files to load. Important bit is that the image has to match the audio file.
Again, I have a button that plays an audio file, another that just loads an image (I did this since I'm a newbie and was just learning how to do these functions.
I'll post a code anyway, and it should make more sense! Sorry if it's a long read! Just thought I'd put a back story on what I'm doing.
import wxversion
wxversion.select("2.8")
import wx
import wx.media
class MainWindow(wx.Frame):
title = "Main Menu"
def __init__(self, parent, id):
wx.Frame.__init__(self,parent,id,'Window', size=(1000,700))
panel=wx.Panel(self, -1)
self.SetBackgroundColour(wx.Colour(100,100,100))
self.Centre()
self.Show()
status=self.CreateStatusBar()
menubar=wx.MenuBar()
filemenu=wx.Menu()
exitmenu = filemenu.Append(wx.NewId(),"Exit", "Exit Program")
menubar.Append(filemenu,"File")
self.Bind(wx.EVT_MENU, self.onExit, exitmenu)
self.SetMenuBar(menubar)
font1 = wx.Font(30, wx.MODERN, wx.NORMAL, wx.NORMAL, False, u'Consolas')
Text1=wx.StaticText(panel, -1, "Rhythm Trainer", (10,15))
Text1.SetFont(font1)
Text1.SetForegroundColour('white')
btn1 = wx.Button(panel, label='Basic', pos=(100,200), size=(150, 50))
btn1.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.newwindow, btn1)
btn2 = wx.Button(panel, label='Advanced', pos=(100,270), size=(150, 50))
btn2.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
btn3 = wx.Button(panel, label='Notations', pos=(100,340), size=(150, 50))
btn3.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
btn4 = wx.Button(panel, label='Settings', pos=(100,410), size=(150, 50))
btn4.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
btn5 = wx.Button(panel, label="Quit", pos=(820, 550), size=(150, 50))
btn5.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.OnClick, btn5)
def OnClick(self, event):
self.Close()
def OnQuitButton(self, event):
wx.Sleep(1)
self.Destroy()
def onExit(self, event):
self.Destroy()
def newwindow(self, event):
secondWindow=window2(parent=None, id=-1)
secondWindow.Show()
class window2(wx.Frame):
title = "new Window"
def __init__(self, parent, id):
wx.Frame.__init__(self, parent, id, 'Window2', size=(1000,700))
panel=wx.Panel(self, -1)
self.SetBackgroundColour(wx.Colour(100,100,100))
self.Centre()
self.Show()
status=self.CreateStatusBar()
menubar=wx.MenuBar()
filemenu=wx.Menu()
exitmenu = filemenu.Append(wx.NewId(),"Exit", "Exit Program")
menubar.Append(filemenu,"File")
self.Bind(wx.EVT_MENU, self.onExit, exitmenu)
self.SetMenuBar(menubar)
font2 = wx.Font(30, wx.MODERN, wx.NORMAL, wx.NORMAL, False, u'Consolas')
Text2=wx.StaticText(panel, -1, "Rhythm Trainer", (10,15))
Text2.SetFont(font2)
Text2.SetForegroundColour('white')
self.Show(True)
btn1 = wx.Button(panel, label="Back", pos=(820, 550), size=(150, 50))
btn1.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.OnClick, btn1)
btn2 = wx.Button(panel, label="Play", pos=(820, 100), size=(150, 50))
btn2.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.onPlaySound, btn2)
btn3 = wx.Button(panel, label="Stop", pos=(820, 150), size=(150, 50))
btn3.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.onStopSound, btn3)
btn4 = wx.Button(panel, label="Next", pos=(820, 200), size=(150, 50))
btn4.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.loadImage, btn4)
self.panel = wx.Panel(self, -1, pos=(50,50), size=(800, 200))
def loadImage(self, event):
image_file = 'Rock-beats.jpg'
bmp = wx.Image(image_file, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
wx.StaticBitmap(self.panel, -1, bmp, pos=(200, 50), size=(417, 133))
# def onNext(self, event):
"""
Calls the nextPicture method
"""
#self.nextPicture()
def onPlaySound (self, event):
sound = wx.Sound('Test3.wav')
sound.Play(wx.SOUND_ASYNC)
def onStopSound(self, event):
wx.Sound.Stop()
def onExit(self, event):
self.Destroy()
wx.Sound.Stop()
def OnClick(self, event):
wx.Sound.Stop()
self.Close()
if __name__=='__main__':
app=wx.PySimpleApp()
frame=MainWindow(parent=None,id=-1)
Code 2.0 for Unutbu- Here's my full runnable code -
import wxversion
#wxversion.select("2.8")
import wx
import wx.media
import itertools as IT
import os
IMAGE_DIR = './'
SOUND_DIR = './'
class MainWindow(wx.Frame):
title = "Main Menu"
def __init__(self, parent, id):
wx.Frame.__init__(self,parent,id,'Window', size=(1000,700))
panel=wx.Panel(self, -1)
self.SetBackgroundColour(wx.Colour(100,100,100))
self.Centre()
self.Show()
status=self.CreateStatusBar()
menubar=wx.MenuBar()
filemenu=wx.Menu()
exitmenu = filemenu.Append(wx.NewId(),"Exit", "Exit Program")
menubar.Append(filemenu,"File")
self.Bind(wx.EVT_MENU, self.onExit, exitmenu)
self.SetMenuBar(menubar)
font1 = wx.Font(30, wx.MODERN, wx.NORMAL, wx.NORMAL, False, u'Consolas')
Text1=wx.StaticText(panel, -1, "Rhythm Trainer", (10,15))
Text1.SetFont(font1)
Text1.SetForegroundColour('white')
btn1 = wx.Button(panel, label='Basic', pos=(100,200), size=(150, 50))
btn1.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.newwindow, btn1)
btn2 = wx.Button(panel, label='Advanced', pos=(100,270), size=(150, 50))
btn2.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
btn3 = wx.Button(panel, label='Notations', pos=(100,340), size=(150, 50))
btn3.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
btn4 = wx.Button(panel, label='Settings', pos=(100,410), size=(150, 50))
btn4.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
btn5 = wx.Button(panel, label="Quit", pos=(820, 550), size=(150, 50))
btn5.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.OnClick, btn5)
def OnClick(self, event):
self.Close()
def OnQuitButton(self, event):
self.Destroy()
def onExit(self, event):
self.Destroy()
def newwindow(self, event):
secondWindow=window2(parent=None, id=-1)
secondWindow.Show()
self.Close()
class window2(wx.Frame):
title = "new Window"
def __init__(self, parent, id):
wx.Frame.__init__(self, parent, id, 'Window2', size=(1000,700))
panel=wx.Panel(self, -1)
self.images = IT.cycle([filename for filename in os.listdir(IMAGE_DIR) if filename.endswith('.jpg')])
self.image_file = None
#self.images = IT.cycle(os.listdir(IMAGE_DIR))
#self.image_file = next(self.images)
self.SetBackgroundColour(wx.Colour(100,100,100))
self.Centre()
self.Show()
status=self.CreateStatusBar()
menubar=wx.MenuBar()
filemenu=wx.Menu()
exitmenu = filemenu.Append(wx.NewId(),"Exit", "Exit Program")
menubar.Append(filemenu,"File")
self.Bind(wx.EVT_MENU, self.onExit, exitmenu)
self.SetMenuBar(menubar)
font2 = wx.Font(30, wx.MODERN, wx.NORMAL, wx.NORMAL, False, u'Consolas')
Text2=wx.StaticText(panel, -1, "Rhythm Trainer", (10,15))
Text2.SetFont(font2)
Text2.SetForegroundColour('white')
self.Show(True)
btn1 = wx.Button(panel, label="Back", pos=(820, 550), size=(150, 50))
btn1.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.OnClick, btn1)
btn2 = wx.Button(panel, label="Play", pos=(820, 100), size=(150, 50))
btn2.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.onPlaySound, btn2)
btn3 = wx.Button(panel, label="Stop", pos=(820, 150), size=(150, 50))
btn3.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.onStopSound, btn3)
btn4 = wx.Button(panel, label="Next", pos=(820, 200), size=(150, 50))
btn4.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.loadImage, btn4)
self.panel = wx.Panel(self, -1, pos=(50,50), size=(1000, 180))
def loadImage(self, event):
#image_file = 'Rock-beats.jpg'
#bmp = wx.Image(image_file, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
#wx.StaticBitmap(self.panel, -1, bmp, pos=(200, 50), size=(417, 133))
self.image_file = next(self.images)
image_file = os.path.join(IMAGE_DIR, self.image_file)
bmp = wx.Image(image_file, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
width = bmp.GetWidth()
height = bmp.GetHeight()
wx.StaticBitmap(self.panel, -1, bmp, pos=(200, 50), size=(width, height))
wx.Sound.Stop()
print(self.image_file)
# def onNext(self, event):
#"""
# Calls the nextPicture method
# """
#self.nextPicture()
def onPlaySound (self, event):
#sound = wx.Sound('Test3.wav')
#sound.Play(wx.SOUND_ASYNC)
sound_file, ext = os.path.splitext(self.image_file)
sound_file = os.path.join(SOUND_DIR, sound_file + '.wav')
sound = wx.Sound(sound_file)
sound.Play(wx.SOUND_ASYNC)
print(sound_file)
def onStopSound(self, event):
wx.Sound.Stop()
def onExit(self, event):
self.Destroy()
wx.Sound.Stop()
def OnClick(self, event):
wx.Sound.Stop()
self.Close()
mainwindow=MainWindow(parent=None, id=-1)
mainwindow.Show()
if __name__=='__main__':
app=wx.PySimpleApp()
frame=MainWindow(parent=None,id=-1)
frame.Show()
app.MainLoop()
Upvotes: 1
Views: 1304
Reputation: 879093
Here is one way you could do it:
First, define global variable(s) defining the directory which contains the images and wav files:
IMAGE_DIR = '/path/to/images'
SOUND_DIR = '/path/to/sounds'
You could use the same directory if you wish. I'm going to assume that
.jpg
,foo.jpg
then the associated wav file is
called foo.wav
.Next, in the window2.__init__
method define two new attributes:
self.images = IT.cycle([filename for filename in os.listdir(IMAGE_DIR) if filename.endswith('.jpg')])
self.image_file = None
and at the top of the file, import the itertools
module:
import itertools as IT
os.listdir(IMAGE_DIR)
returns a list of filenames. The IT.cycle
returns an iterable that cycles through the items in the list ad
infinitum.
next(self.images) returns the items in the iterable
self.images
one at a time -- a different one with each call to
next
. We'll use this below.
Now, loadImage
might be written like this:
def loadImage(self, event):
self.image_file = next(self.images)
image_file = os.path.join(IMAGE_DIR, self.image_file)
bmp = wx.Image(image_file, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
wx.StaticBitmap(self.panel, -1, bmp, pos=(200, 50), size=(417, 133))
and to play the associated wav file:
def onPlaySound(self, event):
sound_file, ext = os.path.splitext(self.image_file)
sound_file = os.path.join(SOUND_DIR, sound_file + '.wav')
sound = wx.Sound(sound_file)
sound.Play(wx.SOUND_ASYNC)
Since os.path.join and os.path.splitext are being used, be sure to import the os
module at the top of the file too.
Here is the code you posted with the suggested changes:
import wxversion
wxversion.select("2.8")
import wx
import wx.media
import itertools as IT
import os
IMAGE_DIR = os.path.expanduser('~/tmp/images')
SOUND_DIR = os.path.expanduser('~/tmp/sounds')
class MainWindow(wx.Frame):
title = "Main Menu"
def __init__(self, parent, id):
wx.Frame.__init__(self, parent, id, 'Window', size=(1000, 700))
panel = wx.Panel(self, -1)
self.SetBackgroundColour(wx.Colour(100, 100, 100))
self.Centre()
self.Show()
status = self.CreateStatusBar()
menubar = wx.MenuBar()
filemenu = wx.Menu()
exitmenu = filemenu.Append(wx.NewId(), "Exit", "Exit Program")
menubar.Append(filemenu, "File")
self.Bind(wx.EVT_MENU, self.onExit, exitmenu)
self.SetMenuBar(menubar)
font1 = wx.Font(
30, wx.MODERN, wx.NORMAL, wx.NORMAL, False, u'Consolas')
Text1 = wx.StaticText(panel, -1, "Rhythm Trainer", (10, 15))
Text1.SetFont(font1)
Text1.SetForegroundColour('white')
btn1 = wx.Button(panel, label='Basic', pos=(100, 200), size=(150, 50))
btn1.SetFont(
wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.newwindow, btn1)
btn2 = wx.Button(
panel, label='Advanced', pos=(100, 270), size=(150, 50))
btn2.SetFont(
wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
btn3 = wx.Button(
panel, label='Notations', pos=(100, 340), size=(150, 50))
btn3.SetFont(
wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
btn4 = wx.Button(
panel, label='Settings', pos=(100, 410), size=(150, 50))
btn4.SetFont(
wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
btn5 = wx.Button(panel, label="Quit", pos=(820, 550), size=(150, 50))
btn5.SetFont(
wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.OnClick, btn5)
def OnClick(self, event):
self.Close()
def OnQuitButton(self, event):
wx.Sleep(1)
self.Destroy()
def onExit(self, event):
self.Destroy()
def newwindow(self, event):
secondWindow = Window2(parent=None, id=-1)
secondWindow.Show()
self.Close()
class Window2(wx.Frame):
title = "new Window"
def __init__(self, parent, id):
wx.Frame.__init__(self, parent, id, 'Window2', size=(1000, 700))
panel = wx.Panel(self, -1)
self.SetBackgroundColour(wx.Colour(100, 100, 100))
self.Centre()
self.Show()
status = self.CreateStatusBar()
menubar = wx.MenuBar()
filemenu = wx.Menu()
exitmenu = filemenu.Append(wx.NewId(), "Exit", "Exit Program")
menubar.Append(filemenu, "File")
self.Bind(wx.EVT_MENU, self.onExit, exitmenu)
self.SetMenuBar(menubar)
font2 = wx.Font(
30, wx.MODERN, wx.NORMAL, wx.NORMAL, False, u'Consolas')
Text2 = wx.StaticText(panel, -1, "Rhythm Trainer", (10, 15))
Text2.SetFont(font2)
Text2.SetForegroundColour('white')
self.Show(True)
btn1 = wx.Button(panel, label="Back", pos=(820, 550), size=(150, 50))
btn1.SetFont(
wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.OnClick, btn1)
btn2 = wx.Button(panel, label="Play", pos=(820, 100), size=(150, 50))
btn2.SetFont(
wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.onPlaySound, btn2)
btn3 = wx.Button(panel, label="Stop", pos=(820, 150), size=(150, 50))
btn3.SetFont(
wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.onStopSound, btn3)
btn4 = wx.Button(panel, label="Next", pos=(820, 200), size=(150, 50))
btn4.SetFont(
wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, u'Consolas'))
self.Bind(wx.EVT_BUTTON, self.loadImage, btn4)
self.panel = wx.Panel(self, -1, pos=(50, 50), size=(800, 200))
self.images = IT.cycle(
[filename for filename in os.listdir(IMAGE_DIR)
if any(filename.lower().endswith(ext)
for ext in ('.png', '.jpg', '.jpeg'))])
self.image_file = next(self.images)
img = wx.EmptyImage(240,240)
self.imageCtrl = wx.StaticBitmap(self.panel, wx.ID_ANY,
wx.BitmapFromImage(img), pos=(200, 50))
def loadImage(self, event):
self.image_file = next(self.images)
print(self.image_file)
image_file = os.path.join(IMAGE_DIR, self.image_file)
img = wx.Image(image_file, wx.BITMAP_TYPE_ANY)
img = img.Scale(240,240)
# The idea of using imageCtrl.SetBitmap comes from
# http://www.blog.pythonlibrary.org/2010/03/26/creating-a-simple-photo-viewer-with-wxpython/
self.imageCtrl.SetBitmap(wx.BitmapFromImage(img))
def onPlaySound(self, event):
sound_file, ext = os.path.splitext(self.image_file)
sound_file = os.path.join(SOUND_DIR, sound_file + '.wav')
print(sound_file)
sound = wx.Sound(sound_file)
sound.Play(wx.SOUND_ASYNC)
def onStopSound(self, event):
wx.Sound.Stop()
def onExit(self, event):
self.Destroy()
wx.Sound.Stop()
def OnClick(self, event):
wx.Sound.Stop()
self.Close()
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = MainWindow(parent=None, id=-1)
app.MainLoop()
Upvotes: 2