0% found this document useful (0 votes)
12 views

GUI Development 2

Uploaded by

Amanda Bilicki
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views

GUI Development 2

Uploaded by

Amanda Bilicki
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 42

Laura Sach Martin O’Hanlon

Create Graphical User


Interfaces with Python
How to build windows, buttons, and widgets
for your Python projects

www.dbooks.org
2 CREATE GRAPHICAL USER INTERFACES WITH PYTHON
CREATE GRAPHICAL USER INTERFACES WITH PYTHON

First published in 2020 by Raspberry Pi Trading Ltd, Maurice Wilkes Building,


St. John's Innovation Park, Cowley Road, Cambridge, CB4 0DS

Publishing Director: Russell Barnes • Editor: Phil King


Design: Critical Media
CEO: Eben Upton

ISBN: 978-1-912047-91-8

The publisher and contributors accept no responsibility in respect of any omissions


or errors relating to goods, products or services referred to or advertised in this book.
Except where otherwise noted, the content of this book is licensed under a Creative
Commons Attribution-NonCommercial-ShareAlike 3.0 Unported
(CC BY-NC-SA 3.0)

3
www.dbooks.org
About the authors...
Martin O'Hanlon
Martin works in the learning team at the Raspberry
Pi Foundation, where he creates online courses,
projects, and learning resources. He contributes
to the development of many open-source projects
and Python libraries, including guizero. As a child,
he wanted to be a computer scientist, astronaut,
or snowboard instructor.

Laura Sach
Laura leads the A Level team at the Raspberry
Pi Foundation, creating resources for students
to learn about Computer Science. She somehow
also manages to make cakes, hug cats, and
wrangle a toddler.

4 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

Welcome!
T
his book will show you how to use Python to create some fun graphical user
interfaces (GUIs) using the guizero library. The guizero library started with the belief
that there must be an easier way for students in school to create Python GUIs. The
library itself was born one day on a long train journey from Cambridge, as the side project of a
secondary school teacher.
Guizero has grown significantly in terms of features, yet remained true to its original aim of
being simple but flexible. It is a library for all beginners to create with, for teachers to scaffold
learning with and for experts to save time with.
We hope that these projects and guizero brings you that little spark of excitement to
your Python programs. That spark might be anything from a button that does something
when you click it, to colours in your otherwise black and white Python programming, to a
full multicoloured Waffle.
It turns out that with open-source software, even if you don't know how to get the whole way
there, if you start, someone will help you. We are grateful to the many contributors who have
put time and effort into creating guizero, and to the thousands of people who have used it in
their projects. Enjoy your journey and be proud of your creations.

Laura and Martin

5
www.dbooks.org
Contents
Chapter 1: Introduction to GUIs 008
How to install guizero and create your first app

Chapter 2: Wanted Poster 012


Use styled text and an image to create a poster

Chapter 3: Spy Name Chooser 018


Make an interactive GUI application

Chapter 4: Meme Generator 026


Create a GUI application which draws memes

Chapter 5: World’s Worst GUI 036


Learn good GUI design by doing it all wrong first!

Chapter 6: Tic-tac-toe 044


Use your GUI to control a simple game

Chapter 7: Destroy the Dots 062


Learn how to use a Waffle to create a tasty game

6 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

Chapter 8: Flood It 078


Create a more complex Waffle-based puzzle game

Chapter 9: Emoji Match 092


Make a fun picture-matching game

Chapter 10: Paint 110


Create a simple drawing application

Chapter 11: Stop-frame Animation 124


Build your own stop-frame animated GIF creator

Appendix A: Setting up 138


Learn how install Python and an IDE

Appendix B: Get started with Python 142


How to start coding in Python

Appendix C: Widgets in guizero 148


An overview of the widgets used in guizero

7
www.dbooks.org
Chapter 1

Introduction to GUIs
How to install guizero and create your first app

A
graphical user interface (GUI,
WHAT YOU'LL NEED
pronounced ‘gooey’) is a way of
You will need a computer (e.g. Raspberry making your Python programs
Pi, Apple Mac, Windows or Linux PC) and easier to use and more exciting. You can add
an internet connection for the software different components called ‘widgets’ to your
installation. You will also need the interface, allowing lots of different ways for
following software installed: information to be entered in to the program
and displayed as output. You might want
• Python 3 (python.org) – see Appendix A
to allow people to push a button, to display
• An IDE (code editor), e.g.: a piece of text, or even let them choose an
IDLE (installed with Python 3), Thonny option from a menu. In this book we will use
(thonny.org), Mu (codewith.mu), the guizero library, which has been developed
PyCharm (jetbrains.com/pycharm) with the aim of helping beginners to easily
create GUIs.
• The guizero Python library
Python’s standard GUI package is called
(lawsie.github.io/guizero)
tkinter, and is already installed with Python

8 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

on most platforms. The guizero library is


a wrapper for tkinter – this means that
it offers a much simpler way of using
Python’s standard GUI library.

