ALBOW
A Little Bit of Widgetry for PyGame
Version 2.1
This is a rather basic, no-frills widget set for creating a GUI using
PyGame. It was developed for use in PyWeek competition entries, and has
been used by the author in several such games so far.
Version 1.1 introduced a theme system
to provide a central place for customising the appearance of Albow
widgets, so you can easily give each of your games a distinctive look.
Version 2.0 adds a number of substantial new features, including TabPanel and
TableView widgets and improved TextField-based controls.
Version 2.1 adds drop-down and pop-up menus, music facilities and OpenGL capabilities.
Contents
Usage
Typical usage of the widget system is as follows:
- Initialize the PyGame display surface.
- Create an instance of RootWidget or subclass thereof (such as Shell), passing it the display surface.
- Create additional widgets if needed and add them as subwidgets of
the root widget. If using Shell, create the screens you will be using
and display your main screen.
- Start the frame timer if you will be using it (see RootWidget.set_timer()).
- Call the run() method of the root widget.
Constructors
There is a
convention used by the constructors of Widget and its subclasses. As
well as the arguments listed in the documentation for the class's
constructor, you can also pass initial values for any other attributes
of the class as keyword arguments.
You can do this for
attributes of your own Widget subclasses as well, if you pass on any
extra keyword arguments to the base class __init__ method. The only
requirement is that the attribute already exist as an instance or class
attribute, or as a property. This ensures that mistaken keyword
arguments are diagnosed rather than silently creating a new attribute.
Themes
Themes
provide a centralised way of customising the appearance of Albow
widgets on a per-class basis. There are three parts to the theme
system: theme properties, which are attributes that get looked up
automatically in the currently active themes; the Theme class,
instances of which hold values for the theme properties of a particular
class; and the theme module, which holds a default hierarchy of Theme
instances that your application can replace. See the documentation
pages on each of these for more details.
Events
Mouse events are classified into mouse_down, mouse_drag, mouse_up and mouse_move,
and are delivered by calling the corresponding method of the relevant
widget. Mouse-down events are delivered to the widget in which the
event occurs. Mouse-drag and mouse-up events are delivered to the
widget that received the last mouse-down event. Mouse-move events (with
no mouse button pressed) are delivered to the widget in which they
occur.
In addition to the usual PyGame event attributes, mouse events have the following extra attribute:
- local
- Position of the mouse in the local coordinate system of the widget to which it is delivered.
Keyboard events are delivered by calling the key_down or key_up methods of the widget having the current keyboard focus. A widget is given the keyboard focus by calling its focus()
method. If the focus widget does not handle a key event, it is
passed up the widget hierarchy until a handler is found.
Both mouse and keyboard events have a set of boolean attributes
indicating the state of the modifier keys at the time of the event:
- shift
- True if one of the Shift keys is down.
- ctrl
- True if the Control key is down.
- alt
- True if the Alt key (Option key on Macintosh) is down.
- meta
- True if the Meta key (Command key on Macintosh, Windows key on PC keyboards) is down.
- cmd
- True if
either the Control or Meta key is down. This can be used to implement
command keys that work according to either Macintosh or Linux/Windows
conventions.
OpenGL
Albow can be used in an OpenGL environment. To do this, create an OpenGL display surface (using pygame.display.set_mode()
with OPENGL in the flags) and pass it to the constructor of your root
widget. You can then add widgets derived from GLViewport to provide 3D
drawing areas, as well as ordinary 2D widgets.
There are a few
things to be aware of when mixing 2D and 3D widgets. When using OpenGL,
Albow distinguishes three kinds of widgets:
- 3D widgets -- GLViewport, GLOrtho, GLPerspective and classes derived from them.
- 2D
widgets -- most other Albow widgets. These are rendered to a temporary
surface which is then transferred to the screen using glDrawPixels.
- Container
widgets -- used for laying out other widgets. By default these are Row,
Column, Grid and classes derived from them. The root widget is also
considered a container widget.
Container widgets and 3D widgets can have any kind of widget as a subwidget, but 2D widgets can only contain other 2D widgets.
You can turn any 2D widget into a container widget by setting its is_gl_container property to true. However, when you do this, no drawing is performed for the widget itself -- its bg_color and border properties are ignored, and its draw() method is never called.
You can also turn a container widget back into an ordinary 2D widget by setting its is_gl_container property to false. You might want to do this, for example, to give a Row of buttons a background or border.
Something
to keep in mind is that drawing on 2D surfaces and transferring them to
an OpenGL window is usually much slower than drawing directly with
OpenGL. So if you want high performance, try to keep the window area
covered by 2D widgets to a minimum.Example Code
There are some programs in the demo directory that exercise many of the classes in the Albow library. You may find them useful as a source of usage examples.
---