|| [[http://wiki.wxpython.org/index.cgi/WxGladeWxWindow|Prev]] || [[http://wiki.wxpython.org/index.cgi/WxGladeTutorial|Up ]] || [[http://wiki.wxpython.org/index.cgi/WxGladeStatusbar|Next]] ||

= wxGlade tutorial - Events and Buttons =
(Contributed by Chris Lale, chrislale AT users DOT berlios DOT de)

'''Table of Contents:'''

<<TableOfContents>>

== Create the application in wxglade ==
Run wxglade. Open the simple project simple-glade.wxg that you created in "first steps" (WxGladeFirstSteps). The project consists of one empty frame. Set the title to "event-glade" and save it as event-glade.py. In the main (toolbox) window
 * Properties - <frame_1> -> Widget -> Title: event-glade
 * File -> Save -> /path/to/your/project/event-glade.wxg
 
The Tree shows that the application contains one frame and a sizer to added automatically by wxGlade.
 * `Application`
  * `frame_1 (MyFrame)`
   * `sizer_1`
 
== About the wx.Button class ==
A button is a control that contains a text string, and is one of the most common elements of a GUI. It may be placed on a dialog box or panel, or indeed almost any other window.

The constructor is `__init__(self, parent, id, label, pos, size, style, validator, name)`, but for simple purposes you only need to specify the first three: parent, id and label.

Look for wx.Button's methods in
 * wxWidgets manual -> Alphabetical class reference -> wxButton -> Members
 
and
 * wxPython API -> Classes -> Button -> Methods summary

== Add a button to the sizer ==

In the wxGlade toolbox window, double-click on `Add a button` icon. Then click inside the Design window to add the button `button_1`. Change the button's label to "Click me":
 * Properties <Button_1> -> Widget -> Label: Click me

The wx.Button instance method is added to `MyFrame`'s `__init()__` method:

{{{
#!python
     self.button_1 = wx.Button(self, -1, "Click me")
}}}
 
The code creates and shows the button.

Check the result:
 * Properties - <frame_1> -> Common -> Preview
 
==  Create an event handler for the button ==
An event handler is a piece of code that is executed when an event occurs (eg clicking on a button). wxGlade will create an empty method for this. You must add the instructions by hand after wxGlade has generated the application's code. Make sure that you choose not to overwrite existing code when you generate the application's code, so that you manually added instructions are preserved.
 * Properties <Button_1> -> Events
  * Event: EVT_BUTTON
  * Handler: !OnBtn1
 
Generate and inspect the code:
 * Tree -> Application
 * Properties -> Application
  * Overwrite existing sources: (untick)
  * Output path: /path/to/your/project/event-glade.py
  * Generate code

The frame's `__init__()` method now includes a method that binds an EVT_BUTTON event on button_1 to the !OnBtn1 method.
{{{
#!python
        self.Bind(wx.EVT_BUTTON, self.OnBtn1, self.button_1)
}}}

The !OnBtn1 method contains a placeholder line that writes a message to standard output when the button is clicked.
{{{
#!python
    def OnBtn1(self, event): # wxGlade: MyFrame.<event_handler>
        print "Event handler `OnBtn1' not implemented"
        event.Skip()
}}}

Replace this line with code that changes the button's label using wx.Button's `SetLabel()` method:
{{{
#!python
    def OnBtn1(self, event): # wxGlade: MyFrame.<event_handler>
        self.button_1.SetLabel("Ouch!")
        event.Skip()
}}}

Save `event-glade.py` and run it.

== Stock buttons ==

The preferred way to create standard buttons is to use a standard ID and an empty label. In this case wxWigets will automatically use a stock label that coresponds to the ID given. In additon, the button will be decorated with stock icons under GTK+ 2.

Create the button using the standard ID for an OK button like this:
 * Properties <Button_1> -> Widget -> Label: (blank)
 * Properties <Button_1> -> Common -> Id (ticked): wx.ID_OK

{{{
#!python
     self.button_1 = wx.Button(self, -1, "Click me")
}}}
becomes
{{{
#!python
     self.button_1 = wx.Button(self, wx.ID_OK, "")
}}}

Generate the code and run `event-glade.py`.

= Appendix: The complete code =
{{{
#!python
#!/usr/bin/env python
# -*- coding: ISO-8859-1 -*-
# generated by wxGlade 0.4.1 on Thu Mar 30 11:13:24 2006

import wx

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.button_1 = wx.Button(self, wx.ID_OK, "")

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.OnBtn1, self.button_1)
        # end wxGlade

    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle("event-glade")
        self.SetSize((350, 250))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_1.Add(self.button_1, 0, wx.ADJUST_MINSIZE, 0)
        self.SetAutoLayout(True)
        self.SetSizer(sizer_1)
        self.Layout()
        # end wxGlade

    def OnBtn1(self, event): # wxGlade: MyFrame.<event_handler>
        self.button_1.SetLabel("Ouch!")
        event.Skip()

# end of class MyFrame


class MyApp(wx.App):
    def OnInit(self):
        wx.InitAllImageHandlers()
        frame_1 = MyFrame(None, -1, "")
        self.SetTopWindow(frame_1)
        frame_1.Show()
        return 1

# end of class MyApp

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()
}}}