Simple Pygame GUI Documentation

Last revision: 11/03/08
Written for version: 0.9.2


Table of Contents


Simple Pygame GUI Documentation.................................................................................................................................................. 1

Introduction............................................................................................................................................................................... 2

Quick-start................................................................................................................................................................................. 2

Embedding the GUI in your application............................................................................................................................... 2

Widgets....................................................................................................................................................................................... 3

Common Attributes............................................................................................................................................................ 3

Dynamic Attributes............................................................................................................................................................ 3

Widget creation................................................................................................................................................................... 4

Events................................................................................................................................................................................... 4

Widgets list.......................................................................................................................................................................... 4

Styles........................................................................................................................................................................................... 6

Label...................................................................................................................................................................................... 6

Button................................................................................................................................................................................... 6

ImageButton........................................................................................................................................................................ 7

Window................................................................................................................................................................................ 7

TextBox................................................................................................................................................................................. 7

CheckBox.............................................................................................................................................................................. 8

OptionBox............................................................................................................................................................................ 8

ListBox.................................................................................................................................................................................. 9

Built-in style creation functions................................................................................................................................... 10

Default styles.................................................................................................................................................................... 11

Conclusions............................................................................................................................................................................. 12


 

Introduction

Welcome to the documentation of the Simple Pygame GUI system, available at the page:-

http://www.pygame.org/project/740/

I'd like to say some preliminary things:

·        SPG library is still in development. The documentation will follow its progresses and changes made to the library will be reflected in updated documentation.

·         First I would like to thank the pygame community for its vivid help and support. Remember: this work is for pygame developers only.

·         I would like to apologize for my English as well. I'm trying to be as clear and correct as possible, but I can not guarantee this text will have no grammatic mistakes.

Enough talk now. Let's get started then!

Quick-start

Extract the zip somewhere and run the example file test.py. If everything is fine, as it should be if you have python and pygame correctly installed on your system, you will see a test application with the GUI in action.

Embedding the GUI in your application

To embed the gui module in your application, start by importing the module with

import gui

Be sure your python application can include the gui.py file.

Next all you need to do to get the system working is to create one, or as many that you need, desktops. A Desktop is a special widget, the root for all the other GUI widgets. When you want to see a widget on screen, you just add it to a desktop instance.

To create a new instance of a Desktop use the following:

Desktop = gui.Desktop()

The pygame events system will not be used, instead the GUI library is used to control event handling of input. To do this, simply use the GUI setEvents() function as followed:

#In the main loop
for e in gui.setEvents():
   #Your event handling here

instead of

#In the main loop
for e in pygame.event.get():
   #Your event handling here

Two method calls in your main loop are also required: the update() method and the draw() one.

#Main loop
for e in gui.setEvents():
   #Custom event handling here

   #... Logic updates here ...

   #Then finally update the active desktop
   desktop.update()

   #...Insert your renderings here...

   #Finally let the active desktop draw itself

   desktop.draw()

That’s all! You don’t need to modify your application structure to add some GUI: just create an instance of the Desktop by updating and drawing it each frame.

Widgets

A widget is the basic GUI component. Every button, label, window, etc is a widget. A desktop can only contain widgets.

Common Attributes

All widgets support the following attributes:

position

It indicates the relative position of the widget in the parent’s client rectangle. For instance, the client rectangle of a Desktop is the whole screen, while the client rectangle of a window is the rectangle of the window widget. This position is NOT the screen position of the widget but only its relative position to the parent’s position. This means that internally the library will add parent’s position to widget position when calculates the screen position of the widget for rendering, but this is completely transparent to you, so will never want to know  a widget screen position. Tuple in the format of (x, y).

size

Define the widgets size in pixels. Be warned that in some cases this attribute will be ignored, as in the case of a label with the “autosize” attribute set to true.
Tuple in the format of
(width, height)

parent

This attribute is fundamental . Every widget must have a parent, otherwise it will give you an error. The root of of each parent chain will always be a desktop. When you add a widget specifying a desktop as parent, you’re actually adding a widget directly onto the screen. At the current state there are only two objects which can be widget parents: the Desktop, and a Window. Do not try to implement any other kind of widget as a parent.

style

