Want to keep learning?

This content is taken from the Raspberry Pi Foundation & National Centre for Computing Education's online course, Scratch to Python: Moving from Block- to Text-based Programming. Join the course to learn more.

Skip to 0 minutes and 3 seconds A Graphical User Interface, or G-U-I, or GUI, is a visual way for users to interact with an application. By using the Python module guizero, you can add a graphical user interface to your Pokémon fetching program, like this one. It’s going to ask us which Pokémon we wish to download, and we can say, Charizard. And when we click the Fetch button, it goes off, downloads the image, and displays it for us. Now to make your GUI, let’s create a new Python program and save it as pokemon_gui.py. The first thing we’re going to do is we’re going to import from the guizero module the App. App is going to be the main window of our GUI. So let’s create it.

Skip to 0 minutes and 51 seconds Let’s say app equals App, open a bracket and close a bracket. And then we can also display our App.

Skip to 1 minute and 1 second Now we’ve done enough to create our very first GUI. Let’s give our program a run and just see what it looks like. So our App appears. It’s not very exciting. It’s blank, but we’re going to add to it now. So you can customise the appearance of your GUI by setting parameters when the App is created. So I’m going to give the App a different title. So I’m going to call it pokemon fetcher, and I’m also going to set its size. I’m going to change its width to be 300 and its height to be 200. And again, if I run my program, what we’ll see is that the title has changed and the size has changed.

Skip to 1 minute and 44 seconds Now a GUI is made up of widgets, which are added to the App. Widgets can be anything from simple text to a clickable button. Now your GUI’s going to use four widgets. It will use a Text widget to display the text across the top. It will use a TextBox widget to provide the box where we enter the name of the Pokémon, a PushButton to provide the button that we click to download the image, and then finally a Picture widget to actually display the image that we download. Now these additional widgets need to be imported from guizero. So let’s do that. We’re going to import Text, TextBox, Picture, and finally, PushButton.

Skip to 2 minutes and 26 seconds Now to create widgets, we do so after the App has been created but before it’s displayed. So the first widget I’m going to create is the Text widget that goes across the top, which asks us which Pokémon we wish to download. I need to tell it which App it belongs to and then set the text. So I’m going to say, “Which Pokémon do you wish to download?”

Skip to 2 minutes and 56 seconds And again, if we stop and run our program, what we will see is “which Pokémon do you wish to download?” has appeared at the top of our application. I’m going to add in the three other widgets, the TextBox, the PushButton, and the Picture. And again, if we run our application, what we will see is our widgets appear. Now you’ll notice that we don’t see a picture because at the moment, we haven’t told our Picture to display anything. We haven’t given it an image, so it’s basically invisible. But what we can do is we can change the image attribute of the Picture widget and set it to be the name of the image that we downloaded from the previous step.

Skip to 3 minutes and 39 seconds We run our program, and we should see the image that we downloaded previously.

Skip to 3 minutes and 47 seconds Now I’m going to add in a version of the fetch_pokemon function from the previous step, which downloads the image and saves it to the file.

Skip to 4 minutes and 1 second We can see the same imports that we imported previously in the fetch_pokemon function that we created in the previous step. There are two key differences. The first one is that the name of the Pokémon is now obtained from the TextBox widget. And then after the image is saved, the Picture widget is updated with the new version of the image that we just downloaded. Now to get our application to call our new function when the button is pressed, we need to set the command attributes, and the command attribute is going to be equal to the function we want to run when the button is pressed. So I’m going to say run the fetch_pokemon function when the button is pressed.

Skip to 4 minutes and 51 seconds So let’s give– let’s run our program and see if it’s working. So we run our program, “Which Pokémon do you wish to download?” And I’m going to say Charizard. You click Fetch. It goes off, fetches the image, saves it, and then updates the Picture widget to be the image that we just downloaded. Can you add some more features to your application? How about displaying the weight and the height of the Pokémon? What happens if the name of the Pokémon– perhaps it isn’t recognised? Can you display text to tell the user to try a different name? Share your failures, successes, and links to your finished GUI programs in the comments. Don’t forget to help each other out, and good luck.

Making it graphical

Using the Python module guizero, you can add a graphical user interface to your Pokémon-fetching program.

A graphical user interface (GUI) is a visual way for users to interact with an application. guizero hides many of the difficult concepts for creating GUIs, making this an easy tool which learners of all ages can use to get started.

My first GUI

Your GUI will ask the user to enter the name of a Pokémon, download it using the PokéAPI, and display it.

