Prev

Up

Next

wxGlade tutorial - First steps

(Contributed by Chris Lale, chrislale AT users DOT berlios DOT de)

Table of Contents:

Create an application in wxglade

Run wxglade.

There are three windows:

Now create an application. Select the first widget in the main window (Add a Frame), by clicking on it.

in the "Select frame class" popup choose

A new, empty window appears showing the design of your application. Its just an empty frame:

The Tree shows that the application contains one frame (window). wxGlade has automatically added a sizer to contain any other widgets you may wish to add later.

Set properties for the frame

In the Tree window, select frame_1(MyFrame).

In the Properties window, set the title. The title will appear at the top of the frame when you run the application.

In the Properties window, set a size for the frame.

Width and height sizes become active. If you are not happy with the sizes, change the size of the design window using the mouse. Alternatively, type new numbers into the Properties window.

Now is a good time to save the project. In the main window

Generate the Python code

In the Tree window, select Application.

In the Properties window, select

Click on

Run the application

Change to the directory containing simple-glade.py. Run the file from the commandline

./simple-glade.py

or

python simple-glade.py

Alternatively you can open the file in Idle and press F5 to run it.

The application is an empty window. It has a title, and you can move, resize and close it just like any other application.

Understanding the code

Open the simple-glade.py file in Idle or a text editor. The file is a Python module that can be run as a Python program.

Line 1 is the "hash-bang" line.

This line enables the file to be run directly (./simple-glade.py), rather than passing it to the Python interpreter (python simple-glade.py).

Line 5: import the Python GUI package.

   1 import wx

Imports wxPython classes, constants, etc into the module's namespace.

Lines 7-31: create a class for the frame

   1 class MyFrame(wx.Frame):
   2 ...
   3 # end of class MyFrame

This section creates a new frame class MyFrame, derived from the wxPython class wx.Frame

There are three methods. First is the frame's __init__() method.

   1     def __init__(self, *args, **kwds):
   2         # begin wxGlade: MyFrame.__init__
   3         kwds["style"] = wx.DEFAULT_FRAME_STYLE
   4         wx.Frame.__init__(self, *args, **kwds)
   5 
   6         self.__set_properties()
   7         self.__do_layout()
   8         # end wxGlade

This method

The next method sets the frame's properties.

   1     def __set_properties(self):
   2         # begin wxGlade: MyFrame.__set_properties
   3         self.SetTitle("simple-glade")
   4         self.SetSize((343, 510))
   5         # end wxGlade

