PySimpleGUI – quick and easy interfaces

The Python PySimpleGUI project has two main goals, a simpler method for creating graphical user interfaces (GUIs), and common code for Tkinter, QT, xW and Web graphics.

I feel comfortable doing my own Python Tkinter and Web interfaces, but using common code for both local interfaces and Web apps could be extremely useful for Rasp Pi projects.

In the this blog I wanted to introduce PySimpleGUI by creating a local GUI/Web interface to control a Raspberry Pi Rover, all in less than 60 lines of code.

Getting Started with PySimpleGUI

The Python PySimpleGUI project has a number of “ports” or versions. The main version is for Tkinter based graphics and it is very fully featured. The versions for Qt,Wx and Web graphics are still in development so some testing may be required if you are hoping for full code compatibility between the different libraries.

There probably aren’t a lot of cases where you would want to flip between Qt, Wx and Tkinter graphic engines but it is remarkable that the possibility exists.

To install the default Tktinter  version of  Pysimplegui enter:

pip install pysimplegui

PySimplegui has a wide range of graphic widgets or elements. Graphic presentations are built by creating a layout variable. Graphic elements are placed in separate rows by open and closed square brackets.

gui_layout

A Button Interface Project

For my rover project I used a layout of 5 rows. The first row contains a feedback text, then rows 2-5 contains buttons.

The code below is a simple button app.


# Create a simple graphic interface
#
import PySimpleGUI as sg

layout = [ [sg.Text("the feedback" , key="feedback")],
           [sg.Button("FORWARD")],
           [sg.Button("LEFT"),sg.Button("RIGHT")],
           [sg.Button("STOP")],
           [sg.Button("QUIT")]
          ]
# Create the Window
window = sg.Window('My First App', layout)
# Event Loop to process "events"
while True:
    event, values = window.read()
    window['feedback'].Update(event) # show the button in the feedback text
    print(event,values)
    if event in (None, 'QUIT'):
        break
window.close()

The PySimplegui sg.window() call displays a window with the title and a layout definition (line 11). The window.read() will return events and values that have been changed (line 14). The feedback text element (line 5) is given a key name of  feedback, and this key name is used for updates to show the key press (line 15).

sg_basic

Standalone Web Apps with PySimpleGUIWeb

The PySimpleGUIWeb library is still under development, so be aware that not all the features in PySimpleGUI are fully supported in the Web version. PySimpleGUIWeb is an excellent way to create a lightweight standalone Web interface, but it is important to note that it isn’t designed to be a multi-page/multi-user Web environment.

To install PySimpleGUIWeb enter:

pip install remi
pip install pysimpleguiweb

The PySimpleGUIWeb window() call has a few more options, such as:

  • web_ip – the IP address to use for the PySimpleGUIWeb micro Web server
  • web_port – port on the micro Web server
  • web_start_browser – open a Web browser on app start

If you use our earlier button example but this time import PySimpleGUIWeb and add some web options we see an almost identical presentation however this time it’s in a Web interface.

sg_basic_web

Command line options can be used to toggle between the different libraries by:

import sys

# Pass any command line argument for Web use 
if len(sys.argv) > 1: # if there is use the Web Interface 
    import PySimpleGUIWeb as sg
    mode = "web"
else: # default uses the tkinter GUI
    import PySimpleGUI as sg
    mode = "tkinter"

Formatting of Display Elements

The next step is to adjust the graphic elements’  fonts, colors, and size properties.

Below is an example of changing the “FORWARD” button to have a size of 32 characters wide and 3 lines high with color and larger font.

[sg.Button("FORWARD", size=(32,3), 
  font="Ariel 32", 
  button_color=('white','green'))]

To make the interface more usable all the rover control buttons can be adjusted and the “QUIT” button can be left the default.

py_rovergui

Raspberry Pi Rover Interface

For my Raspberry Pi Rover project I used :

  • Arduino car chassis (~ $15),
  • a portable USB charger
  • Pimoroni Explorer Hat Pro (a Pi motor shield)

Below is the final code and it used a command line option (any character) to toggle into a Web application, otherwise it was the default PySimpleGUI interface. The application also included the Pi GPIO library to start/stop the car chassis motors.


# SGui_rover.py - use PySimpleGUI/Web to control a Pi Rover Pi
#

import sys
# Pass any command line argument for Web use
if len(sys.argv) > 1: # if there is use the Web Interface
    import PySimpleGUIWeb as sg
    mode = "web"
else: # default uses the tkinter GUI
    import PySimpleGUI as sg

import RPi.GPIO as gpio
gpio.setmode(gpio.BOARD)
# Define the motor pins to match your setup
motor1pin = 38 # left motor
motor2pin = 37 # right motor
gpio.setup(motor1pin, gpio.OUT)
gpio.setup(motor2pin, gpio.OUT)

