I have this bind "self.Bind(wx.EVT_LISTBOX, self.selLoadFile, listbox)". How would I add another function, I guess thats what youd call it. Like the self.selLoadFile, how would I add another function to the same event? I am making a music player and want the file to automatically play after it is selected. The self.selLoadFile function loads the file, how would I add the "self.Play" function to the same evt?
Thanks in advance!!
I'm sorry, I am new to programming. Could you help me out alittle? So if my functions where:
def selLoadFile(self, event):
my_selection = self.myListBox.GetStringSelection()
file_path = os.path.join(os.getcwd(),"songs",my_selection)
self.doLoadFile2(file_path)
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.mc.SetBestFittingSize()
self.mc.Play()
def Play(self, event):
self.mc.Play()
self.playbackSlider.SetRange(0,self.mc.Length())
How would I include all 3 of the above functions in one function?
If you want to bind a widget to two event handlers, then just do it. That will work as long as you call event.Skip() at the end of the handler code. Without this line the event will be consumed by the first handler and will not be caught by any additional handlers. Here's a silly example:
import wx
########################################################################
class MyPanel(wx.Panel):
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
btn = wx.Button(self, label="Press Me")
btn.Bind(wx.EVT_BUTTON, self.HandlerOne)
btn.Bind(wx.EVT_BUTTON, self.HandlerTwo)
def HandlerOne(self, event):
print "handler one fired!"
event.Skip()
def HandlerTwo(self, event):
print "handler two fired!"
event.Skip()
########################################################################
class MyFrame(wx.Frame):
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="Test")
panel = MyPanel(self)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
Related
I am making a quick and dirty soundboard using the wxPython package and was wondering how to go by implementing a scroll-list of sounds to play.
Here is a picture of what I am trying to convey:
http://i.imgur.com/av0E5jC.png
and here is my code so far:
import wx
class windowClass(wx.Frame):
def __init__(self, *args, **kwargs):
super(windowClass,self).__init__(*args,**kwargs)
self.basicGUI()
def basicGUI(self):
panel = wx.Panel(self)
menuBar = wx.MenuBar()
fileButton = wx.Menu()
editButton = wx.Menu()
exitItem = fileButton.Append(wx.ID_EXIT, 'Exit','status msg...')
menuBar.Append(fileButton, 'File')
menuBar.Append(editButton, 'Edit')
self.SetMenuBar(menuBar)
self.Bind(wx.EVT_MENU, self.Quit, exitItem)
wx.TextCtrl(panel,pos=(10,10), size=(250,150))
self.SetTitle("Soundboard")
self.Show(True)
def Quit(self, e):
self.Close()
def main():
app = wx.App()
windowClass(None)
app.MainLoop()
main()
My question remains, how does one load a list of sounds on that panel and click a certain button to play that sound. I don't really care about implementing pause and fast forward features since this is only going to play really quick sound files.
Thanks in advance.
Just removed the text widget, replaced by a listbox, and hooked a callback on item click, slightly elaborate: when clicking, it finds the position of the item, retrieves the label name and fetches the filename in the dictionary
(we want to play a .wav file with a path, but not necessarily display the full filename)
I refactored the code so callbacks and other attributes are private, helps the lisibility.
import wx
class windowClass(wx.Frame):
def __init__(self, *args, **kwargs):
super(windowClass,self).__init__(*args,**kwargs)
self.__basicGUI()
def __basicGUI(self):
panel = wx.Panel(self)
menuBar = wx.MenuBar()
fileButton = wx.Menu()
editButton = wx.Menu()
exitItem = fileButton.Append(wx.ID_EXIT, 'Exit','status msg...')
menuBar.Append(fileButton, 'File')
menuBar.Append(editButton, 'Edit')
self.SetMenuBar(menuBar)
self.Bind(wx.EVT_MENU, self.__quit, exitItem)
self.__sound_dict = { "a" : "a.wav","b" : "b.wav","c" : "c2.wav"}
self.__sound_list = sorted(self.__sound_dict.keys())
self.__list = wx.ListBox(panel,pos=(20,20), size=(250,150))
for i in self.__sound_list: self.__list.Append(i)
self.__list.Bind(wx.EVT_LISTBOX,self.__on_click)
#wx.TextCtrl(panel,pos=(10,10), size=(250,150))
self.SetTitle("Soundboard")
self.Show(True)
def __on_click(self,event):
event.Skip()
name = self.__sound_list[self.__list.GetSelection()]
filename = self.__sound_dict[name]
print("now playing %s" % filename)
def __quit(self, e):
self.Close()
def main():
app = wx.App()
windowClass(None)
app.MainLoop()
main()
I have a Frame and once the user clicks on the exit button, I want a dialogue box to open and ask him if he really wants to close the window.
So I did:
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
and then I have the Callback:
def OnCloseWindow(self, event):
dialog = wx.MessageDialog(self, message = "Are you sure you want to quit?", caption = "Caption", style = wx.YES_NO, pos = wx.DefaultPosition)
response = dialog.ShowModal()
if (response == wx.ID_YES):
Pairs = []
self.list_ctrl_1.DeleteAllItems()
self.index = 0
self.Destroy()
elif (response == wx.ID_NO):
wx.CloseEvent.Veto(True)
event.Skip()
This works, However, I get the error:
TypeError: unbound method Veto() must be called with CloseEvent instance as first argument (got bool instance instead)
How do I catch the closeWindows instance of the event that is raised?
You do not really need to do that much. If you catch the event and do not call event.Skip(), it does not get propagated forward. So if you catch the event and do not call event.Skip() or self.Destroy(), the window stays open.
import wx
class MainWindow(wx.Frame):
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
self.panel = wx.Panel(self)
self.Bind(wx.EVT_CLOSE, self.on_close)
self.Show()
def on_close(self, event):
dialog = wx.MessageDialog(self, "Are you sure you want to quit?", "Caption", wx.YES_NO)
response = dialog.ShowModal()
if response == wx.ID_YES:
self.Destroy()
app = wx.App(False)
win = MainWindow(None)
app.MainLoop()
You want to call event.Veto(True), not wx.CloseEvent.Veto(True). event is an instance of wx.CloseEvent - that's what you want to Veto. Right now you're trying to call Veto on the wx.CloseEvent class itself, which doesn't make sense.
I'am a new bie in python,I have to call a frame "Frame2" when I clic on a button from Frame1,I have this error:
this I my code:
global Frame2 fr
def OnButton4Button(self, event):
fr.Show()
even.Skip()
NB:I work with wxpython,and boa constructor
thanks fro help
You have several typos in your code. Here's a corrected example:
from Frame2 import fr
def OnButton4Button(self, event):
fr.Show()
event.Skip() # you need to spell event correctly
This assumes that Frame2 is a module. Most of the time, you don't need to use globals in Python.
To make this a bit easier to follow, I wrote an example that has a MainFrame class and a Frame2 class in the same module so you don't have to import anything or use globals:
import wx
########################################################################
class Frame2(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="Frame2")
panel = wx.Panel(self)
########################################################################
class MainFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="Main Frame")
panel = wx.Panel(self)
button = wx.Button(panel, label="Open Frame2")
button.Bind(wx.EVT_BUTTON, self.onButton)
self.Show()
#----------------------------------------------------------------------
def onButton(self, event):
""""""
frame = Frame2()
frame.Show()
event.Skip()
if __name__ == "__main__":
app = wx.App(False)
frame = MainFrame()
app.MainLoop()
In your short code you have an indentation on the second line, this is an error, you must write it like:
from Frame2 import fr
def OnButton4Button(self, event):
fr.Show()
event.Skip()
You may respect the indentation in Python like following example:
global var
def function():
#indented block
#should be always on the same column
condition = 1
if condition:
#new indented block
#is also aligned on a column
print "something"
#this is out of the IF block
#call the function
function()
In the PEP8 recommendations you will find the rules to avoid indenting errors.
Given the following simple program:
import wx
class TestDraw(wx.Panel):
def __init__(self,parent=None,id=-1):
wx.Panel.__init__(self,parent,id,style=wx.TAB_TRAVERSAL)
self.SetBackgroundColour("#FFFFFF")
self.Bind(wx.EVT_PAINT,self.onPaint)
self.SetDoubleBuffered(True)
self.circleX=320
self.circleY=240
def onPaint(self, event):
event.Skip()
dc=wx.PaintDC(self)
dc.BeginDrawing()
dc.DrawCircle(self.circleX,self.circleY,100)
dc.EndDrawing()
class TestFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(640,480))
self.mainPanel=TestDraw(self,-1)
self.Show(True)
app = wx.App(False)
frame = TestFrame(None,"Test App")
app.MainLoop()
How can I change it so that I can execute logic and repaint the panel at a constant rate? I'd like the circle to bounce around the screen, but I just can't figure out the place I would change its x and y variables.
Your can use a wxTimer to periodically call an onTimer(self) method.
What event is used when I close a tab in an auinotebook? I tested with
EVT_AUINOTEBOOK_PAGE_CLOSE(D). It didn't work.
I would also like to fire a right click on the tab itself event.
Where can I find all the events that can be used with the aui manager/notebook? Might just be my poor searching skills, but I can't find any lists over the different events that exist, not for mouse/window events either. It would be really handy to have a complete list.
#!/usr/bin/python
#12_aui_notebook1.py
import wx
import wx.lib.inspection
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
self.nb = wx.aui.AuiNotebook(self)
self.new_panel('Page 1')
self.new_panel('Page 2')
self.new_panel('Page 3')
self.nb.Bind(wx.EVT_AUINOTEBOOK_PAGE_CLOSED, self.close)
def new_panel(self, nm):
pnl = wx.Panel(self)
pnl.identifierTag = nm
self.nb.AddPage(pnl, nm)
self.sizer = wx.BoxSizer()
self.sizer.Add(self.nb, 1, wx.EXPAND)
self.SetSizer(self.sizer)
def close(self, event):
print 'closed'
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, '12_aui_notebook1.py')
frame.Show()
self.SetTopWindow(frame)
return 1
if __name__ == "__main__":
app = MyApp(0)
# wx.lib.inspection.InspectionTool().Show()
app.MainLoop()
Oerjan Pettersen
This is the bind command you want:
self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSED, self.close, self.nb)
To detect a right click on the tab (e.g. to show a custom context menu):
self.Bind(wx.aui.EVT_AUINOTEBOOK_TAB_RIGHT_DOWN, self.right, self.nb)
Here's a list of the aui notebook events:
EVT_AUINOTEBOOK_PAGE_CLOSE
EVT_AUINOTEBOOK_PAGE_CLOSED
EVT_AUINOTEBOOK_PAGE_CHANGED
EVT_AUINOTEBOOK_PAGE_CHANGING
EVT_AUINOTEBOOK_BUTTON
EVT_AUINOTEBOOK_BEGIN_DRAG
EVT_AUINOTEBOOK_END_DRAG
EVT_AUINOTEBOOK_DRAG_MOTION
EVT_AUINOTEBOOK_ALLOW_DND
EVT_AUINOTEBOOK_DRAG_DONE
EVT_AUINOTEBOOK_BG_DCLICK
EVT_AUINOTEBOOK_TAB_MIDDLE_DOWN
EVT_AUINOTEBOOK_TAB_MIDDLE_UP
EVT_AUINOTEBOOK_TAB_RIGHT_DOWN
EVT_AUINOTEBOOK_TAB_RIGHT_UP
From: {python folder}/Lib/site-packages/{wxpython folder}/wx/aui.py