These are the values for title and frame size that you chose in wxGlade. They are used to set the properties of the class MyFrame. MyFrame inherits these properties from the wx.Frame class, which in turn inherits them from the wx.Window base class. (Ref: http://www.wxpython.org/docs/api/wx.Window-class.html)

The third method defines the frame's layout.

   1     def __do_layout(self):
   2         # begin wxGlade: MyFrame.__do_layout
   3         sizer_1 = wx.BoxSizer(wx.VERTICAL)
   4         self.SetAutoLayout(True)
   5         self.SetSizer(sizer_1)
   6         self.Layout()
   7         # end wxGlade

sizer_1 = wx.BoxSizer(wx.VERTICAL) creates the sizer sizer_1, and sets its style to the built-in wx.VERTICAL. This is the default set by wxGlade. You did not have a choice for this sizer.

SetAutoLayout(True) determines that the Layout function will be called automatically when the window is resized.

SetSizer(sizer_1) sets the window's layout to consist only of the sizer sizer_1. Layout() invokes the sizer-based algorithm for this window.

SetAutoLayout(), SetSizer() and Layout() are methods inherited from the class wx.Window (see http://www.wxpython.org/docs/api/wx.Window-class.html).

<!> Warning:: the calls to SetAutoLayout(), Layout(), and Fit() (the latter appears in code generated by wxGlade > 0.4) are unnecessary; only one Fit() is necessary, at the top level (frame). This is just a performance issue.

<!> Warning:: In wxGlade > 0.4, the code generated also contains a call to sizer_1.SetSizeHints(self) which is WRONG. Actually, a more complex example would show that SetSizeHints() is called on most sizers. Such a call makes sense only for top-level windows (typically) and actually prevents proper sizing of your windows. E.g., if you have custom panels that involve dynamically changing the contents of your frame, then having the sizers SetSizeHints() called will prevent the sizers from computing the new "best fit". (Ref a post on wxpython-users mailing list, dated 2006-04-20; same post also archived here). Once I removed *all* the SetSizeHints() calls that wxGlade was putting in my files, the layouts were behaving as expected. You can also modify the source code of wxGlade: the file is wxGlade/edit_sizers/sizers_codegen.py; comment out the lines that have SetSizeHints(), in the three classes Python*SizerBuilder (one line per class). While you're at it, comment out the lines just above those that have SetAutoLayout() (if you also uncomment the ones that have Fit(), then you will be missing one call to Fit() in your top-level frame; which in the typical case will be necessary anyhow).

Lines 34-42 create a class for the application.

   1 class MyApp(wx.App):
   2 ...
   3 # end of class MyApp

It creates a new application class MyApp, derived from the wxPython class wx.App. It contains one method - the application's OnInit() method.

   1     def OnInit(self):
   2         wx.InitAllImageHandlers()
   3         frame_1 = MyFrame(None, -1, "")
   4         self.SetTopWindow(frame_1)
   5         frame_1.Show()
   6         return 1

This method is the start of the application (like "main" in C).

wx.InitAllImageHandlers() enables the module to handle a variety of image file formats (see http://wxwidgets.org/manuals/2.6.1/wx_appinifunctions.html#wxinitallimagehandlers).

frame_1 = MyFrame(None, -1, "") creates the application's window with parent=None, id=-1 (ie id set automatically) and title="" (ie no title). (More details of the default constructor parameters at http://wxwidgets.org/manuals/2.6.1/wx_wxframe.html#wxframector.)

self.SetTopWindow(frame_1) lets wxWidgets know which is the main window. (More details at http://wxwidgets.org/manuals/2.6.1/wx_wxapp.html#wxappsettopwindow.)

frame_1.Show() shows the window. Without this, the window would remain invisible. Note: frame_1.Show() is the same as frame_1.Show(True); frame_1.Show(False) would hide the window. (See http://www.wxpython.org/docs/api/wx.Window-class.html.)

Lines 44-46: the if __name__ trick

   1 if __name__ == "__main__":
   2     app = MyApp(0)
   3     app.MainLoop()

The simple-glade.py file is a python module. It can be imported into other python programs. The bottom three lines are a trick to enable the program to be run as a standalone program. If you run simple-glade.py directly, its __name__ attribute is __main__, so app = MyApp(0) and app.MainLoop() are invoked.

The gui platform and all the widgets have now been created and initialised.

app = MyApp(0) creates an instance of the application class MyApp, and calls the OnInit() method. It then sets the application's main window - there is only one window in this case, of course.

app.MainLoop() starts the event loop which continues until the application terminates or all the top level windows are closed. The event loop monitors the gui continuously. When it detects an event (eg a button press), it executes any code that has been bound to that event. Of course, we have not added any code to this example since there are no widgets to generate events!

Appendix: The complete code

   1 #!/usr/bin/env python
   2 # -*- coding: ISO-8859-1 -*-
   3 # generated by wxGlade 0.4.1 on Fri Mar 24 14:22:53 2006
   4 
   5 import wx
   6 
   7 class MyFrame(wx.Frame):
   8     def __init__(self, *args, **kwds):
   9         # begin wxGlade: MyFrame.__init__
  10         kwds["style"] = wx.DEFAULT_FRAME_STYLE
  11         wx.Frame.__init__(self, *args, **kwds)
  12 
  13         self.__set_properties()
  14         self.__do_layout()
  15         # end wxGlade
  16 
  17     def __set_properties(self):
  18         # begin wxGlade: MyFrame.__set_properties
  19         self.SetTitle("simple-glade")
  20         self.SetSize((343, 510))
  21         # end wxGlade
  22 
  23     def __do_layout(self):
  24         # begin wxGlade: MyFrame.__do_layout
  25         sizer_1 = wx.BoxSizer(wx.VERTICAL)
  26         self.SetAutoLayout(True)
  27         self.SetSizer(sizer_1)
  28         self.Layout()
  29         # end wxGlade
  30 
  31 # end of class MyFrame
  32 
  33 
  34 class MyApp(wx.App):
  35     def OnInit(self):
  36         wx.InitAllImageHandlers()
  37         frame_1 = MyFrame(None, -1, "")
  38         self.SetTopWindow(frame_1)
  39         frame_1.Show()
  40         return 1
  41 
  42 # end of class MyApp
  43 
  44 if __name__ == "__main__":
  45     app = MyApp(0)
  46     app.MainLoop()

WxGladeFirstSteps (last edited 2008-03-11 10:50:24 by localhost)