It’s a dictionary containing all the needed informations and style of the widget. You must always give a style to widgets, it is possible to create a shortcut to avoid passing the same style to all labels, instead setting the GUI default styles.

enabled

This attribute defines if a widget is active and able to receive user input. If it’s set to false, the widget will not change its status, generate events or interact with the user.

To set a widget attribute, do the following:

#This will set a new size for a label
myLabel.size = (150,100)

Dynamic Attributes

This GUI library is highly optimized to be as fast as possible. Widgets don’t completely draw themselves to the screen each frame. Internally, each widget has a refresh method which refreshes all or part of widget appearance each time you call the desktop.update() method. For instance, an event which makes a widget refresh, is when one of the dynamic attributes are changed. All common attributes such as position, size, etc are dynamic attributes,  a widget will automatically refresh when you change its size. You will never want to call the refresh method yourself, only desktop.update() needs to be invoked and all of its children will automatically be refreshed.

Widgets may have other custom dynamic attributes like the “text” attribute for a label or button.

Some people questioned  me about the reason for this mechanism. Well, it’s pretty simple: the reason is optimization! I’ll explain giving an example: let’s say you have a label and you change its text attribute many times during your logic “update” method in the same frame. If you don’t have a mechanism like that, you’ll have to refresh the text surface every time you change it, which is really not needed when only the last refreshed surface will be the one shown on the screen. Possibly you may refresh your widgets every frame, but why do this if the label text didn’t change? Using a system like this, the widget will refresh only when strictly needed, substantially increasing the frame rate.

Widget creation

To create a new widget, you use the following:

#You want to create a new label
myNewWidget = Label(position = (24,56), text = “Yahoo!”, parent = desktop)

You’ve may have noticed it does not specify the size as well as the style. When you create a new widget, the important and obligatory parameter is the parent only. If it is not specified, the position will be (0,0), the size will become the default (100, 20), the text will be the name of the widget and the style will be the default style set for that type of widget.

So remember: always set the widget’s parent while you can forget or ignore about the other parameters depending on what is required.

Callbacks

To add logic to your widgets, every GUI must have an event-based system. SPG uses a very pythonic way to do this. Every widget has four attributes: onClick, onMouseOver, onMouseDown and onMouseLeave. These attributes are called callbacks and must contain an user function with only one parameter, which is the widget that raised the event. Everything will be totally clear with an example:

#You have a Desktop instance called “desktop” ...

#This creates a button

myButton = Button(text = “Click me!”, parent = desktop)

#Define a function that will be called when the button is clicked
def myButton_onClick(widget):
   #The “widget” parameter is the widget which raised the event,   
   #“myButton” in this case. This will change myButton’s text.

   widget.text = “OK, you clicked me!”

#Finally set the myButton onClick attribute.
myButton.onClick = myButton_onClick

#The work is done :)

Desktop Callbacks

The Desktop class support callbacks too, and they should be used when you want to interact with the background. It is suggested you to use callbacks instead of handling pygame events such as MOUSEMOTION or MOUSEBUTTONDOWN because they do not know if between the mouse cursor and the background there is a widget.

Desktop

Most important class. Add all your widget to this container if you want them to be shown on screen.

Methods

Description

update()

Let all widgets to update.

draw()

Draws the desktop onto screen.

nextPosition(spacing)

Returns a (x, y) tuple which is the position after the last widget added, far a number of pixels equal to the spacing parameter (the Window widget support this method too)

Callbacks

Description

onClick(position, buttons)

Occurs when user clicks on it. position is the current mouse cursor absolute position while buttons is a tuple containing the status of the three mouse buttons.

onMouseDown(position, button)

Occurs when user presses the left mouse button on it. position is the current mouse cursor absolute position while button is the index of the pressed button (1, 2 or 3).

onMouseMove(position, buttons)

Occurs when mouse cursor leaves it. position is the current mouse cursor absolute position while buttons is a tuple containing the status of the three mouse buttons.

 

Widgets list

Let’s now have a look at the list of all supported widgets. The list contains a brief description about the widget, and all widget-specific attributes.

Label

A simple text container. Use it to show text on the screen. It supports word wrapping and auto sizing.

Attributes

Description

text

The text that will be shown inside the label.

Callbacks

