Graphical user interfaces (GUIs) may be developed in Python using the GUI library.* Unlike many other GUI libraries, this library keeps simple things simple and makes complicated things possible.
To build a GUI, you have to create at least one display (window).
Once a display has been created, you populate it by placing various GUI widgets and graphics objects on it. The library provides various GUI widgets and graphics objects.
The origin (0, 0) of a display is at the top-left corner.
The following function creates a new Display, so you need to save it in a variable (in order to add GUI objects to it later).
Function |
Description |
Display(title, width, height) |
Creates a display window with the specified title (string — default is blank), width (default is 600 pixels), and height (default is 400 pixels). |
Display(title, width, height, x, y, color) |
Same as above, but also initial x and y position on screen (default is (0, 0) at top-left) and background color (default is Color.WHITE). |
For example, a display may be created as follows:
d = Display("Simple GUI", 120, 60)
Once a display has been created, you can add GUI widgets and other graphical objects, using the following function:
d.add(object, x, y)
where object is a GUI widget or graphical object (presented below). The coordinates x, y are optional and specify where in the display to place the object. If omitted, e.g.,
d.add(object)
the object is placed using its own coordinates (e.g., a line or a circle) specified when it was created (more below).
Once a display has been created, the following functions are available:
Display objects support drawing of various graphics objects. This is done with the following functions.
For convenience, each of the above functions returns the corresponding graphics object (e.g., drawLabel() returns a Label), which can be ignored or saved for further interaction, such as animation.
Widgets are used to present information and receive user input. The following widgets are available:
Below we present each of these objects in more detail.
Label objects are used to present labels and other permanent text on displays.
The following function creates a new Label, so you need to save it in a variable (so you can use it later).
Function |
Description |
Label(text, alignment) |
Creates a new label with specified text (string) and alignment (LEFT, CENTER, or RIGHT — default is LEFT). |
For example, a label may be created as follows:
label1 = Label("Hello World!")
Once a label has been created, it cannot be resized. So you should create it with the widest (possibly blank) string necessary, e.g.,
label1 = Label(" ") # up to 16 characters
Once a label has been created, it may be added to a Display, specifying where to place its top-left corner.
d.add(label1, 50, 50)
Also, the following functions are available:
Function |
Description |
label1.setText(text) |
Updates the contents of label1 to text (a string). |
label1.getText() |
Returns the text contained in label1 (as a string). |
label1.setFont() |
Changes the font used in label1, e.g., Font("Dialog", Font.PLAIN, 12) or Font("Serif", Font.ITALIC, 16). |
Button objects can be pressed by the user.
Pressing a Button calls a function. Which function to call is specified when the button is created.
The following function creates a new Button, so you need to save it in a variable (so you can use it later).
Function |
Description |
Button(text, function) |
Creates a new button containing text (a string). Every time the button is pressed, function is called automatically. This function should expect zero parameters. |
For example, a button may be created as follows:
button1 = Button("Play music", playMusic)
where playMusic is a function with zero parameters. This function will be called automatically when the user presses this button.
Once a Button has been created, it may be added to a Display, specifying where to place its top-left corner.
d.add(button1, 50, 50)
Checkbox objects can clicked (i.e., selected or deselected) by the user.
The following function creates a new Checkbox, so you need to save each in a unique variable (so you can use them later).
Function |
Description |
Checkbox(text, function) |
Creates a new checkbox with the specified text label (a string) and a function (optional) to be called every time the checkbox changes state. If provided, this function should expect one parameter (Boolean—signifies the changed state of the checkbox—True means checkbox was just checked, False means checkbox was just unchecked). |
For example, a checkbox may be created as follows:
checkbox1 = Checkbox()
Once a Checkbox has been created, it may be added to a Display, specifying where to place its top-left corner.
d.add(checkbox1, 50, 50)
If you create a Checkbox without using a callback function, then it is a passive GUI element. In other words, a different part of your program needs to check the state (selected, deselected) of the Checkbox. This can be done using the following functions:
Function |
Description |
checkbox1.isChecked() |
Returns True if checkbox1 is checked, False if unchecked. |
checkbox1.check() |
Sets checkbox1 (i.e., makes it appear checked). |
checkbox1.uncheck() |
Clears checkbox1 (i.e., makes it appear unchecked). |
If you create a Checkbox with a callback function, then that function will be called any time the changes state (checked, unchecked) by the user. The function should accept one parameter.
Slider objects contain an indicator which can be moved by the user to set a value.
The function below creates a new Slider, so you need to save it in a variable (so you can use it later).
Function |
Description |
Slider(orientation, lower, upper, start, function) |
Creates a new Slider with orientation (HORIZONTAL or VERTICAL—default is HORIZONTAL), lower value (integer—default is 0), upper value (integer—default is 100), placing the indicator at start value (integer—default is half-way). When the indicator is moved, function (optional) is called automatically. If provided, this function should expect one parameter (i.e., the new value of the slider). |
For example, a slider may be created as follows:
slider1 = Slider(VERTICAL, 0, 127, 50, changeVolume)
where changeVolume is a function which expects one parameter, the new value of the slider. When the function is called, it may use this value to update the volume of some musical material, for instance.
Once a Slider has been created, it may be added to a Display, specifying where to place its top-left corner.
d.add(slider1, 50, 50)
Additionally, you may use the following functions to get its current value:
Function |
Description |
slider1.getValue() |
Returns the current value of the slider (an integer between lower and upper). |
slider1.setValue(value) |
Sets the current value of the slider to value (an integer between lower and upper). |
DropDownList objects contain items which can be selected by the user.†
The following function creates a DropDownList, so you need to save it in a variable (so you can use it later).
Function |
Description |
DropDownList(items, function) |
Creates a drop-down list containing the provided items (list of strings, e.g. ["item1", "item2", "item3"]). When an item gets selected, function (optional) is called automatically. If provided, the function should expect one parameter (string—the selected item). |
For example, a drop-down list may be created as follows:
ddl1 = DropDownList(["item1", "item2", "item3"], itemSelected)
where itemSelected is a function which expects one parameter, the selected item (a string).
Once a DropDownList has been created, it may be added to a Display, specifying where to place its top-left corner.
d.add(ddl1, 50, 50)
TextField objects are used for entering text on a user interface.
The following function creates a TextField object, so you need to store it in a variable (or other memory location) to be able to use it later.
Function |
Description |
TextField(text, columns, function) |
Creates a text field containing specified text (a string—optional), with specified number of columns width (optional—default is 8), with function to call when the ENTER key is pressed in the text field. This function should expect one parameter (string—the contents of the text field). |
If you create a TextField with a callback function, then that function will be called any time the enter key is typed inside the box. (Presumably, the user will change the text and then press enter.)
For example, a text field may be created as follows:
text = TextField("type and hit <ENTER> ", 18, process-Entry)
where processEntry is a function which expects one parameter, the updated text (a string).
Once a TextField has been created, it may be added to a Display, specifying where to place its top-left corner.
d.add(textfield1, 50, 50)
If you create a TextField without using a callback function, then it is a passive GUI element. In other words, a different part of your program needs to manage (e.g., check for change in) the text content. This can be done using the following functions:
Function |
Description |
textField.getText() |
Returns the text contained in the text field (as a string). |
textField.setText() |
Sets the text contained in the text field (as a string). |
textField.setFont() |
Changes the font used in the text field, e.g., Font("Dialog", Font.PLAIN, 12) or Font("Serif", Font.ITALIC, 16). |
TextArea objects are used for entering text that may span several lines.
Function |
Description |
TextArea(text, rows, columns) |
Creates a text area containing the given text (string) with the given rows (default 5) and columns (default 400). If the text exceeds the text area dimensions, a slider bar will appear on the right. |
Once a TextArea has been created, it may be added to a Display, specifying where to place its top-left corner.
d.add(textarea1, 50, 50)
A TextArea is a passive GUI element. You can access its contents with the following functions:
Function |
Description |
textArea.getText() |
Returns the text contained in the text area (a string). |
textArea.setText() |
Sets the text contained in the text area (a string). |
textArea.setFont() |
Changes the font used in the text area, e.g., Font("Dialog", Font.PLAIN, 12) or Font("Serif", Font.ITALIC, 16). |
Icon objects contain external images (.jpg or .png). They are created using the following functions.
Function |
Description |
Icon(filename) |
Imports an image from the given filename (e.g. "apple.jpg" or "apple.png"). |
Icon(filename, width) |
Imports an image from the given filename and resizes it (proportionally) using the provided width (in pixels). |
Icon(filename, width, height) |
Imports an image from the given filename and resizes (stretches) it using the provided width and height (in pixels). |
Once an Icon has been created, it may be added to a Display, specifying where to place its top-left corner point.
d.add(icon1, 50, 50)
Additionally, you may use the following functions:
Function |
Description |
icon.setSize(width, height) |
Changes/stretches the width and height of an image (in pixels). |
icon.getWidth() |
Returns the width of an image (in pixels). |
icon.getHeight() |
Returns the height of an image (in pixels). |
icon.rotate(angle) |
Rotates the image angle degrees. |
icon.crop(x, y, width, height) |
Crops the image starting from point x, y up to width and height (from the point x, y). |
The GUI library simplifies creation of Menu objects. A display has a menu bar at the top. This is initially empty. Menu items may be added to it (e.g., “File”, “Edit”, etc.). Menus can also be added to a display (or any other graphical object, for that matter), as pop-up menus (i.e., menus that come up when you press the right mouse button).
Menu objects are created using the following function:
Function |
Description |
Menu(menuName) |
Creates a new Menu with the specified name. |
Once a menu has been created, it can be populated with items using the following functions:
Function |
Description |
menu.addItem(item, functionName) |
Adds item (string) to the menu and specifies which function to call when item is selected. |
menu.addItemList(itemList, functionNameList) |
Adds a list of items (a list of strings) to the menu and specifies the corresponding functions to call (one function per item). The two lists are parallel (and thus need to be of equal length). |
menu.addSeparator() |
Adds a separator line to the menu. |
menu.addSubmenu(menu) |
Adds a submenu to the menu. Used for creating hierarchical menus. |
menu.enable() |
Enables the menu (active). |
menu.disable() |
Disables/grays out the menu (inactive). |
Once a menu has been created, it can be added to a display as follows:
Function |
Description |
d.addMenu(menu) |
Adds menu to the menu bar (left to right) of display d (e.g., “File”, “Edit”, etc.) |
d.addPopupMenu(menu) |
Adds a popup menu (e.g. a right-click menu) on display d. |
Again, the second function is also available for every GUI object (e.g., a circle). This opens the door for many interesting GUI applications.
The following outlines the process of creating menu objects:
Every display has its own menu bar. To add menus to it, follow these steps:
menu = Menu(name)
where name is a string.
menu.addItem(name, function)
where name is a string, and function is a function to be called when the user selects this menu item. This function should expect no parameters.
display.addMenu(menu)
Pop-up menus are menus displayed when the user right-clicks on a display or other GUI object.
Pop-up menus are created the same way as drop-down menus. The only difference is that pop-up menus are added to a GUI object using the object’s addPopupMenu() function, as follows:
object.addPopupMenu(menu)
Graphics objects are used to draw various geometric shapes on a display. The following graphics objects are available:
Line objects are created using the following functions. Lines are drawn between a starting point (x1, y1) and an ending point (x2, y2).
Function |
Description |
Line(x1, y1, x2, y2) |
Creates a line from point x1, y1 to point x2, y2. |
Line(x1, y1, x2, y2, color, thickness) |
Creates a line from point x1, y1 to point x2, y2. Additional optional parameters include color (e.g. Color.BLACK (default), Color.ORANGE, or Color(255, 0, 255), using specific RGB values), and thickness (default is 1 pixel). |
Once a Line has been created, it may be added to a Display, specifying where to place its leftmost point.
line1 = Line(100, 100, 200, 200)
display1.add(line1)
Circle objects are created using the following functions. Circles are drawn specifying their center point (x, y), and their radius.
Function |
Description |
Circle(x, y, radius) |
Creates a circle at the given x, y coordinates and radius. |
Circle(x, y, radius, color, filled, thickness) |
Creates a circle at the given x, y coordinates, radius, color (e.g. Color.BLACK (default), Color.ORANGE, or Color(255, 0, 255), using specific RGB values), filled (boolean — default is False), and thickness (default is 1 pixel). |
Once a Circle has been created, it may be added to a Display, specifying where to place its center point.
circle1 = Circle(50, 50, 5)
d.add(circle1)
Point objects are created using the following functions. Points are drawn specifying their center point (x, y).
Function |
Description |
Point(x, y) |
Creates a new Point at the given x, y coordinates. |
Point(x, y, color) |
Creates a new Point at the given x, y coordinates and color (e.g. Color.BLACK (default), Color.ORANGE, or Color(255, 0, 255), using specific RGB values). |
Once a Point has been created, it may be added to a Display, specifying where to place its center point.
point1 = Point(50, 50)
d.add(point1)
Oval objects are created using the following functions. Ovals are drawn by specifying the top-left corner point (x1, y1) and the bottom-right corner point (x2, y2) of the box that encloses them.
Function |
Description |
Oval(x1, y1, x2, y2) |
Creates an Oval with top-left corner at x1, y1 and bottom-right corner at x2, y2. |
Oval(x1, y1, x2, y2, color, filled, thickness) |
Creates an Oval with top-left corner at x1, y1, bottom-right corner at x2, y2, color (e.g. Color.BLACK (default), Color.ORANGE, or Color(255, 0, 255), using specific RGB values), filled (boolean — default is False), and thickness (default is 1 pixel). |
Once an Oval has been created, it may be added to a Display, specifying where to place its top-left corner point (x1, y1).
oval1 = Oval(50, 30, 100, 150)
d.add(oval1)
Rectangle objects are created using the following functions. Rectangles are drawn by specifying the top-left corner point (x1, y1) and the bottom-right corner point (x2, y2).
Function |
Description |
Rectangle(x1, y1, x2, y2) |
Creates a Rectangle with top-left corner at x1, y1 and bottom-right corner at x2, y2. |
Rectangle(x1, y1, x2, y2, color, filled, thickness) |
Creates a Rectangle with top-left corner at x1, y1, bottom-right corner at x2, y2, color (e.g. Color.BLACK (default), Color.ORANGE, or Color(255, 0, 255), using specific RGB values), filled (boolean — default is False), and thickness (default is 1 pixel). |
Once a Rectangle has been created, it may be added to a Display, specifying where to place its top-left corner point.
rec1 = Rectangle(50, 30, 100, 150)
d.add(rec1)
Once a graphics object has been created, the following functions are available:
Function |
Description |
object.setColor(color) |
Changes the object color to the specified color (e.g. Color.BLACK or Color(255, 0, 255), using specific RGB values). If the color parameter is omitted, a color selection dialog box will be presented. |
object.getColor() |
Returns the current object color. |
Event functions are used to receive and process user actions at the GUI interface. Every GUI object listens for user actions (e.g., mouse click, mouse drag, typing a key, etc.), and allows you to specify a function to be called if and when a user action occurs.
You do not have to specify a function for every user action on every object on your GUI, only for the ones that you want. For example, you could make a program that draws a circle when the mouse is clicked on a particular location and cleans up all circles when the mouse exits the window.
The following event functions are available for all GUI library objects (i.e., Display, Label, Button, Checkbox, DropDownList, Slider, TextBox, Line, Circle, Rectangle, and Icon) except menus.§
Note: In the case of overlapping objects (e.g., a label and display), user events are handled by the object on top (front-most).
Keyboard events are divided into “key typed” and “key pressed/released” events. (For more information, see the Java API documentation on KeyEvents.)
“Key typed” events are higher-level and generally are independent of platform (and keyboard layout). These are generated when a character is typed on the keyboard (typing means both pressing and releasing the character key(s) on the keyboard).
The following function is provided to handle “key typed” events. It is available for all GUI objects (e.g., Display, Circle, etc.).
Function |
Description |
object.onKeyType(function) |
When the user types a key (i.e., presses it and releases it), the system calls the provided function.* This function should accept one parameter (a string), which is the key typed, e.g., “a”, “A”, “b”, “B”, “/”, etc.). Lower and uppercase characters are distinguished. |
* Such functions are known as callback functions, because they are “called back” by the system if and when the specific event happens.
“Key down” and “key up” events are lower-level events and are generated whenever a key is pressed or released. As a result, these events may be used for various gaming applications (e.g., when pressing and holding a key does one thing, and when releasing the key does another).
These events are specific to the platform and keyboard layout (i.e., some keys may not work the same on all platforms). So test on all desired platforms to make sure keystroke controls work as intended.
“Key down” and “key up” events are the only way to find out about keys that do not generate character input (e.g., action keys, modifier keys, etc.).
Function |
Description |
object.onKeyDown(function) |
When the user presses a key (i.e., pushes a key down), the system calls the provided function. This function should accept one parameter (an integer), which is the virtual key pressed, e.g., VK_SHIFT or VK_A. NOTE: This function may be called many times, if a key is held down (according to the keyboard’s key repeat rate). This is similar to pressing a key and having it repeat many times (e.g., in an editor window). |
object.onKeyUp(function) |
When the user releases a key, the system calls the provided function. This function should accept one parameter (an integer), which is the virtual key released, e.g., VK_SHIFT or VK_A. |
The following functions are provided to handle “key down” and “key up” events. They are available for all GUI objects (e.g., Display, Circle, etc.).
“Key down” and “key up” events use virtual key codes to report which keyboard key has been pressed, rather than a character generated by the combination of one or more keystrokes (such as “A”, which comes from shift and “a”).
For example, pressing the Shift key will cause a “key down” event with a VK_SHIFT key code whereas pressing the “a” key will result in a VK_A key code. After the “a” key is released, a “key up” event will be fired with VK_A.
Here is a list of the most important virtual key codes:
For a complete list see the Java API documentation on KeyEvent.
The following functions handle various mouse events.
The first group handles mouse events which happen inside a specific GUI object (e.g., display, circle, etc.):
Function |
Description |
object.onMouseClick(function) |
When the user clicks the mouse (left button),* the system calls the provided function. This function should accept two parameters, x and y (i.e., the coordinates of the mouse cursor). |
object.onMouseDown(function) |
When the user presses the left mouse button, the system calls the provided function. This function should accept two parameters, x and y (i.e., the coordinates of the mouse cursor). |
object.onMouseUp(function) |
When the user releases the left mouse button, the system calls the provided function. This function should accept two parameters, x and y (i.e., the coordinates of the mouse cursor). |
object.onMouseMove(function) |
When the user moves the mouse within the object, the system calls the provided function. This function should accept two parameters, x and y (i.e., the coordinates of the mouse cursor). |
object.onMouseDrag(function) |
When the user drags the mouse within the object (i.e., moves the mouse while clicking), the system calls the provided function. This function should accept two parameters, x and y (i.e., the coordinates of the mouse cursor). |
* The mouse right button is reserved for pop-up menus.
The following functions handle movement of a mouse that crosses the borders of a GUI object (i.e., entering or exiting the object boundaries):
Function |
Description |
object.onMouseEnter(function) |
When the user moves the mouse into the borders of an object (from outside), the system calls the provided function. This function should accept two parameters, x and y (i.e., the coordinates of the mouse cursor). |
object.onMouseExit(function) |
When the user moves the mouse from inside to outside the borders of an object, the system calls the provided function. This function should accept two parameters, x and y (i.e., the coordinates of the mouse cursor). |
In addition to all the above, Display objects also have an onClose() event handling function.
Function |
Description |
d.onClose(function) |
When display d is closed, the system calls the provided function. This function should have zero parameters. It may be used to perform cleanup, play a sound, update other displays, etc. |
The GUI library supports scheduling tasks (e.g., animation) through Timer class. Timer objects are used to schedule how often to perform a certain task (i.e., how often to call a given function).
Timer objects are used to to schedule functions to be executed after a given time interval, repeatedly or once. The following function creates a new Timer, so you need to save it in a variable (so you can use it later).
Function |
Description |
Timer(delay, function, parameters, repeat) |
Creates a new Timer to execute function after delay time interval (in milliseconds). The optional parameter parameters is a list of parameters to pass to the function (when called). The optional parameter repeat (boolean—default is True) determines if the timer will go on indefinitely. Note: The list of parameters is fixed at timer creation time and cannot be modified. |
For example, the following:
t = Timer(500, Play.noteOn, [A4], True)
creates a Timer t, which will call function Play.noteOn(A4) repeatedly every 500 milliseconds (i.e., half second). In order for a timer to operate, it needs to get started:
t.start()
Once a Timer t has been created, the following functions are available:
Function |
Description |
t.start() |
Starts timer t. |
t.stop() |
Stops timer t. |
t.getDelay() |
Returns the delay time interval of timer t (in milliseconds). |
t.setDelay(delay) |
Sets a new delay time interval for timer t (in milliseconds). This allows us to change the speed of the animation, after some event occurs. |
t.isRunning(delay) |
Returns True if timer t is running (has been started), False otherwise. |
t.setFunction(function, parameters) |
Sets the function to execute. The optional parameter parameters is a list of parameters to pass to the function (when called). |
t.getRepeat() |
Returns True if timer t is set to repeat, False otherwise. |
t.setRepeat(flag) |
If flag is True, timer t is set to repeat (this also starts the timer, if stopped). Otherwise, if flag is False, timer t is set to not repeat (this stops the timer, if running). |
* The GUI library is based on Java’s Swing library. It provides a clean, simpler API to use for building graphical user interfaces. For advanced users, existing Swing functionality is also available, but not advertised. Here, as in the rest of the book, the target audience is beginning programmers.
† Whereas Menu objects (seen later in the appendix) are fixed at a display’s menu bar (top), DropDownList objects can be placed anywhere on a display.
‡ You may also add separators and submenus, similarly.
§ Menus handle user events (i.e., selection) by definition, as seen in the Menu section.