Installing guizero
You will need to install the guizero
(lawsie.github.io/guizero) Python library An alternative way to install guizero is to
to create the programs in this book. It is download the zip file from GitHub
available as a Python package, which is
reusable code you can download, install, and then use in your programs.
How you install of guizero will depend on your operating system and the permissions you
have to control your computer.
If you have access to the command line / terminal, you can use the following command:

pip3 install guizero

Comprehensive installation instructions for guizero are available at lawsie.github.io/guizero,


including options for installing when you have no administration rights to your computer and
downloadable installations for Windows.

Hello World
Now that you have guizero installed, let’s check that it’s working and write a small ‘hello
world’ app which is traditional for programmers to write as their first program when using a
new tool or language.

AIMS OF GUIZERO
• Able to be used without installation • Accessible to young children, but able be used
for advanced projects
• Remove unnecessary code new learners find
difficult to understand • Good-quality documentation with examples

• Sensible widget names • Generate helpful error messages

Chapter 1 Introduction to GUIs 9


www.dbooks.org
Open up the editor where you will write your Python
code. At the start of every guizero program, you will
choose the widgets you need from the guizero library
and import them. You only need to import each widget
once, and then you can use it in your program as many
times as you like.
At the top of the page, add this code to import the
App widget:

from guizero import App


Figure 1 Your first guizero app
All guizero projects begin with a main window which is a container widget called an App. At the
end of every guizero program, you must tell the program to display the app you have just created.
Add these two lines of code underneath the line where you imported the App widget:

app = App(title="Hello world")


app.display()

Now save and run your code. You should see a GUI window with the title ‘Hello world’ (Figure
1). Congratulations, you’ve just created your first guizero app!

Adding widgets
Widgets are the things which appear on the GUI, such as text boxes, buttons, sliders, and
even plain old pieces of text.
All widgets go between the line of code to create the App and the app.display() line.
Here is the app you just made, but in this example we have added a Text widget:

from guizero import App, Text


app = App(title="Hello world")
message = Text(app, text="Welcome to the app")
app.display()

Did you notice that there are two changes (Figure 2)? There is now an extra line of code to
add the Text widget, and we have also added Text to the list of widgets to import on the very
first line.
Let’s look at the Text widget code in a bit more detail:

message = Text(app, text="Welcome to the app")

10 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

Just like any variable in Python, a widget needs a


name. This one is called ‘message’. Then we specify
that we would like this to be a ‘Text’ widget. Inside the
brackets are some parameters to tell the Text widget
what it should look like. The first one, ‘app’, tells the
Text where it will live. All widgets need to live inside
a container widget. Most of the time your widgets
will live directly inside an App, but you will discover
later that there are also some other types of container
widget you can put things in too. Finally, we tell the
widget to contain the text “Welcome to the app”. Figure 2 Add a text message

01-helloworld.py / Python 3 DOWNLOAD


from guizero import App, Text magpi.cc/guizerocode
app = App(title="Hello world")
message = Text(app, text="Welcome to the app")
app.display()

Chapter 1 Introduction to GUIs 11


www.dbooks.org
Chapter 2

Wanted Poster
Use styled text and an image to create a poster

N
ow that you can create a basic GUI, let’s make it look a bit more exciting. You can
add text in different fonts, sizes and colours, change the background colour, and
add pictures too. To practise all of this, let’s create a ‘Wanted’ poster.
First of all, you need to start off by creating an app. In your editor, add this code to create
the most basic app window:

from guizero import App

app = App("Wanted!")

app.display()

Save and run your code and you should see an app that
looks like a plain grey square with the title ‘Wanted!’ at
the top (Figure 1).
Figure 1 The basic app

12 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

Background colours
Let's make the background of the app a bit different.
Traditionally, wanted posters look like they are made of
parchment, so let’s add a pale yellow colour instead as
the background.
Find the line of code where you create the app.
Immediately after this line of code, add one more line
of code to modify the bg property of the window. In
this case, bg is short for ‘background’ and will let us
change the colour of the background. Now your code
should look like this: Figure 2 Background colour

from guizero import App

app = App("Wanted!")
app.bg = "yellow"

app.display()

This is called editing a property. In the code, you need to specify the widget you are talking
about (app), the property you want to change (bg) and the value you want to change it to.
You might think this colour (Figure 2) is a bit too yellow, so let's look up the hex code of
a different yellow colour. There are lots of websites where you can search for colours, for
example you could try htmlcolorcodes.com (Figure 3).

Figure 3 Selecting a shade on htmlcolorcodes.com

Chapter 2 Wanted Poster 13