# Send Action to Control Rover
def rover(action):
if action == "FORWARD":
    gpio.output(motor1pin, gpio.HIGH)
    gpio.output(motor2pin, gpio.HIGH)
if action == "LEFT":
    gpio.output(motor1pin, gpio.HIGH)
    gpio.output(motor2pin, gpio.LOW)
if action == "RIGHT":
    gpio.output(motor1pin, gpio.LOW)
    gpio.output(motor2pin, gpio.HIGH)
if action == "STOP":
    gpio.output(motor1pin, gpio.LOW)
    gpio.output(motor2pin, gpio.LOW)

# All the stuff inside your window.
myfont = "Ariel 32"
layout = [ [sg.Text(" ",size=(20,1) , key="feedback")],
[sg.Button("FORWARD", size=(32,3), font=myfont, button_color=('white','green'))],
[sg.Button("LEFT", size=(15,3), font=myfont),sg.Button("RIGHT", size=(15,3), font=myfont)],
[sg.Button("STOP", size=(32,3), font=myfont, button_color=('white','red'))],
[sg.Button("QUIT")]
]
# Create the Window
if mode == "web":
    window = sg.Window('PySimpleGUI Rover Control', layout,
        web_ip='192.168.0.106', web_port = 8888, web_start_browser=False)
else:
    window = sg.Window('PySimpleGUI Rover Control', layout )

# Event Loop to process "events" and pass them to the rover function
while True:
    event, values = window.read()
    print(event,values)
    if event in (None, 'QUIT'): # if user closes window or clicks cancel
        break
    window['feedback'].Update(event) # show the button in the feedback text
    rover(event)

window.close() # exit cleanly

py_sg_rover

Final Comment

I feel that PySimpleGUI and PySimpleGUIWeb have a lot of great potential for Raspberry Pi projects.

 

13 thoughts on “PySimpleGUI – quick and easy interfaces

  1. Very nicely written! I like it. Good screenshots, code was well done.
    There have been problems with “Realtime buttons” lately which has made doing “remote control interfaces” a little tricky. It’s rare to run into a good PySimpleGUIWeb tutorial like this. Thank you for making it.

    Like

    1. Thanks for the message. I’m glad that you liked it. I’m trying to do a Pi sensor write-up using PySimpleGUI/Web with some basic bar charts and line charts. I feel that this would be very useful for the IoT hobbyist.

      Like

  2. For robotic control, the RealtimeButton elements are once again working for the primary (tkinter) PySimpleGUI port. They had a bug that was fixed in the 4.39 and 4.40 releases. This button will return events for as long as the button is held.

    Like

    1. Hi Mike,

      I had some good luck with the PySimpleWebGUI. I’m not sure what the error you are seeing but I would double check the IP address that you are using. For this example I was using my IP, you’ll need to modify it for your setup.

      For my first tests I started simple, just a couple of buttons. I got it working in Tkinter than I used the Web library. I had some issues with the web version when I was doing more complex stuff with tabs and canvases.

      Like

  3. Thank you for the clear example of using PySimpleGUIWeb.

    My PySimpleGUI app is working nice. I made the change as you said for PySimpleGUIWeb and tried to run from the command line (just like my PySimpleGUI app).
    `python3 my_app.py`.

    This threw error from remi: “ModuleNotFoundError: No module named ‘HTMLParser'”
    So I ran `pip install HTMLParser`.

    Next it threw error from HTMLParser: “ModuleNotFoundError: No module named ‘markupbase'”.

    Command `pip install markupbase` is not working.

    Like

    1. Update:
      I downloaded the file markupbase.py from the web (I dont know which lcoation but a simple search with filename will bring it) and pasted it next to my_app.py. This fixed the issue.

      Like

    2. Hi,
      Are you running this on Windows or a Raspberry Pi? The reason that I ask is that neither HTMLParser or Markupbase are required on the Pi/Linux for PySimpleGUIWeb

      You can check dependencies by:
      $ pip show PySimpleGUIWeb

      It will show something like….

      Name: PySimpleGUIWeb
      Version: 0.39.0
      Summary: A port of PySimpleGUI that runs in a web browser. Utilizes Remi as the GUI framework
      Home-page: https://github.com/PySimpleGUI/PySimpleGUI
      Author: PySimpleGUI
      Author-email: PySimpleGUI@PySimpleGUI.org
      License: UNKNOWN
      Location: /home/pete/.local/lib/python3.8/site-packages
      Requires: remi
      Required-by:

      I don’t have either HTMLParser or markupbase installed on my Pi/Linux systems are things are working fine. (Note: remi is required).

      Anyways I’m glad that things are working for you.

      Like

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 )

Facebook photo

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

Connecting to %s