Description

onClick

Occurs when user clicks on it.

onMouseDown

Occurs when user presses the left mouse button on it.

onMouseOver

Occurs when user moves mouse onto it.

onMouseLeave

Occurs when mouse cursor leaves it.

 

Button

A button is the easiest way to let the user interact with the application. When the user clicks on the button the set onClick function will be called to let you handle the event. It changes its appearance depending on its current state, that can be normal, when mouse is away from it, mouse-over, when mouse is on it but left button is not pressed, mouse-down when the mouse is over and left button is pressed, or disabled, when it’s not enabled.

Attributes

Description

text

The text that will be shown inside the label.

image

A pygame surface which will be shown instead of text if not None.

Callbacks

Description

onClick

Occurs when user clicks on it.

onMouseDown

Occurs when user presses the left mouse button on it.

onMouseOver

Occurs when user moves mouse onto it.

onMouseLeave

Occurs when mouse cursor leaves it.

 

ImageButton

It’s a button that does not contain text. It allows you to specify the image when in normal, mouse-over, mouse-down or disabled state.

Attributes

Description

-

-

Callbacks

Description

onClick

Occurs when user clicks on it.

onMouseDown

Occurs when user presses the left mouse button on it.

onMouseOver

Occurs when user moves mouse onto it.

onMouseLeave

Occurs when mouse cursor leaves it.

 

Window

A Window is a floating container which contains other widgets (except Desktops or other Windows). You can specify a window as a widget parent and it will be drawn inside the window.

Attributes

Description

text

The title of the window.

closeable

Indicates if the window will show the close button on the top-right corner.

Callbacks

Description

onClick

Occurs when user clicks on it.

onMouseDown

Occurs when user presses the left mouse button on it.

onMouseOver

Occurs when user moves mouse onto it.

onMouseLeave

Occurs when mouse cursor leaves it.

onClose

Occurs when user closes the window.

onMove

Occurs when window moving begins.

onMoveStop

Occurs when window moving ends.

onShade

Occurs when the window becomes shaded.

onUnshade

Occurs when the window becomes unshaded.

 

TextBox

Widget that allows user to insert text into a text box.

Attributes

Description

text

The current text contained in the TextBox.

Callbacks

Description

onClick

Occurs when user clicks on it.

onMouseDown

Occurs when user presses the left mouse button on it.

onMouseOver

Occurs when user moves mouse onto it.

onMouseLeave

Occurs when mouse cursor leaves it.

 

CheckBox

It’s drawn as a label next to a checkable item. It has only two values, checked or unchecked.

Attributes

Description

text

The text shown next to the check button image.

value

It’s the current status of the CheckBox: true if checked or false if unchecked.

Callbacks

Description

onClick

Occurs when user clicks on it.

onMouseDown

Occurs when user presses the left mouse button on it.

onMouseOver

Occurs when user moves mouse onto it.

onMouseLeave

Occurs when mouse cursor leaves it.

onValueChanged

Occurs when its value changes.

 

OptionBox

It’s very similar to a CheckBox, but it has a very important difference: if you add two or more OptionBoxes into the same container, only one can be checked. This means that if the user tries to check a not checked OptionBox while another in the same container is checked, this one will be unchecked while the other will be checked.

Attributes

Description

text

The text shown next to the check button image.

value

It’s the current status of the OptionBox: true if checked or false if unchecked.

Callbacks

Description

onClick

Occurs when user clicks on it.

onMouseDown

Occurs when user presses the left mouse button on it.

onMouseOver

Occurs when user moves mouse onto it.

onMouseLeave

Occurs when mouse cursor leaves it.

onValueChanged

Occurs when its value changes.

 

ListBox

It allows user to chose an option in a list of options. It can be used to simply show a list of rows as well, without caring about selection. If you want to add/remove values at runtime, it’s better to use addItem(item) and removeItem(item) methods because this will make the list to refresh on next update. If you use the python list append method to items, it’s not assured the new item will be shown.

Attributes

Description

items

A python list containing all the options

selectedIndex

Returns the index of the selected item.

Callbacks

Description

onClick

Occurs when user clicks on it.

onMouseDown

Occurs when user presses the left mouse button on it.

onMouseOver

