Easy Way to Create a GUI Application for Your Project in Python

1. It’s surprisingly easy to create your own GUI app nowadays

Modern solutions for programming became extremely accessible.

Figure. Example GUI app

Python programming language is easy and intuitive to learn and lacks unnecessary syntax caveats which may confuse young players. Making an app that simplifies our life, solves some problems or just outputs funny things is as easy as ever before.

Making a GUI app for your already existing application will make it not only more accessible to non-terminal people but will also simplify using it and make it more error-proof.


2. Requirments and installation

Few things are required:

  • some python script
  • Internet to download package
  • a monitor to dispaly GUI app ;)

In this tutorial, a PySimpleGUI package will be used [1]. There are many more solutions but this is the one I’ve used. My motivation for writing this tutorial was how fast I managed to bring up a working GUI for my project. How easy was it to code each button’s function and user interface. I literally had an app in 15 minutes!

To install the mentioned package in the terminal enter:

1
python3 -m pip install pysimplegui

You may also need to install thinker, for Python3:

1
sudo apt install python3-tk

3. First steps

How to start with GUI, based on my example script discussed below.

My Python Script

In my case, in the game ARK Survival Evolved there is an option to make ammo out of basic ingredients. First, it is needed to gather Stone and Flint. Flint can also be made out of Stone. Secondly, Stone and Flint are used to make Spatkpowder. Combining it with Charcoal, Gunpowder can be made. Out of it, the Ammo can be crafted with the help of Metal Ingot.

Each of the crafting steps requires a certain amount of each ingredient to get some amount of output product. Numerical values don’t matter in this example.

Writing a program that would provide a sum of all required ingredients to make a desired amount of Ammo is a handy way to know when to stop harvesting shared in the game World. Or maybe even better: to calculate how much ammo can be made from already gathered supplies. That’s exactly what I’ve done and the output is below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<=== To make 1004 Advanced Rifle Bullet ===>
Required Metal Ingot: 502
Required Gunpowder: 4518:
Required Sparkpowder: 3012:
Stone: 1004
Flint: 2008:
Stone: 4016
Required Charcoal: 3012

Totalling Stone (4016) to put into Grinder
Totalling Flint (2008) and Stone (1004) and Charcoal (3012) to put into Laboratory
Tottaling Metal Ingot (502) and Gunpowder (4518) to put into Fabricator

Total Stone to be collected: 5020
Total Charcoal to be collected: 3012
Total Metal Ingot to be collected: 502

Source code as well as a source code for GUI app can be found here: [2]

GUI requirements

I wanted it to present the above info based on the provided amount of Ammo desired. It should update constantly, or when an Apply button is pressed.

Basics

First of all, import:

1
import PySimpleGUI as sg

Below the import the window is created:

1
window = sg.Window("ARKulator", layout)

It contains the parameters of the physical GUI window that will appear.

  • "ARKulator" is a Title of the window, usually in the middle of the top bar.
  • layout defines the, well, the layout of the elements in the window. It should be defined here or before the sg.Window.

layout is of a form:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
layout = [
[ sg.Text("How much ammo:\t"),
sg.In(size=(int(horizontal_size/2), 1), enable_events=True, key="_AMMO_AMOUNT_", default_text='0')],
[ sg.Text("How much Flint:\t"),
sg.In(size=(int(horizontal_size/2), 1), enable_events=True, key="_FLINT_AMOUNT_", default_text='0')],
[ sg.Button("Apply", enable_events=True, key="_APPLY_BUTTON_") ],
[ sg.Text("<=== Advanced Rifle Ammo ===>")],

[ sg.Multiline("Provide number of ammo demanded ^", size = (horizontal_size,20), enable_events=True,key="_OUTPUT_TEXT_") ],

[ sg.Text("To exit:"),
sg.VSeparator( pad=(50,0) ),
sg.Button("Do not exit", enable_events = True, key = "_EXIT_BUTTON_") ]

]

It will produce the following GUI:

Figure. Produced GUI layout

Describing the layout which starts with:

1
2
3
layout = [

]

Here, all elements will be included.
Each next [] inside represents the vertical line of elements. If we want a certain Text field, and right next to it a Text box for the user input, and at the end a button to apply field it will look like that:

1
2
3
4
5
6
layout = [
[ sg.Text("How much Flint:\t"),
sg.In(size=(int(horizontal_size/2), 1), enable_events=True, key="_FLINT_AMOUNT_", default_text='0'),
sg.Button("Apply", enable_events=True, key="_APPLY_BUTTON_")
],
]

will give:

Figure. Simple GUI layout example.

Each field has its own parameters, like default value, size and behavior. Most important is the key='' which is like the index of the element - it directly leads to it. Give each element an individual name.

Each next [] in layout will present the next line of elements.

In my example, there are several lines of elements.

How to control input and outputs?

Similar, to the Arduino sketch: with a while True loop:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
while True:
event, values = window.read()
if event == "_EXIT_BUTTON_" or event == sg.WIN_CLOSED:
break

if event in ["_AMMO_AMOUNT_", "_FLINT_AMOUNT_", "_APPLY_BUTTON_"]:
try:
amount_of_flint = int(values['_FLINT_AMOUNT_'])
except:
amount_of_flint = 0
window['_FLINT_AMOUNT_'].update(0)

try:
amount_of_ammo = int(values["_AMMO_AMOUNT_"])
except:
amount_of_ammo = 0
window['_AMMO_AMOUNT_'].update(0)
try:
window["_OUTPUT_TEXT_"].update(f'{make_ammo(amount_of_ammo, amount_of_flint)}\nAmount of flint{amount_of_flint}')
except:
window["_OUTPUT_TEXT_"].update(f'Provided value is not a number, lol\
\nHow much ammo do you think is: {amount_of_ammo} ammo?')
amount_of_ammo = -1

In event, values = window.read() program catches user inputs. It registers what event and where it happened.

1
2
if event == "_EXIT_BUTTON_" or event == sg.WIN_CLOSED:
break

will check if the defined Exit Button was pressed, or if the Red X was pressed. In such case, the while True loop will break and the last line of the whole code: window.close() will close the window and end the execution.

Similar to the exit part of the code the script checks what was pressed and what do to with it. I had to use several try: except:‘s cause without them, the script would crash if default 0 in the input field was attempted to be changed to something else (no character as input). After that, when the script has the ammo which I want to make (input variable) it will use a previously defined function to gather all of the ingredients. Having that, it will update the Text field named _OUTPUT_TEXT_ with .update().

1
window["_OUTPUT_TEXT_"].update("Whatever Text you want")

window['_AMMO_AMOUNT_'] can be used to update any other field, by changing its index name.

And that’s it, the final effect can be seen below.

Figure. Working script with full output.

As can be seen, the script will update on every change in input fields, so the Apply button is useless.


Conclusions

Creating a GUI app with the help of PySimpleGUI is extremely easy and fast in making basic GUI app. It will bring basic input and outputs to the graphical usage.


Sources

[1] https://www.pysimplegui.org/en/latest/

[2] https://github.com/AlekSmola/ARKulator

[3] https://realpython.com/pysimplegui-python/