All associated wiki pages:
BoxSizerFromTheGroundUp/DivideAndConquer |
Divide and Conquer
All the basics needed for nesting sizers with multiple controls have been covered. Let's get complicated now. Here's a screen shot of a music file player for MS Windows from Creative Labs. The task is to recreate the following GUI using wxPython. Ignore the fancy gradients, shading, custom bitmaps and such. Facsimiles can easily be added once the GUI has been constructed.
This may, at first, seem to be a rather daunting project at this time. Here's where a very fundamental and useful engineering principle known as Divide and Conquer can be effectively wielded. Simply stated, it means that a large task should be broken down into smaller, more manageable sub-tasks. Implement and test each sub-task on its own to make sure it works the way you want. Then, combine together these lower-level constructs into increasingly larger intermediate constructs and test them as you go along. In the end everything will be combined into a single and complete working solution.
Sounds simple, doesn't it ? While you are Dividing and Conquering you also are naturally organizing the project in a hierarchical fashion. This is not only to make the project easier to accomplish, but also make it far easier to understand, especially to everyone else.
Since this task's result is to be graphical the best tools to analyze it are graphical, too, such as produced by the tried-and-true pencil and paper. You could, instead, use graphical software apps such as MS Visio, Adobe Photoshop, HyperSnap-DX or similar programs to create drawings as I did. Here's a sketch of the control panel reduced to just the actual controls without all the fancy "eye candy" :
This simpler drawing makes the control panel much easier to analyze and break down into clusters of controls. This drawing isn't 100% accurate, but it's certainly close enough for analysis purposes. Here's a list of all the controls compiled by the use of simple visual inspection :
2 wx.StaticBitmap (logo image graphics)
22 wx.BitmapButton (provide a custom, but uniform button appearance)
- 2 wx.Gauge (The track's play index control/display slider; the volume control slider)
1 wx.StaticText (text caption for the logo bitmap)
3 wx.StaticText (currently playing track info)
Again, by simple observation all the control groups can be chosen that can be handled by specific sizers:
The blue boxes represent vertical box sizers, the green ones are horizontal. The solid rectangles are spacers of the most appropriate kind (fixed or proportional).
This drawing demonstrates why a container can have only a single overall sizer: If there were more than one top-level sizer, what would arrange them in the container relative to each other ?
This drawing is still too visually complicated and should be further broken down until only individual sizers and their controls are left to be implemented. I've tried to pick descriptive, but reasonably short names for the sizers.
Trying to work with poorly named variables is a sure path to needless confusion and frustration. Simply naming sizers "A" and "B", or "first" and "last", etc., will lead to certain insanity ! However, shortening the trailing "_vertSzr" to, say, "_vSzr" is perfectly appropriate, even desirable, but I'm to lazy to change all the images in this tutorial. Names that are a little too long are far better than names that are a little too short.
The GUI has been completely dissected. You've learned how to use BoxSizers to create each of the necessary control groups. You also know how to combine sizers and your own custom sizer-managed container classes within an overall encompassing sizer. Now is the best time for you to use these techniques to start out with something small and build up to something really useful.