Occurs when user moves mouse onto it.

onMouseLeave

Occurs when mouse cursor leaves it.

onItemSelected

Occurs when user selects an item from the list.

 

Styles

SPG (Simple Pygame GUI) is a style-based gui system. This means you create, for each GUI component (called widget), a style instance and, after setting all its parameters, you pass it to the single component, and it will have the exact look-and-feel you wanted.

Every widget must have a style, but this doesn’t mean you have to create one for every single widget you add to your desktop. Generally, you’ll create just one default style for every type of widget (such as buttons, labels, textboxes, etc.).

In SPG, a style is a dictionary. A rule is that every field must be fulfilled, except in some cases.

Let’s now have a detailed look on what styles need to be set:

Label

Key

Value

font

A pygame Font instance that will be used to render label text.

font-color

Tuple in the format (r, g, b) or (a, r, g, b) which identifies a color that will be used to draw the text.

bg-color

Tuple in the format (r, g, b) or (a, r, g, b) which identifies a color that will be used as the widgets background.

border-width

Integer. It represents the width of an eventual border drawn around the widget. Set it to 0 if you don’t want any.

border-color

Color of the border.

offset

(x, y) tuple which indicates the spacing from the top-left corner of the widget to the top-left corner of the text drawn inside. It can be compared to the padding in a CSS style. The x value indicates the horizontal spacing while the y value indicates the vertical spacing.

autosize

If set to true, the given size will be ignored and the widget will automatically fit its size to contain the text completely.

wordwrap

If set to true (and autosize is set to false), it will automatically dispose the text inside the widget, breaking the text lines when too long to fit inside.

antialias

If set to true, the text will be antialiased.

Button

Key

Value

font

A pygame Font instance that will be used to render label text.

font-color

This is a tuple in the format (r, g, b) or (a, r, g, b) which identifies a color that will be used to draw the text.

left-normal

A surface or subsurface (recommended!) that contains the left-most part of the button in the normal state.

middle-normal

Same as “left-normal”, but this will contain the image of the button in the middle. It must have the same height of the left-normal image, but don’t worry about the width because it will automatically tile along the button width.

right-normal

Same as “left-normal”, but it is for the right-most part.

do-over

Boolean. If set to true, the button will animate on mouse over, but you’ll have to give the following three fields as well. You can set it to false and it won’t change its appearance from the “normal” appearance when mouse crosses over it.

left-over

Surface or subsurface containing the left-most part of the button when is highlighted by the mouse.

middle-over

Same as “middle-normal”, but in the case the mouse cursor is over it.

right-over

Same as “right-normal”, but in the case the mouse cursor is over it.

do-down

Boolean. If set to true the button will animate showing a “mouse-down” state. You’ll need to give the following three surfaces or subsurfaces as well.

left-down

-

middle-down

-

right-down

-

do-disabled

Boolean. If set to true the button will animate showing a “disabled” state when its attribute “Enabled” is set to false, otherwise, even if set enable is set to false, it will show the normal appearance.

left-disabled

-

middle-disabled

-

right-disabled

-

ImageButton

Key

Value

image-normal

Surface or subsurface of the button when in the normal state.

do-over

Same as button “do-over” field. If set to true it will show the following surface when mouse is over it.

image-over

-

do-down

-

image-down

-

do-disabled

-

image-disabled

-

Window

Key

Value

font

A pygame Font instance that will be used to render label text.

font-color

This is a tuple in the format (r, g, b) or (a, r, g, b) which identifies a color that will be used to draw the text.

bg-color

Tuple in the format (r, g, b) or (a, r, g, b) which identifies a color that will be used as the widgets background.

border-width

Integer. It represents the width of an eventual border drawn around the widget. Set it to 0 if you don’t want any.

border-color

Color of the border.

offset

It’s a (x, y) tuple. It indicates where from to start rendering widgets. In other words, to obtain a widget screen position, the system adds the relative position of a widget to the window relative position and to its “offset” value.

close-button-style

An ImageButton style to assign to the close button.

TextBox

Key

Value

font

A pygame Font instance that will be used to render label text.

font-color

This is a tuple in the format (r, g, b) or (a, r, g, b) which identifies a color that will be used to draw the text.

bg-color-normal

