Adding widgets to a frame

Figure 2.8 shows a custom frame subclass called InsertFrame. When the close button is clicked, the window will close and the application will end.

Listing 2.3 defines the wx.Frame subclass shown in figure 2.8. Not all of the concepts in this snippet have been covered yet, so don't worry if some things are not clear.

Figure 2.8 The InsertFrame window is an example demonstrating the basics of inserting items into a frame.

Figure 2.8 The InsertFrame window is an example demonstrating the basics of inserting items into a frame.

Listing 2.3 The InsertFrame code

#!/usr/bin/env python import wx class InsertFrame(wx.Frame)

Adding the button C . ,,, to the panel def _init_(self, parent, id): r wx.Frame._init__(self, parent, id, 'Frame With Button', size=(300, 100)) panel = wx.Panel(self) b Creating the panel button = wx.Button(panel, label="Close", pos=(125, 10), <—

self.Bind(wx.EVT_BUTTON, self.OnCloseMe, button) <—© Binding self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) <—, the button

I click event def OnCloseMe(self, event): Binding the WindoW Q

self.Close(True) close event def OnCloseWindow(self, event): self.Destroy()

frame = InsertFrame(parent=None, id=-1)

frame.Show()

app.MainLoop()

The__init__method of the InsertFrame class creates two subwindows O, ©.

The first is a wx.Panel, which is essentially a plain container for other windows and has little functionality of its own. The second is a wx.Button, which is an ordinary button. Next, the button click event and the close window event are bound to the function that will be executed when the event takes place ©, Q.

In most cases, you will create a single wx.Panel instance the same size as your wx.Frame to hold all of the contents of your frame. Doing so keeps the custom contents of the window separate from other elements such as the toolbar and status bar. In addition, on Windows operating systems, the default background color of a wx.Frame is not standard (it's gray, not white), while a wx.Panel will have a white background by default (assuming you haven't changed your system's color and theme settings). The wx.Panel class also enables traversal of the elements inside via the tab button, which wx.Frame does not.

If you are familiar with other UI toolkits, it may seem strange that you do not need to explicitly call an add method to insert a subwindow into a parent. Instead, in wxPython you just specify the parent window when the subwindow is created, and the subwindow is implicitly added inside that parent object, as is done in listing 2.3 ©.

You might also wonder why the wx.Button in listing 2.5 is created with an explicit position and size, while the wx.Panel is not. In wxPython, if a frame is created with just a single child window, then that child window (in this case, the wx.Panel) is automatically resized to fill the client area of the frame. This automatic resizing will override any position or size information for the child—even if a position or size had been specified for the panel, it would have been ignored. This automatic resizing only happens for a single element if it is within frames or dialogs. The button is a child of the panel, not the frame, so its specified size and position are used. If a size and position had not been specified for the button, it would have been placed in the default position, which is the upper left corner of the panel, with its size based on the length of the label.

Explicitly specifying the size and position of every subwindow can get tedious quickly. More importantly, it doesn't allow your application to reposition objects gracefully when the user resizes a window. To solve both of these problems, wxPy-thon uses objects called sizers to manage complex placement of child windows. Sizers will be covered briefly in chapter 7 and in more detail in part 2.

Was this article helpful?

0 0

Post a comment