www.dbooks.org
When you have selected the colour you want,
you will see its code displayed on the site either
as hexadecimal (in this case #FBFBD0) or as RGB
(251, 251, 208). You can use both of these formats
for setting colours in guizero; for example, you could
delete the code for making your background yellow
and then try one of these options in your program:

app.bg = "#FBFBD0"
app.bg = (251, 251, 208)
Figure 4 Pale background

Add some text


Your app should look something like Figure 4. Now let’s add some text to the GUI. We will
begin by adding the text that all good wanted posters need – the word ‘Wanted’!
First, look for the line of code you already have where you imported the App.

from guizero import App

You need to import Text to be able to create a piece of text, so add it to the end of the list.
Now the line looks like this:

from guizero import App, Text

Every time you want to use a new type of widget, add its name to the end of the list. There is
no need to keep adding whole new lines of code: just stick with one list so that your program
doesn’t get too confusing.
Now that you can use text, let's add a piece of text. Remember that all widgets on the
GUI must be added between the line of code where you create the App and the line of code
where you display it. Your code should now look like this:

from guizero import App, Text

app = App("Wanted!")
app.bg = "#FBFBD0"

wanted_text = Text(app, "WANTED")

app.display()

14 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

Let’s take a closer look at that line of code you just added.

wanted_text = Text(app, "WANTED")

Here, wanted_text is the name of the piece of text. This is so that we can talk about it later
on in the code – think of it like a person's name. (You could even call your piece of text Dave
if you want – the computer won’t care!)
Inside the brackets we have two things. The second one, "WANTED", is straightforward as
it is the text we would like to display on the screen. The first is the container which controls
this piece of text, which is called its ‘master’. In this case we are saying that this text should
be controlled by the app. When you first start creating GUIs, most of your widgets will have
the app as their master, but there are other containers that can store widgets that you will
learn about later on.

Change text size and colour


Uh oh, this text is pretty small (Figure 5). Let's change the text_size property in exactly the
same way as you did when we changed the background colour of the app. Remember that
you needed to specify three things:

1. The name of the widget


2. Which property to change
3. The new value to change it to

So, in this case you are going to specify the widget Figure 5 Text is too small
(wanted_text), the property to change (text_size)
and the new value (50). Add one new line of code immediately under the line where you
created the text, to change the property.

wanted_text = Text(app, "WANTED")


wanted_text.text_size = 50

You now have larger text on your poster (Figure 6). See if you can now change the font
of this text to something different. Which fonts are available depends on which operating
system you are using, so here are some suggestions:

• Times New Roman


• Verdana
• Courier
• Impact Figure 6 Larger text

Chapter 2 Wanted Poster 15


www.dbooks.org
No ‘wanted’ poster would be complete without a picture, so let’s add one. My poster is going
to be for my cat, because she is always scratching things she shouldn’t be.
Save a copy of the image you would like to use in the same folder as your GUI program.
You can use images in other folders, but if you do you will have to provide the path to the
image, so it’s a lot easier to just store them in the same folder when you are starting out.

IMAGE MANIPULATION
Because guizero is a library for beginners and we wanted to make it as easy as possible to install,
it does not come with the fancier image manipulation functions as these require an extra library
called 'pillow'. You can always use non-animated GIF images on any platform, and PNG images on all
platforms except Mac, so if you're not sure whether you have installed the extra image manipulation
functions, stick to those image types.

Hopefully you’re now getting used to adding widgets. Remember that they must always be
imported at the top of the program, and then the widget created with a sensible name after
the line of code where you create the App, but before the final app.display() line.
Add 'Picture' to the list of widgets to import at the start of the program.

from guizero import App, Text, Picture

Now create a Picture widget with two parameters: the app and the file name of the picture.
This is the code we used because our picture was called tabitha.png.

cat = Picture(app, image="tabitha.png")

Run your code (which should look like 02-wanted.py)


again and you should see the picture displaying below
your text (Figure 7).
Now it's up to you to use your new GUI
customisation skills to style your poster however you
would like.

Figure 7 The finished poster

16 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

READING THE DOCS


You might be wondering how to find out what properties a particular widget has that you can change.
Even if you are a complete beginner programmer, it is worth learning how to read documentation
because it will let you use the full power of guizero and any other libraries you come across.

The guizero documentation can be found at lawsie.github.io/guizero. Once you are there, click on the
widget you would like to change, and scroll down until you reach the properties section. For example, if
you select ‘Text’ under the heading of widgets, you will see all of the properties of a piece of Text that
you can possibly change. Documentation also often contains helpful snippets of code which show you
how to use a particular property or method, so don't be scared of having a look through – you never
know what you might learn!

02-wanted.py / Python 3 DOWNLOAD


from guizero import App, Text, Picture magpi.cc/guizerocode

app = App("Wanted!")
app.bg = "#FBFBD0"

wanted_text = Text(app, "WANTED")


wanted_text.text_size = 50
wanted_text.font = "Times New Roman"

cat = Picture(app, image="tabitha.png")

app.display()

Chapter 2 Wanted Poster 17


www.dbooks.org
Chapter 3

Spy Name Chooser


Make an interactive GUI application