The same format of font-color, but will be used as widget background when it doesn’t have focus.

bg-color-focus

This color will be used as background when focused instead of “bg-color-normal”.

border-width

Integer. It represents the width of an eventual border drawn around the widget. Set it to 0 if you don’t want any.

border-color-normal

Color of the border when not focused.

border-color-focus

Color of the border when focused.

appearance

Indicates the way the border will be drawn. Its possible values are gui.APP_FLAT or gui.APP_3D.

offset

It’s a (x, y) tuple which indicates the spacing between the TextBox corner and the text drawn inside.

antialias

If set to true, the text will be antialiased.

CheckBox

Key

Value

font

A pygame Font instance that will be used to render label text.

font-color-normal

This is a tuple in the format (r, g, b) or (a, r, g, b) which identifies a color that will be used to draw the text when the widget is not disabled.

font-color-disabled

As before, but when disabled.

border-width

Integer. It’s the width of an eventual border drawn around the widget. Set it to 0 if you don’t want any.

border-color

Color of the border.

spacing

Integer. It sets the distance between the image of the check button and the text.

autosize

If set to true, the given size will be ignored and the widget will automatically fit its size to contain the text completely.

wordwrap

If set to true (and autosize is set to false), it will automatically dispose the text inside the widget, breaking the text lines when too long to fit inside.

antialias

If set to true, the text will be antialiased.

checked-normal

Surface or subsurface of the CheckBox image when it’s checked and the mouse cursor is not over it.

checked-over

Surface or subsurface of the CheckBox image when it’s checked and the mouse cursor is over it.

checked-down

Surface or subsurface of the CheckBox image when it’s checked and mouse-pressed.

checked-disabled

Surface or subsurface of the CheckBox image when it’s checked and disabled.

unckecked-normal

Same as checked-normal but the CheckBox is unchecked.

unchecked-over

Same as checked- over but the CheckBox is unchecked.

unchecked-down

Same as checked- down but the CheckBox is unchecked.

unchecked-disabled

Same as checked- disabled but the CheckBox is unchecked.-

OptionBox

Key

Value

font

A pygame Font instance that will be used to render label text.

font-color-normal

This is a tuple in the format (r, g, b) or (a, r, g, b) which identifies a color that will be used to draw the text when the widget is not disabled.

font-color-disabled

As before, but when disabled.

border-width

Integer. It’s the width of an eventual border drawn around the widget. Set it to 0 if you don’t want any.

border-color

Color of the border.

spacing

Integer. It sets the distance between the image of the check button and the text.

autosize

If set to true, the given size will be ignored and the widget will automatically fit its size to contain the text completely.

wordwrap

If set to true (and autosize is set to false), it will automatically dispose the text inside the widget, breaking the text lines when too long to fit inside.

antialias

If set to true, the text will be antialiased.

checked-normal

Surface or subsurface of the OptionBox image when it’s checked and the mouse cursor is not over it.

checked-over

Surface or subsurface of the OptionBox image when it’s checked and the mouse cursor is over it.

checked-down

Surface or subsurface of the OptionBox image when it’s checked and mouse-pressed.

unckecked-normal

Same as checked-normal but the OptionBox is unchecked.

unchecked-over

Same as checked- over but the OptionBox is unchecked.

unchecked-down

Same as checked- down but the OptionBox is unchecked.

disabled

Surface or subsurface of the OptionBox image when it’s disabled.

ListBox

Key

Value

font

A pygame Font instance that will be used to render label text.

font-color                   

This is a tuple in the format (r, g, b) or (a, r, g, b) which identifies a color that will be used to draw the text of the item when it’s in a normal status.

font-color-over                      

Color item text when the mouse is over it.

font-color-selected

As before, but when the item is selected.

bg-color

Background color of the ListBox.

bg-color-over

Background color of the item focused by the mouse.

bg-color-selected

Background color of the selected item.

border-width

Integer. It’s the width of an eventual border drawn around the widget. Set it to 0 if you don’t want any.

border-color

Color of the border.

item-height

Integer. Height in pixels of a single row.

padding

Integer. Distance of the items text from ListBox borders.

autosize

If set to true, the given size will be ignored and the widget will automatically fit its size to contain the text completely.