The Pokémon-fetching GUI where the user has entered the name Pikachu, and an image of a Pikachu is displayed underneath

You are going to create the GUI first, before moving onto downloading the Pokémon and displaying it.

  1. Create a new Python program called pokemon_gui.py.

  2. Import App from the guizero module. App is the main window of your GUI.

    from guizero import App
    
  3. Create an App object.

    app = App()
    
  4. When the App has been created, it can be displayed by adding this line of code.

    app.display()
    
  5. Run your program. Your GUI should appear.

An empty window with the title guizero

You can customise the appearance of your GUI by setting parameters when the App is created, e.g. changing the title and the size of the window.

app = App(title='Pokemon Fetcher', width=300, height=200)

Adding ‘widgets’ to your GUI

A GUI is made up of widgets (components) which are added to the App. A widget can be anything from simple text to a button.

Your GUI will use four widgets:

  • Text to show the message “Which Pokémon do you want to fetch?”
  • TextBox where the user can enter the name of the Pokémon
  • PushButton which when pressed will download the Pokémon
  • Picture which will display the image

An illustration of the Pokémon GUI application where the App, Text, TextBox, PushButton, and Picture widgets are labelled

  1. Additional widgets need to be imported. Modify your program to import the widgets by changing the import at the top of your program.

    from guizero import App, Text, TextBox, PushButton, Picture
    
  2. Add a Text widget to your GUI to display a message.

    app = App(title='Pokemon Fetcher', width=300, height=200)
    
    welcome = Text(app, text="Which Pokemon do you want to fetch?")
    
    app.display()
    

    Note: All widgets need to be created after the App, but before the App is displayed.

  3. Run your program, you should see your message displayed in the Text widget at the top of your GUI.

    Pokémon-fetcher window, with the message displayed at the top

  4. Create the TextBox, PushButton, and Picture widgets after the welcome message.

    welcome = Text(app, text="Which Pokemon do you want to fetch?")
    
    input_box = TextBox(app)
    submit = PushButton(app, text='Fetch')
    icon = Picture(app)
    
  5. Run your program to see the widgets you added.

    GUI app with additional text box and button, the Picture widget is not visible

The Picture widget isn’t currently displaying anything so it’s “invisible”. To display the pokemon image you downloaded in the previous step you can to set the image parameter of the Picture to the filename of the image. e.g.

icon = Picture(app, image="poke.gif")

Fetching your Pokémon

Each time the Fetch button is pressed, the image of the Pokémon whose name is entered should be displayed.

To display the Pokémon image, you will reuse the fetch_pokemon code you created in the previous step.

  1. Add the required modules at the top of your program.

    from pokebase import pokemon
    from requests import get
    from PIL import Image
    from io import BytesIO
    

In the previous example you captured the name of the Pokémon to fetch using an input command. In your GUI, the user_input text box wll store the name of your Pokémon. You can read the contents of a text box using its value property.

  1. Create a new fetch_pokemon function and get the name of the Pokémon from the text box. This function will be called when the button is pressed.

    def fetch_pokemon():
        name = input_box.value
    
  2. Add the code you wrote previously to download the Pokémon image and save it to a file.

    def fetch_pokemon():
        name = input_box.value
        poke = pokemon(name)
        pic = get(poke.sprites.front_default).content
        image = Image.open(BytesIO(pic))
        image.save('poke.gif')
    
  3. You can now set the icon widget’s value property to the name of the file and display the image.

    def fetch_pokemon():
        ...
        image.save('poke.gif')
        icon.value = 'poke.gif'
    
  4. The final step is to change the PushButton widget to call the fetch_pokemon function each time it is pressed. You can do this by setting the command parameter when it is created.

    submit = PushButton(app, text='Fetch', command=fetch_pokemon)
    
  5. Run your program.

    The fetch_pokemon function will run when the submit button is pressed. The image of the Pokémon is downloaded, saved, and then displayed in the icon image widget.

    Animation of the Pokémon name Charizard being entered and its image being displayed

Challenge

  • Can you add some more features to your application? How about displaying the weight and height of the Pokémon?
  • What happens if the name of the Pokémon is not recognised? Can you display text to tell the user to try a different name?

You can find out more about how to use guizero at lawsie.github.io/guizero.

Share your failures, successes, and links to your finished GUI programs using your link from Pastebin in the comments! Be sure to help other participants out if you can answer their questions.

Share this video:

This video is from the free online course:

Scratch to Python: Moving from Block- to Text-based Programming

Raspberry Pi Foundation