A very simple GUI framework for Python 3
Enabling students to concentrate on core concepts and application logic
Created by Bill Robinson
last edited Aug 31 2017 by Bill Robinson
A very simple GUI framework for Python 3
Inspired by and extending Laura Sach’s guizero framework, ggui is intended to both enable and simplify the creation of a wide variety of small desktop applications by my GCSE and A-level students. Its main objective is to enable students to focus on core concepts and application logic rather than on pack/grid/etc., and so I thought it might perhaps be of interest to other teachers who use Python 3. It needs further work, but if you want to try it out ‘as-is’ simply dump the whole lot in an empty folder and run the examples, which should be reasonably self-explanatory (there are no dependencies other than tkinter). Further documentation is in the comments in the App, CanvasBG, ChildWindow, and Plotter files, and below.
Main features include
Processing style animation loop support and event handlers
- Simple creation of child windows and their event handlers
- Simple graphics & text creation
- Simple plotting of functions and data relying only upon tkinter (much better if using Tk version 8.6+, which supports angled text)
- Simple creation of and interaction with sprites (supporting multiple costumes) in any window (Tk 8.6+ allows PNGs as well as GIFs to be used)
- Uses the geometry manager with which students should already be pretty familiar from other curricular subjects, i.e. absolute positioning using x,y coordinates, rather than requiring them to also assimilate pack or grid and their options. Tkinter experts might prefer pack or grid, but that’s probably because they are experts, not beginners.
The attached screenshots demonstrate ggui usage, and the zipped file contains the example code and the ggui folder which (for now) can be simply dropped into a student’s program’s folder.
A few more notes
Considerable liberties have been taken for the sake of simplicity of use (though many will probably disagree with this approach), and the creation of child windows, widgets and graphics, etc. is done via functions which are bound to the main module or to each child window:
- main module only:
- main module and child windows:
- child windows only:
- Child windows are created by calling window() in the main module, with default options modal=False, title=None, width=None, height=None, background=None; if no options are supplied as arguments the new window inherits its title, size and background color from the main window.
- Child windows do not automatically show themselves on creation and their show method must be called to make them appear; hide() and close() may also be used to control them. N.B. They are initially centred on their parent, so in some of the examples you may have to drag them aside to also view the main window
- If draw(mouse_x, mouse_y, mouse_button) is implemented in the main module, this function will be called framerate times per second (default 50 fps). To stop this function being called use
framerate(nn), where nn is the desired framerate, will restart it.
- An alternative way to repeatedly call a function is to use every, which causes a function to be called after the specified interval with an arbitrary number of arguments e.g.
every(1000, print, 'Hello', 'World'); In this way every can be used to create a secondary/alternative animation or event handling loop
- If mouse_pressed(mouse_x, mouse_y, mouse_button) or key_pressed(key) are implemented in the main module they will be called to handle these events (see ex1a.py); mouse_button can take values 0 (not pressed), 1 (left click), 2 or 3. If you want to check which keys are currently pressed without using a key_pressed handler (e.g. in the main animation loop or in one created using every) you can use key, e.g
if key('space'): ...; see e.g. ex2g3.py, which polls keys pressed on the child window
- Event handlers for child windows are set using the obviously named functions in the listing above, and these are passed the child window as their first argument, enabling a single handler to handle multiple child windows
- Sprites can be created in the main or child windows, with multiple costumes (GIFs in Tk 8.5, PNGs and GIFs in TK 8.6), see ex2g.py, ex2h.py, ex2i.py, ex2m.py for examples
- If you do draw a very large number of graphics objects try to manage them and use obj.destroy() (or clear() to get rid of them all) when they are no longer needed
- The plotter can plot a function or list of data tuples in the main window or a child window (see examples), using its functions
bars; range, labels and ‘tick size’ can be specified by the user. Tk < 8.6 does not support drawing angled text and so if a lesser version is present an alternative form of labelling of the y-axis and column charts is done. If plotting in a child window make sure you call show() before calling plotter
- The limits of the plotter’s horizontal axis are set by the options xmin and xmax in either the call to plotter(…) or, if unspecified there, the first call to plot(…). Subsequent use of values for xmin and xmax in calls to plot simply constrain the range of the function being plotted (See ex17.py & Different_Ranges.png)
- When plotting functions/data the x & y axes’ values of the point under the mouse cursor is displayed; not always hugely accurate given mouse coordinates are in whole pixels, but one can always replot at higher resolution for greater accuracy
- To get/set the text in all 3 types of text widget (i.e. text, textbox, and textarea) you can use their text property, as at the bottom of ex9.py. Similary, to set / get tags for drawn objects or sprites, use their tags property
- An alternative to the widgets above for displaying simple text is to use the label function (see ex1a.py), which draws directly onto the canvas, has no background colour and can also contain newlines (‘\n’)
- Sprites and drawn graphic items have the following methods:
right (these last four can also be use as setters),
overlaps (the latter tests whether an overlap exists with another sprite/canvas item ).
- They may also be supplied with a click event handler at instantiation, or tagged with one or more identifiers using the tags property. Additionally, sprites offer
next_costume whilst graphics items offer
color which enables their stroke and fill to be changed (see ggui/CanvasBG.py for method parameters)
- Unless otherwise specified, when graphics items are created they use the current defaults (previously set by using
stroke_width); point and label have a stroke keyword argument, line has stroke and stroke_width, and all other graphic items have stroke, fill, and stroke_width keyword arguments. Colors may be specified using either hexadecimal strings or rgb tuples, and the hue of an RGB or hexadecimal color may be altered using color_shift
This has all been done in rather a rush for the start of term and so very probably contains some glaring errors I’ve overlooked - it’s not been fully tested yet, and comes with no warranties whatsoever. If you do try it out and come across errors please let me know, and I will update the version here when bugs show up.
License/warranty terms are stated in the license.txt file included in the download, but are essentially the same as those of guizero.
Level: (Beginner / Intermediate/ Advanced)