Simple GUI application development using PyperCard

In this chapter we will learn about creating very simple GUI application using [PyperCard](https://pypercard.readthedocs.io/en/latest/). PyperCard is a HyperCard inspired Pythonic GUI framework for beginner programmers.

Installing PyperCard in a virtualenv

The first step would be installing PyperCard in a virtualenv.

python3 -m venv venv
source venv/bin/activate
python3 -m pip install pypercard

This may take some time, and specially while building Kivy, which is a dependency.

If you see any error in building Kivy on your distribution, you will have to install all dependencies on your operating system.

On Debian Buster

sudo apt install libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev pkg-config libgl1-mesa-dev libgles2-mesa-dev python3-setuptools libgstreamer1.0-dev git-core gstreamer1.0-plugins-{bad,base,good,ugly} gstreamer1.0-{omx,alsa} python3-dev libmtdev-dev xclip xsel libjpeg-dev mesa-common-dev

Hello World example

1from pypercard import Card, CardApp
2
3
4card = Card("hello", text="Hello, World!", text_color="yellow")
5
6app = CardApp(stack=[card, ])
7app.run()

In the first line, we are importing two classes from the module. Card is the class for every screen in our application, and CardApp is the primary application.

Note

Remember that each card in your application must have an unique name.

If you execute the code, python3 hello.py, you will see the following GUI window. It does not do much, it shows the string “Hello World!” with the text color we mentioned (Yellow).

_images/helloworld_pyper.png

Two Cards and a button

 1from pypercard import Card, CardApp
 2
 3
 4first_card = Card(
 5    "first_card",
 6    text="Hello, World!",
 7    text_color="yellow",
 8    buttons=[{"label": "Next", "target": "byescreen"}],
 9)
10card2 = Card("byescreen", text="Hack the planet!", text_color="white")
11
12app = CardApp(stack=[first_card, card2])
13app.run()

In this code, we have two different cards. The first_card also got a button, with a text Next, and the target as the name of the next card to show. In this case, we are showing the card named bye

_images/twocard_pyper.gif

Taking simple text input

In this example, we will learn how to take simple text input.

 1from pypercard import Card, CardApp, Inputs
 2
 3
 4def store_name(data_store, form_value):
 5    """
 6    Stores the user input in the data_store dictionary
 7    """
 8    if form_value:
 9        data_store["name"] = form_value
10        return "showname"
11    else:
12        return "error"
13
14
15card = Card(
16    "start",
17    text="Enter your name",
18    text_color="yellow",
19    form=Inputs.TEXTBOX,
20    buttons=[{"label": "Next", "target": store_name}],
21)
22
23card2 = Card("showname", text="May the force be with you {name}.", text_color="white")
24
25errorcard = Card(
26    "error",
27    text="You forgot to enter a name",
28    text_color="RED",
29    buttons=[{"label": "Start again", "target": "start"}],
30)
31app = CardApp(stack=[card, card2, errorcard])
32app.run()

At line 1, we are importing Inputs, which has various graphical objects to take user input.

In line 19, you can see that we passed a new keyword argument to the card object called form and saying that it is a Inputs.TEXTBOX. Another big change is that as a target of the button, we are passing a function called store_name. This can be any function which takes two arguments, first one is called data_store, a dictionary passed from the application itself, and then form_value is the actual user input via the card. Here, we are checking if there is a proper user input, then we are storing the value in the dictionary with the key name and returning the next card name showname, otherwise we are showing the error card from the stack.

In line 23, we are creating the showname card, where you can see we can directly use any keyname of data_store.

_images/textinput_pyper.gif

Check name problem

Here is a small problem for you, change the code such a way, so that if the name starts with Python, then the next screen will tell us the version of Python we are running.

_images/checkname_pyper.gif

Check name solution

 1from pypercard import Card, CardApp, Inputs
 2import sys
 3
 4
 5def store_name(data_store, form_value):
 6    """
 7    Stores the user input in the data_store dictionary
 8    """
 9    if form_value:
10        if form_value.startswith("Python"):
11            data_store["msg"] = sys.version.replace("\n", "")
12        else:
13            data_store["msg"] = "May the force be with you {0}.".format(form_value)
14        return "showname"
15    else:
16        return "error"
17
18
19card = Card(
20    "start",
21    text="Enter your name",
22    text_color="yellow",
23    form=Inputs.TEXTBOX,
24    buttons=[{"label": "Next", "target": store_name}],
25)
26card2 = Card(
27    "showname",
28    text="{msg}",
29    text_color="white",
30    buttons=[{"label": "Start again", "target": "start"}],
31)
32
33errorcard = Card(
34    "error",
35    text="You forgot to enter a name",
36    text_color="RED",
37    buttons=[{"label": "Start again", "target": "start"}],
38)
39app = CardApp(stack=[card, card2, errorcard])
40app.run()