antialias

If set to true, the text will be antialiased.

 

 

Built-in style creation functions

The GUI module comes with some pretty functions to help you to create styles easily and quickly.

Button: createButtonStyle(font, fontcolor, surface, *widths)

Attributes

Description

font

The font to use for the button.

fontcolor

The color of the text drawn on it.

surface

A surface containing all the images of all states of the button.

widths

A list containing all the widths for every part and status of the button. You must pass a list with 3, 6, 9 or 12 values (each triple is for one status: normal, mouse-over, mouse-down, disabled). So if you pass 6 values, it will set the normal and mouse-over status but not mouse-down and disabled.

Explanation:

To use this function, simply load an image structured like the following in a pygame surface:

For example, it may be like this:

The widths parameter is a list containing the width of each part in the order they’re presented in the previous scheme. The widths list of the example is [4,1,4,4,1,4,4,1,4,4,1,4].

Example:

createButtonStyle(defaultFont,(0,0,0),buttonsurf,4,1,4,4,1,4,4,1,4,4,1,4)

 

ImageButton: createImageButtonStyle(image, buttonWidth)

Attributes

Description

image

The surface containing the all status.

buttonWidth

The width of a single status image.

Explanation:

The image parameter is a surface containing all the status images of the ImageButton one next to the other in the order: normal, mouse-over, mouse-down, disabled.

The buttonWidth indicates the width of a single status image.

Example:

createImageButtonStyle(closeButtonSurf,12)

 

CheckBox: createCheckBoxStyle(font, image, singleImageWidth, font_color = (0,0,0), disabled_font_color = (150,150,150), spacing = 2, borderwidth = 0, bordercolor = (0,0,0), autosize = False, wordwrap = True, antialias = True )

Attributes

Description

font

The font to use.

image

The surface containing all the status images of the CheckBox.

singleImageWidth

The width of a single status image contained in the image parameter.

font_color

The color of the text in normal status.

disabled_font_color

The color of the text when the widget is disabled.

spacing

The distance between the image and the text.

borderwidth

The width of the border.

bordercolor

The color of the border.

autosize

-

wordwrap

-

antialias

-

Explanation:

The image parameter is a surface containing all the status images of the CheckBox one next to the other in the order: normal, mouse-over, mouse-down, disabled.

The singleImageWidth indicates the width of a single status image.

 

OptionBox: createOptionBoxStyle(font, image, singleImageWidth, fontcolor = (0,0,0), disabledfontcolor = (150,150,150), spacing = 2, borderwidth = 0, bordercolor = (0,0,0), autosize = False, wordwrap = True, antialias = True )

Attributes

Description

exactly as CheckBox

 

ListBox: createListBoxStyle(font, fontcolor, fontcolorover, fontcolorselected, bgcolor, bgcolorover, bgcolorselected, bordercolor = (0,0,0),  itemheight = None, padding = 3, antialias = True)

Attributes

Description

font

The font to use.

fontcolor

The color of the item text.

fontcolorover

The color of the item text when mouse cursor is over it.

fontcolorselected

The color of the text in normal status.

bgcolor

Background color of the ListBox.

bgcolorover

Background color of the item when mouse cursor is over it.

bgcolorselected

Background color of the item when selected.

bordercolor

The color of the border.

itemheight

Height in pixels of a single row. Leave it to None and it will find the best height itself.

padding

Distance between the items text and the ListBox borders.

antialias

-

 

Default styles

There is a shortcut to avoid passing the style to each widget you create. You can set the GUI module attributes to a default style and each new widget with no specified style will take the default style.

In the gui module these are the following attributes which can accept default styles:

·         defaultFont

·         defaultButtonStyle

·         defaultWindowStyle

·         defaultImageButtonStyle

·         defaultLabelStyle

·         defaultTextBoxStyle

·         defaultCheckBoxStyle

·         defaultOptionBoxStyle

·         defaultListBoxStyle

·         defaultComboBoxStyle

The library comes with an extra module called defaultStyle.py which contains sample styles. To use it, import the module and do as follows

defaultStyle.init(gui)

where gui is the module loaded from the file gui.py.

Conclusions

Thanks to everyone who collaborated to the library so far and thanks Luke for the English corrections ;)