S
o far you've learnt how to
customise your GUI with a
variety of different options. It's
now time to get into the really interactive Figure 1 Displaying the text in a window
part and make a GUI application that
actually responds to input from the user. Who could resist pushing a big red button to
generate a super secret spy name?
Since you already know how to create an app, why not go ahead and create a basic window
and add some text if you like? Here is some code to get you started, and this code also
includes some comments (the lines that start with a #) to help you structure your program:

# Imports ---------------
from guizero import App, Text

# Functions -------------

18 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

# App -------------------
app = App("TOP SECRET")

# Widgets ---------------
title = Text(app, "Push the red button to find out your spy
name")

# Display ---------------
app.display()

Run this code and you should see a window with the text (Figure 1).

Add a button
Let's go ahead and add a button to the GUI. Add PushButton to your list of imports so that
you can use buttons. (Be careful to use a capital B!)
Underneath the Text widget, but before the app displays, add a line of code to create
a button.

button = PushButton(app, choose_name, text="Tell me!")

Your code should now look like spy1.py (page 22). Run it and no button will appear, but you’ll
see an error in the shell window:

NameError: name 'choose_name' is not defined

This is because choose_name is the


name of a command which runs when the
button is pressed. Most GUI components
can have a command attached to them.
For a button, attaching a command Figure 2 You now have a button
means “when the button is pressed, run
this command.” A GUI program works differently to other Python programs you might have
written because the order in which the commands are run in the program depends entirely
on the order in which the user presses the buttons, moves the sliders, ticks the boxes or
interacts with whichever other widgets you are using. The actual command is almost always
the name of a function to run.

Chapter 3 Spy Name Chooser 19


www.dbooks.org
Create a function
Let's write the function choose_name so
your button has something it can do when
it is pressed.
Look at your program and find the
functions section. This is where you Figure 3 Text is output to the shell window

should write all of the functions which will


be attached to GUI widgets, to keep them separate from the code for displaying the widget.
Add this code in the functions section:

def choose_name():
print("Button was pressed")

Your code should now look like spy2.py. The button will now appear (Figure 2). If you press
the button, it may appear that nothing has happened, but if you look in your shell or output
window, you will see that some text has appeared there (Figure 3).
Instructing your function to first print out some dummy text is a useful way of confirming
that the button is activating its command function correctly when it is pressed. You can then
replace the print statement with the actual code for the task you would like your button
to perform.
Inside your choose_name function, type a # symbol in front of the line of code that prints
"Button was pressed". Programmers call this ‘commenting out’, and what you have done
here is told the computer to treat this line of code as if it were a comment, or in other words
you have instructed the computer to ignore it. The benefit of commenting a line of code out
instead of just deleting it is so that if you ever want to use that code again, you can easily
make it part of your program again by removing the # symbol.

BIG RED BUTTON


At the moment, your button is not big or red! You used properties in the previous chapter to change
the appearance of your text on the ‘Wanted’ poster, so can you use the properties of the PushButton
widget to change the background colour and the text size?

Note that it may not bepossible to change the colour of a button on macOS, as some versions of the
operating system will not allow you to do so, but you should still be able to alter the text size.

20 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

Add some names


On a new line, add a list of first names.
You can choose the names in your list
and there can be as many names as you
like, but make sure that each name is
between quotes, and the names are each Figure 4 Outputting a spy name

separated by a comma. A collection of


letters, numbers, and/or punctuation between quotation marks is called a string, so we say
that each name must be a string.

first_names = ["Barbara", "Woody", "Tiberius", "Smokey",


"Jennifer", "Ruby"]

Now add a list of last names as well:

last_names = ["Spindleshanks", "Mysterioso", "Dungeon",


"Catseye", "Darkmeyer", "Flamingobreath"]

Now you will need to add a way of choosing a random name from each list to form your spy
name. Your first job is to add a new import line in your imports section:

from random import choice

This tells the program that you would like to use a function called choice which chooses a
random item from a list. Someone else has written the code which does this for you, and it is
included with Python for you to use.
In your code for the choose_name function, just below your lists of names, add a line of
code to choose your spy's first name, and then concatenate it together with the last name,
with a space in between. Concatenate is a fancy word that means ‘join two strings together’
and the symbol in Python for concatenation is a plus (+).

spy_name = choice(first_names) + " " + choice(last_names)


print(spy_name)

Your code should now resemble spy3.py. Save and run it. When you press the button, you
should see that a randomly generated spy name appears in your console or shell, in the
same place where the original "Button was pressed" message showed up before (Figure 4).

Chapter 3 Spy Name Chooser 21


www.dbooks.org
Put the name in the GUI
That's good, but wouldn't it be nicer if
the spy name appeared on the GUI? Let's
make another Text widget and use it to
display the spy name.
In the widgets section, add a new Text
widget which will display the spy name: Figure 5 The finished spy name chooser

name = Text(app, text="")

When you create the widget, you don't want it to display any text at all as the person won't
have pressed the button yet, so you can set the text to "", which is called an ‘empty string’
and displays nothing. Inside your choose_name function, comment out the line of code
where you print out the spy name.
Now add a new line of code at the end of the function to set the value of the name Text
widget to the spy_name you just created. This will cause the Text widget to update itself and
display the name.

name.value = spy_name

Your final code should be as in 03-spy-name-chooser.py. Run it and press the button to see
your spy name displayed proudly on the GUI (Figure 5).
You can press the button again if you don't like the name you are given, and the program
will randomly generate another name for you.

spy1.py / Python 3 DOWNLOAD


# Imports --------------- magpi.cc/guizerocode
from guizero import App, Text, PushButton

# Functions -------------

# App -------------------
app = App("TOP SECRET")

# Widgets ---------------
title = Text(app, "Push the red button to find out your spy name")
button = PushButton(app, choose_name, text="Tell me!")

# Display ---------------
app.display()

22 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

spy2.py / Python 3
# Imports ---------------
from guizero import App, Text, PushButton

# Functions -------------
def choose_name():
print("Button was pressed")

# App -------------------
app = App("TOP SECRET")

# Widgets ---------------
title = Text(app, "Push the red button to find out your spy name")
button = PushButton(app, choose_name, text="Tell me!")

# Display ---------------
app.display()

spy3.py / Python 3
# Imports ---------------
from guizero import App, Text, PushButton
from random import choice

# Functions -------------
def choose_name():
#print("Button was pressed")
first_names = ["Barbara", "Woody", "Tiberius", "Smokey",
"Jennifer", "Ruby"]
last_names = ["Spindleshanks", "Mysterioso", "Dungeon",
"Catseye", "Darkmeyer", "Flamingobreath"]
spy_name = choice(first_names) + " " + choice(last_names)
print(spy_name)

# App -------------------
app = App("TOP SECRET")

# Widgets ---------------
title = Text(app, "Push the red button to find out your spy name")
button = PushButton(app, choose_name, text="Tell me!")
button.bg = "red"
button.text_size = 30

# Display ---------------
app.display()

Chapter 3 Spy Name Chooser 23


www.dbooks.org
03-spy-name-chooser.py / Python 3
# Imports ---------------

from guizero import App, Text, PushButton


from random import choice

# Functions -------------

def choose_name():
#print("Button was pressed")
first_names = ["Barbara", "Woody", "Tiberius", "Smokey",
"Jennifer", "Ruby"]
last_names = ["Spindleshanks", "Mysterioso", "Dungeon",
"Catseye", "Darkmeyer", "Flamingobreath"]
spy_name = choice(first_names) + " " + choice(last_names)
#print(spy_name)
name.value = spy_name

# App -------------------

app = App("TOP SECRET")

# Widgets ---------------

title = Text(app, "Push the red button to find out your spy name")
button = PushButton(app, choose_name, text="Tell me!")
button.bg = "red"
button.text_size = 30
name = Text(app, text="")

# Display ---------------

app.display()

24 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

Chapter 3 Spy Name Chooser 25


www.dbooks.org
Chapter 4

Meme Generator
Create a GUI application which draws memes

L
et's take the lessons you learnt from the previous chapters to create a GUI which
draws memes. You will input the text and image name and your GUI will combine them
into your own meme using the Drawing widget.
Start by creating a simple GUI with two text boxes for the top and bottom text. This is where
you will enter the text which will be inserted over your picture to create your meme. Add this
line to import the widgets needed.

from guizero import App, TextBox, Drawing

Then add this code for the app:

app = App("meme")

top_text = TextBox(app, "top text")


bottom_text = TextBox(app, "bottom text")

app.display()

26 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

The meme will be created on a Drawing widget which will hold the image and text.

Create a meme
Add it to the GUI by inserting this code just before the app.display() line. The Drawing
widget’s height and width should be set to ‘fill’ the rest of the GUI.

meme = Drawing(app, width="fill", height="fill")

The meme will be created when the text in the top and bottom text boxes changes. To do that,
we will need to create a function which draws the meme.
The function should clear the drawing, create an image (we're using a photo of a
woodpecker, but you can use any you want) and insert the text at the top and bottom of
the image.
Remember when you used name.value to set the value of the Text widget with the spy
name in Chapter 3? You can also use the value property to get the value of a Text widget, so in
this case top_text.value means ‘please get the value that is typed in the top_text box’.

def draw_meme():
meme.clear()
meme.image(0, 0, "woodpecker.png")
meme.text(20, 20, top_text.value)
meme.text(20, 320, bottom_text.value)

The first two numbers in meme.image(0,


0) and meme.text(20, 20) are the x, y
co-ordinates of where to draw the image
and text. The image is drawn at position
0, 0, which is the top-left corner, so the
image covers the whole of the drawing.
Finally, call your draw_meme function just
before you display the app. Insert this code
just before the app.display line:

draw_meme()

Your code should now look like meme1.py. Figure 1 Meme with unstyled text

Chapter 4 Meme Generator 27


www.dbooks.org
If you run your app (Figure 1) and try changing the top and bottom text, you will notice that
it doesn’t update in the meme. To get this working, you will have to change your program to
call the draw_meme function when the text changes, by adding a command to the two TextBox
widgets to the app.

top_text = TextBox(app, "top text", command=draw_meme)


bottom_text = TextBox(app, "bottom text", command=draw_meme)

Your code should now look like that in meme2.py. Run it and update your meme by changing
the top and bottom text.
You can then look of your meme by changing the color, size, and font parameters of the text.
For example:

meme.text(
TIP
20, 20, top_text.value,
color="orange", These lines of code were

size=40, starting to get very long, so we

font="courier") have split them over a number

meme.text( of lines to make it easier to

20, 320, bottom_text.value, read. It doesn’t affect what the

color="blue", program does, just how it looks.

size=28,
font="times new roman",
)

Your code should now look like meme3.py. Try different styles until you find something you
like (Figure 2).

Customise your meme generator


For a truly interactive meme generator, the
user should be able to set the font, size,
and colour themselves. You can provide
additional widgets on the GUI to allow
them to do this.
The number of options available for
the colour and font are limited, so you
could use a drop-down list, also known as
a Combo, for this. The size could be set
using a Slider widget.
Figure 2 Alter the fonts and colours

28 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

First, modify your import statement to include the Combo and Slider widgets.

from guizero import App, TextBox, Drawing, Combo, Slider

After you have created your TextBox widgets for the top and bottom text, create a new Combo
widget so the user can select a colour.

bottom_text = TextBox(app, "bottom text", command=draw_meme)


color = Combo(app,
options=["black", "white", "red", "green", "blue", "orange"],
command=draw_meme)

The options parameter sets what colours the user can select from the Combo. Each colour is
an element in a list. You can add any other colours you want to the list.
The options are displayed in the order in which you put them in the list. The first option is
the default, which is displayed first. If you want to have a different option as the default, you
can do it using the selected parameter, e.g. "blue".

color = Combo(app,
options=["black", "white", "red", "green", "blue", "orange"],
command=draw_meme,
selected="blue")

Now your user can select a colour. Next, you need to change the draw_meme function to use
Combo’s value when creating the text in your the meme. For example:

meme.text(
20, 20, top_text.value,
color=color.value,
size=40,
font="courier")

Do the same for the bottom-text block of code. Your program should now resemble meme4.py.
Following the steps above, add a second Combo to your application so the user can select a
font from this list of options: ["times new roman", "verdana", "courier", "impact"].
Remember to change the draw_meme function to use the font value when adding the text.
Create a new Slider widget to set the size of the text your user wants.

size = Slider(app, start=20, end=40, command=draw_meme)

Chapter 4 Meme Generator 29


www.dbooks.org
The range of the slider is set using the start and end parameters. So, in this example, the
smallest text available will be 20 and the largest 40.
Modify the draw_meme function to use the value from your size slider when creating the
meme's text.

meme.text(
20, 20, top_text.value,
color=color.value,
size=size.value,
font=font.value)

Your code should now resemble that in


04-meme-generator.py. Try running it and
you should see something like Figure 3.
Can you change the GUI so that the
name of the image file can be entered
into a TextBox or perhaps selected from
a list in a Combo? This would make your
application capable of generating memes
with different images too.

Figure 3 The finished meme generator

DRAWING WIDGET
The Drawing widget is really versatile and can be used to display lots of different shapes, patterns,
and images.

To find out more about the Drawing widget, see Appendix C, or take a look at the online
documentation: lawsie.github.io/guizero/drawing.

30 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

meme1.py / Python 3 DOWNLOAD


# Imports --------------- magpi.cc/guizerocode

from guizero import App, TextBox, Drawing

# Functions -------------

def draw_meme():
meme.clear()
meme.image(0, 0, "woodpecker.png")
meme.text(20, 20, top_text.value)
meme.text(20, 320, bottom_text.value)

# App -------------------

app = App("meme")

top_text = TextBox(app, "top text")


bottom_text = TextBox(app, "bottom text")

meme = Drawing(app, width="fill", height="fill")

draw_meme()

app.display()

meme2.py / Python 3
# Imports ---------------

from guizero import App, TextBox, Drawing

# Functions -------------

def draw_meme():
meme.clear()
meme.image(0, 0, "woodpecker.png")
meme.text(20, 20, top_text.value)
meme.text(20, 320, bottom_text.value)

Chapter 4 Meme Generator 31


www.dbooks.org
meme2.py (cont.) / Python 3

# App -------------------

app = App("meme")

top_text = TextBox(app, "top text", command=draw_meme)


bottom_text = TextBox(app, "bottom text", command=draw_meme)

meme = Drawing(app, width="fill", height="fill")

draw_meme()

app.display()

meme3.py / Python 3
# Imports ---------------

from guizero import App, TextBox, Drawing

# Functions -------------

def draw_meme():
meme.clear()
meme.image(0, 0, "woodpecker.png")
meme.text(
20, 20, top_text.value,
color="orange",
size=40,
font="courier")
meme.text(
20, 320, bottom_text.value,
color="blue",
size=28,
font="times new roman",
)

32 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

meme3.py (cont.) / Python 3


# App -------------------

app = App("meme")

top_text = TextBox(app, "top text", command=draw_meme)


bottom_text = TextBox(app, "bottom text", command=draw_meme)

meme = Drawing(app, width="fill", height="fill")

draw_meme()

app.display()

meme4.py / Python 3
# Imports ---------------

from guizero import App, TextBox, Drawing, Combo, Slider

# Functions -------------

def draw_meme():
meme.clear()
meme.image(0, 0, "woodpecker.png")
meme.text(
20, 20, top_text.value,
color=color.value,
size=40,
font="courier")
meme.text(
20, 320, bottom_text.value,
color=color.value,
size=28,
font="times new roman",
)

# App -------------------

Chapter 4 Meme Generator 33


www.dbooks.org
meme4.py (cont.) / Python 3
app = App("meme")

top_text = TextBox(app, "top text", command=draw_meme)


bottom_text = TextBox(app, "bottom text", command=draw_meme)

color = Combo(app,
options=["black", "white", "red", "green", "blue",
"orange"],
command=draw_meme, selected="blue")

meme = Drawing(app, width="fill", height="fill")

draw_meme()

app.display()

04-meme-generator.py / Python 3
# Imports ---------------

from guizero import App, TextBox, Drawing, Combo, Slider

# Functions -------------

def draw_meme():
meme.clear()
meme.image(0, 0, "woodpecker.png")
meme.text(
20, 20, top_text.value,
color=color.value,
size=size.value,
font=font.value)
meme.text(
20, 320, bottom_text.value,
color=color.value,
size=size.value,
font=font.value,
)

34 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

04-meme-generator.py / Python 3

# App -------------------

app = App("meme")

top_text = TextBox(app, "top text", command=draw_meme)


bottom_text = TextBox(app, "bottom text", command=draw_meme)

color = Combo(app,
options=["black", "white", "red", "green", "blue",
"orange"],
command=draw_meme, selected="blue")

font = Combo(app,
options=["times new roman", "verdana", "courier",
"impact"],
command=draw_meme)

size = Slider(app, start=20, end=50, command=draw_meme)

meme = Drawing(app, width="fill", height="fill")

draw_meme()

app.display()

Chapter 4 Meme Generator 35


www.dbooks.org
Chapter 5

World’s Worst GUI


Learn good GUI design by doing it all wrong first!

#13A751
Well
Welldone!
done!
You Well done!
started
Well done! #EA5F10
You
Youstarted
Well done!
started
the
theapplication.
You started
application.
You started
the
theapplication. #289099
theapplication.
application.

Areyou
Are yousure?
sure?
Are you sure?
YES NO
YES NO
YES NO

I
ts time to really go to town with your GUIs and experiment with different widgets,
colours, fonts, and features. Like most experiments, it’s likely that you won’t get it right
first time! In fact, you are going to explore the wrong way to approach creating your GUI.

It’s hard to read


The right choice of GUI colour and font are important. It’s important that the contrast between
background and text colour ensure that your GUI is easily readable. What you shouldn't do it is
use two very similar colours.
Import the widgets at the top of the code:

from guizero import App, Text

Create an app with a title:

app = App("it's all gone wrong")


title = Text(app, text="Some hard to read text")

36 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

app.display()

Experiment by changing the colours, font, and text size (see worst1.py listing, page 41). My
choices are not the best!

app = App("it's all gone wrong", bg="dark green")


title = Text(app, text="Some hard-to-read text", size="14",
font="Comic Sans", color="green")

It’s important that text on a GUI also stays around long enough to be read. It certainly shouldn't
disappear or start flashing.
All widgets in guizero can be made invisible (or visible again) using the hide() and show()
functions. Using the repeat function in guizero to run a function every second, you can make
your text hide and show itself and appear to flash.
Create a function which will hide the text if it’s visible and show it if it’s not:

def flash_text():
if title.visible:
title.hide()
else:
title.show()

Before the app is displayed, use repeat to make the flash_text function run every 1000
milliseconds (1 second).

app.repeat(1000, flash_text)

app.display()

Your code should now look like worst2.py. Test your app: the title text should flash, appearing
and disappearing once every second.

The wrong widget


Using an appropriate widget can be the difference between a great GUI and one which is
completely unusable.
Which widget would you use to enter a date? A TextBox? Multiple Combos? A TextBox
would be more flexible but would require validation and formatting. Multiple Combos for year,
month, and day wouldn't require validating but would be slower to use.

Chapter 5 World’s Worst GUI 37


www.dbooks.org
Figure 1 A slider to set date and time Figure 2 Combos to choose letters

Using a Slider to set a date and time (Figure 1), as in the worst3.py code example, is not a
great idea, though.
The Slider widget returns a number between 0 and 999,999,999. This is the number of
seconds since 1 January 1970. The function ctime() is used to turn this number into a date
and time.
Getting text from your user is simple: a TextBox or a multi-line TextBox should fulfil all your
needs. Is it too simple, though. Does this require too much typing?
What about the user who just wants to use a mouse? Perhaps a series of Combos each
containing all the letters in the alphabet would be better (Figure 2)?
Start by importing the guizero widgets and ascii_letters.

from guizero import App, Combo


from string import ascii_letters

ascii_letters is a list containing all the ‘printable’ ASCII characters which you can use as
the options for the Combo.
Create a single Combo which contains all the letters and displays the app.

a_letter = Combo(app, options=" " + ascii_letters, align="left")

app.display()

Your program should now resemble worst4.py. Running it, you will see a single Combo which
contains all the letters plus a space and is aligned to the left of the window.
To get a line of letters together, you could continually add Combo widgets to your app, e.g.:

a_letter = Combo(app, options=" " + ascii_letters, align="left")


b_letter = Combo(app, options=" " + ascii_letters, align="left")
c_letter = Combo(app, options=" " + ascii_letters, align="left")

38 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

By aligning each Combo widget to the left,


the widgets are displayed next to each other
against the left edge.
Alternatively, you could use a for loop,
create a list of letters, and append each letter
to the list, as shown in worst5.py.
Try both these approaches and see which
you prefer. The for loop is more flexible as it
allows you to create as many letters as you like.

Pop-ups
No terrible GUI would be complete without
a pop-up box. guizero contains a number of
pop-up boxes, which can be used to let users Figure 3 Pointless pop-up
know something important or gather useful
information. They can also be used to irritate and annoy users!
First, create an application which pops up a pointless box at the start to let you know the
application has started.

from guizero import App

app = App(title="pointless pop-ups")

app.info("Application started", "Well done you started the


application")

app.display()

Running your application, you will see that an ‘info’ box appears (Figure 3). The first parameter
passed to info is the title of the window; the second parameter is the message.
You can change the style of this simple pop-up by using warn or error instead of info.
Pop-up boxes can also be used to get information from the user. The simplest is a yesno
which will ask the user a question and get a True or False response. This is useful if you want
a user to confirm before doing something, such as deleting a file. Perhaps not every time they
press a button, though!
Import the PushButton widget into your application:

from guizero import App, PushButton

Create a function which uses the yesno pop-up to ask for confirmation.

Chapter 5 World’s Worst GUI 39


www.dbooks.org
def are_you_sure():
if app.yesno("Confirmation", "Are you sure?"):
app.info("Thanks", "Button pressed")
else:
app.error("Ok", "Cancelling")

Add the button to your GUI which calls the function when it is pressed.

button = PushButton(app, command=are_you_sure)

Your code should now resemble 05-worlds-worst-gui.py.


When you run the application and press the button, you will see
a pop-up asking to you confirm with a Yes or No (Figure 4).
You can find out more about the pop-up boxes in guizero at
lawsie.github.io/guizero/alerts.
How about combining all of these ‘features’ into one
great GUI? Figure 4 Yes, we’re sure!

WINDOW WIDGET
Pop-up boxes can be used to ask users You can control whether a Window is on screen
questions, but they are really simple. using the show() and hide() methods.
If you want to do show additional information
or ask for supplementary data, you could use the window.show()
Window widget to create multiple windows. window.hide()
Window is used in a similar way to App and
has many of the same functions. An app can be made to wait for a window to be
closed after it has been shown, by passing True
from guizero import App, Window to the wait parameter of show. For example:

app = App("Main window") window.show(wait=True)


window = Window(app, "2nd Window")
You can find out more about how to use multiple
app.display() windows in the guizero documentation:
lawsie.github.io/guizero/multiple_windows.

40 CREATE GRAPHICAL USER INTERFACES WITH PYTHON


CREATE GRAPHICAL USER INTERFACES WITH PYTHON

worst1.py / Python 3 DOWNLOAD


# Imports --------------- magpi.cc/guizerocode

from guizero import App, Text

# App -------------------

app = App("its all gone wrong", bg="dark green")

title = Text(app, text="Hard to read", size="14", font="Comic


Sans", color="green")

app.display()

worst2.py / Python 3
# Imports ---------------

from guizero import App, Text

# Functions -------------

def flash_text():
if title.visible:
title.hide()
else:
title.show()

# App -------------------

app = App("its all gone wrong", bg="dark green")

title = Text(app, text="Hard to read", size="14", font="Comic


Sans", color="green")

app.repeat(1000, flash_text)

app.display()

Chapter 5 World’s Worst GUI 41


www.dbooks.org
worst3.py / Python 3
# Imports ---------------

from guizero import App, Slider, Text


from time import ctime

# Functions -------------

def update_date():
the_date.value = ctime(date_slider.value)

# App -------------------

app = App("Set the date with the slider")


the_date = Text(app)
date_slider = Slider(app, start=0, end=999999999, command=update_
date)

app.display()

worst4.py / Python 3
# Imports ---------------
from guizero import App, Combo
from string import ascii_letters

# App -------------------

app = App("Enter your name")

a_letter = Combo(app, options=" " + ascii_letters, align="left")

app.display()

42 CREATE GRAPHICAL USER INTERFACES WITH PYTHON

You might also like