Computing · guizero · Teaching

gui zero – making Python GUIs really simple

When I was a teacher, I found it frustrating that it was not at all easy for students to create GUIs using Python. I used tkinter a little bit with my GCSE class and they instantly loved creating GUIs, but became frustrated because simple things were so difficult to do. After talking with some developers about this at Pycon UK, I decided to do something about it, and so I wrote a library called guizero which is meant to be used by children and removes all the unnecessary nasty bits without removing the intellectual requirements. Another thing which is important to me is that guizero is very easy to install and get started with – so there’s a completely no faff installation process, which is a winner if you’re struggling with getting your school techies to install things.

Download guizero and read the documentation here

But, promo flannel aside – is it any good for use in the classroom? On the CAS resources site, Stuart Lucas posted a popular “Book of programming challenges” resource (9651 downloads at the time of writing) so I thought I’d put guizero to the test to see how easy it is to complete a few of his challenges with a GUI and let you see for yourself.

Challenge 1

Write a program that will display a joke. Don’t display the punchline until the reader hits the enter key.
Extension: display the punchline in a different colour.

from guizero import *

# Method to call when button pressed
def display_joke():
   punchline.set("Poke him on")
# Set up the app
app = App("Joke teller")

joke = Text(app, "How do you get Pikachu on a bus?")
punchline = Text(app, text="", color="red")
button = PushButton(app, display_joke, text="Display punchline")

app.display()

challenge1

So this was pretty straightforward. I created two pieces of text and a button, with the second piece of text remaining blank until the button is pressed, at which point it fills in the punchline.

Challenge 2

Write a program that will ask you your name. It will then display ‘Hello Name’ where ‘Name’ is the name you have entered.

from guizero import *

# Method to display the greeting
def display_greeting():
   text.set("Hello " + name.get() )

# Set up the app
app = App("Hello machine")

text = Text(app, text="What is your name?")
name = TextBox(app)
button = PushButton(app, display_greeting, text="Greet me")

app.display()

challenge2a challenge2b

This challenge makes use of the get() and set() methods of the Text and TextBox widgets to easily get values typed in and display them elsewhere on the page.

Challenge 3

Write a program to work out the area of a rectangle. Collect the width and height of the rectangle from the keyboard. Calculate the area and display the result.

Extension: Display the volume of a cuboid. See what happens when you don’t type in numbers! Try to explain what has happened and why.

from guizero import *

# Method to calculate the area
def calculate():

    # Validation to check whether they typed in numbers
    if not height.get().isdigit() or not width.get().isdigit():
        error("Input error", "You must type in numbers for height and width")
    # Depth is allowed to be a digit or blank
    elif not depth.get().isdigit() and depth.get() != "":
        error("Input error", "You must type in a number for depth")

    # Perform the calculation
    else:
        area = int( height.get() ) * int( width.get() )
        if depth.get() == "":        
            result.set(str(area) + "cm squared")
        else:
            volume = area * int(depth.get())
            result.set(str(volume) + "cm cubed")
        

# Set up the app
app = App("Area and Volume calculator", layout="grid")

width_label = Text(app, text="Width:", grid=[0,0], align="left")
width = TextBox(app, grid=[0,1], align="left", width=30)

height_label = Text(app, text="Height:", grid=[1,0], align="left")
height = TextBox(app, grid=[1,1], align="left", width=30)

depth_label = Text(app, text="Depth:", grid=[2,0], align="left")
depth = TextBox(app, grid=[2,1], align="left", width=30)

button = PushButton(app, calculate, text="Calculate", grid=[3,1])

result_label = Text(app, text="Result:", grid=[4,0], align="left")
result = TextBox(app, grid=[4,1], align="left", width=30)

app.display()

challenge3a challenge3b challenge3c

This challenge was a little tricker. I used a grid layout so make the interface look tidy and line up the boxes properly. However, it wasn’t the GUI part which generated most of the code here, it was the validation. Since the get() methods always return strings I had to cast them to integers to do calculations (but this should already be familiar to students). I also saw a good excuse to use the error() box function to pop up a message if the validation check didn’t pass.

What do you think?

I’d love to hear your thoughts on guizero – whether they are positive or negative. Is this useful for you and your students? Is there something you’d like it to do but it doesn’t currently do? Would you like to see a tutorial on how to do a particular thing? Is there a bug? You can find the project on GitHub and add issues/ideas here, or leave a comment on this post, or tweet me @codeboom with your thoughts.

Advertisements

10 thoughts on “gui zero – making Python GUIs really simple

  1. isdigit() suggests to me that you can only test for a single digit.

    Could you add isinteger(), isfloat(), and isnumber() methods to gui zero? I think they should return false on empty strings, so that you can simplify a lot of your validation.

  2. oh, yes! there needs to be a few more of these.

    as the author of an educational pl designed to be as easy as possible tp learn, the gui is something that is never simple enough– i know there are a few “easy guis” out there, and theyre usually limited but a few more and a good balance might be found. i havent had more than a moments look at yours, but fwiw i think you have the right idea.

  3. I bought an inexpensive 5″ touch screen display for the pi and am using guizero for the user interface. The system sends me an alert email when it sees one of the input pins active. I would like several windows, one for an overview, another for entering email information, another to display a log of the email alerts. The user clicks a PushButton to open the desired window and closes it when done. Did you try having more than one App displaying at the same time? It sort of works for me, but not well. For instance the second App is not able to set the text in a TextBox, and strangely I don’t have to Display() the second App for it to show on the screen.

  4. I have been looking at guizero for a couple of days. I am teaching a middle school python class and want kids to create a choose your own adventure. Can you show an example of using if statements with either dropboxes or textboxes? Thanks.

    1. Something simple. Do you want anything fancier?

      from guizero import *

      def greeting():
      name = tbxName.get()
      if name == “Eric”:
      txtGreeting.set(“Welcome Sir ” + name)
      else:
      txtGreeting.set(“Welcome Mr./Ms. ” + name)

      app = App(title=”Demo 1″)
      tbxName = TextBox(app)
      PushButton(app, text=”GREETING”, command=greeting)
      txtGreeting = Text(app)
      app.display()

  5. I am using guizero in a first semester Intro to Programming course with good success. I have a question that I believe is style and not syntax, because my programs work as expected. If I define a widget that is never referenced, I don’t assign it a name, like:
    Text(app, “A label”)
    Is there a reason to consider this bad style? It creates less clutter in the code.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s