image/svg+xml
import wxapp = wx.PySimpleApp()frame = wx.Frame(None, -1, "Hello World")frame.Show(1)app.MainLoop()
-1 = system assigned ID
no parent
wxDialog
wxFrame
wxWindow
other displayedelements on thescreen
import wxclass MainWindow(wx.Frame): """ We simply derive a new class of Frame. """ def __init__(self,parent,id, title): wx.Frame.__init__(self,parent,wx.ID_ANY,title,size=(200,100), style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE) self.control = wx.TextCtrl(self,1,style=wx.TE_MULTILINE) self.Show(True)app = wx.PySimpleApp()frame=MainWindow(None,-1,'Small editor')app.MainLoop()
Derive your window fromwxFrame
def OnOpen(self,e): """ Open a file""" self.dirname = '' dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "*.*", wx.OPEN) if dlg.ShowModal() == wx.ID_OK: self.filename=dlg.GetFilename() self.dirname=dlg.GetDirectory() f=open(os.path.join(self.dirname,self.filename),'r') self.control.SetValue(f.read()) f.close() dlg.Destroy()
Dialogs
EVT_MENU(self, ID_ABOUT, self.OnAbout)def OnAbout(self, event): ...
import osimport wxID_ABOUT=101ID_EXIT=110class MainWindow(wx.Frame): def __init__(self,parent,id,title): wx.Frame.__init__(self,parent,wx.ID_ANY, title, size = ( 200,100), style=wx.DEFAULT_FRAME_STYLE| wx.NO_FULL_REPAINT_ON_RESIZE) self.control = wx.TextCtrl(self, 1, style=wx.TE_MULTILINE) self.CreateStatusBar() # A StatusBar in the bottom of the window # Setting up the menu. filemenu= wx.Menu() filemenu.Append(ID_ABOUT, "&About"," Information about this program") filemenu.AppendSeparator() filemenu.Append(ID_EXIT,"E&xit"," Terminate the program") # Creating the menubar. menuBar = wx.MenuBar() menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar self.SetMenuBar(menuBar) # Adding the MenuBar to the Frame content. wx.EVT_MENU(self, ID_ABOUT, self.OnAbout) # attach the menu-event ID_ABOUT to the # method self.OnAbout wx.EVT_MENU(self, ID_EXIT, self.OnExit) # attach the menu-event ID_EXIT to the # method self.OnExit self.Show(True) def OnAbout(self,e): d= wx.MessageDialog( self, " A sample editor \n" " in wxPython","About Sample Editor", wx.OK) # Create a message dialog box d.ShowModal() # Shows it d.Destroy() # finally destroy it when finished. def OnExit(self,e): self.Close(True) # Close the frame.app = wx.PySimpleApp()frame = MainWindow(None, -1, "Sample editor")app.MainLoop()
event.Skip()
...to skip the event
Events
wxFileDialog
wxMenuBar
wxStatusBar
wxToolBar
wxControl
wxButton
wxStaticText
wxTextCtrl
wxComboBox
...and so on and so forth...
wxPanel
enables tabbingbetween widgets
3 Placement Schemes
wxSizer subclasses
Manual Positioning
wxLayoutConstraints & "Delphi-like" LayoutAnchors
wxBoxSizer
wxGridSizer
wxFldexGridSizer
sizer.Add(window, weight, options...)sizer.AddMany(...)
wxBoxSizer(wxVERTICAL)
wxBoxSizer(wxHORIZONTAL) wxButton1 wxButtonTwo wxButton3
wxBoxSizer(wxHORIZONTAL) wxButtonFour wxButton5 wxButtonSix
Sizer's nest:
Placement
import wximport osID_ABOUT=101ID_OPEN=102ID_BUTTON1=110ID_EXIT=200class MainWindow(wx.Frame): def __init__(self,parent,id,title): self.dirname='' wx.Frame.__init__(self,parent,wx.ID_ANY, title, style=wx.DEFAULT_FRAME_STYLE| wx.NO_FULL_REPAINT_ON_RESIZE) self.control = wx.TextCtrl(self, 1, style=wx.TE_MULTILINE) self.CreateStatusBar() # A Statusbar in the bottom of the window # Setting up the menu. filemenu= wx.Menu() filemenu.Append(ID_OPEN, "&Open"," Open a file to edit") filemenu.AppendSeparator() filemenu.Append(ID_ABOUT, "&About"," Information about this program") filemenu.AppendSeparator() filemenu.Append(ID_EXIT,"E&xit"," Terminate the program") # Creating the menubar. menuBar = wx.MenuBar() menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar self.SetMenuBar(menuBar) # Adding the MenuBar to the Frame content. wx.EVT_MENU(self, ID_ABOUT, self.OnAbout) wx.EVT_MENU(self, ID_EXIT, self.OnExit) wx.EVT_MENU(self, ID_OPEN, self.OnOpen) self.sizer2 = wx.BoxSizer(wx.HORIZONTAL) self.buttons=[] for i in range(0,6): self.buttons.append(wx.Button(self, ID_BUTTON1+i, "Button &"+`i`)) self.sizer2.Add(self.buttons[i],1,wx.EXPAND) # Use some sizers to see layout options self.sizer=wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.control,1,wx.EXPAND) self.sizer.Add(self.sizer2,0,wx.EXPAND) #Layout sizers self.SetSizer(self.sizer) self.SetAutoLayout(true) self.sizer.Fit(self) self.Show(1) def OnAbout(self,e): d= wx.MessageDialog( self, " A sample editor \n" " in wxPython","About Sample Editor", wx.OK) # Create a message dialog box d.ShowModal() # Shows it d.Destroy() # finally destroy it when finished. def OnExit(self,e): self.Close(True) # Close the frame. def OnOpen(self,e): """ Open a file""" dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "*.*", wx.OPEN) if dlg.ShowModal() == wx.ID_OK: self.filename=dlg.GetFilename() self.dirname=dlg.GetDirectory() f=open(os.path.join(self.dirname, self.filename),'r') self.control.SetValue(f.read()) f.close() dlg.Destroy()app = wx.PySimpleApp()frame = MainWindow(None, -1, "Sample editor")app.MainLoop()
0: does not grow1+: pieces of the pie
wxEXPAND aka wxGROWvs. wxSHAPED (retain shape)weight 0? wxALIGN_CENTER_HORIZONTAL wxALIGN_CENTER_VERTICAL wxALIGN_CENTER wxALIGN_TOP wxALIGN_BOTTOM wxALIGN_LEFT wxALIGN_RIGHT
But: A sizer is not a parent window!It merely performs positioning.
sizer tree
widget tree
(positioning hierarchy)
(widget hierarchy)
yes, I want to use sizerfor positioning(redundant, unnecessary, in Python 2.4)
which sizer to use
apply size & positions, now
import wxapp = wx.PySimpleApp()frame = wx.Frame(None, -1, "Hello, world!")panel = wx.Panel(frame, -1)quote = wx.StaticText(panel, -1, "This is a hello world example.", wx.Point(20, 30))frame.Show(1)
Simple Example
More Complex Example
In Python2.4, youcan just call:self.SetSizerAndFit(sizer)
EVT_BUTTON(ctrl, id, cb)button clicks
EVT_TEXT(ctrl, id, cb)text changed
EVT_CHAR(ctrl, cb)key pressed
Event Table
event -> member functionevent -> member functionevent -> member function
* not virtual functions!* similar form:** take wxEvent derivative as sole arg** void return type
BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(wxID_EXIT, MyFrame::OnExit) EVT_MENU(DO_TEST, MyFrame::DoTest) EVT_SIZE( MyFrame::OnSize) EVT_BUTTON(BUTTON1, MyFrame::OnButton1)END_EVENT_TABLE
MyFrame
wxFrame
Example Event Table class hierarchy
event identified by type & ID#
not this one; no ID required
event does NOT have to originatefrom within the class---button clicks produce "Command Events,"which propagate up the window hierarchy
Panel instance
MyFrame instance
(wxFrame super-class)
Example Event Table window hierarchy
2 Hierarchies!
Button instance
DECLARE_EVENT_TABLE(at end of class)
::Connect(event_id=wxID_ANY, second_id=wxID_ANY, eventType, handler_cb, userdata, handling_object)
optional
optional
if NULL, "this" is used
eventtype
eventid
wxEventHandler
wxWindow
...the 10,000 things
Everything that handles eventsderives from wxEventHandler.
"wxCommandEvent" eventspropagate up thewindow hierarchy
MyFrame::OnSize should receivea wxEvent subclasss(wxSizeEvent, specifically)
wxEvent
wxCommandEvent
Event Handler Macros
wxEVENT_BUTTON_CLICKED
created with a "command type,"along with id of sender
a command type,for a wxCommandEvent,generated by a button click
Skip()
remember,no morehandlers areprocessed ifyou don't callSkip()
::ProcessEvent(event)
1. disabled? jump to 62. wxWindow? give wxValidators 1st crack at it3. SearchEventTable - failing that, try base class4. down "chain of event handlers"5. wxWindow? + wxCommandEvent? (or wxEvent ::ShouldPropagate?) ProcessEvent up the window hierarchy6. wxApp:ProcessEvent
Did it find something?(& Skip() wasn't called?)Stop when done.
When does it match?(AND (Event Type matches),(OR (id matches)(id is in range)(event table entry lists id #0)))
Processing endswith the first handler tohandle the event!To allow processing to continue,the handler must call Skip().
Remember:If you don't call Skip()from a handler,processing stops!You don't goany higher upthe window hierarchy.
Either there were no event handlers,or every handler performed a Skip().
SeveralwxEventHandlerscan be "hung off"of a wxWindowwith wxWindow::PushEventHAndler.
And beyond!If a wxFrame has a parent, the event keeps propagating up.But events do not propagate beyond for dialogs.You can change whether something propagates onor not past a given wxWindow, withwxWindow::SetExtraStyle(wxWS_EX_BLOCK_EVENTS)
Eventsin Detail