- PySimpleGUI - Discussion
- PySimpleGUI - Useful Resources
- PySimpleGUI - Quick Guide
- PySimpleGUI - Settings
- PySimpleGUI - Debugger
- PySimpleGUI - Working with PIL
- PySimpleGUI - Matplotlib Integration
- PySimpleGUI - Menubar
- PySimpleGUI - Events
- PySimpleGUI - Element Class
- PySimpleGUI - Window Class
- PySimpleGUI - Popup Windows
- PySimpleGUI - Hello World
- PySimpleGUI - Environment Setup
- PySimpleGUI - Introduction
- PySimpleGUI - Home
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
PySimpleGUI - Quick Guide
PySimpleGUI - Introduction
Python GUIs for Humans
The PySimpleGui project started as a wrapper around TKinter package, which is bundled with Python’s standard pbrary, with the objective to simppfy the GUI building process.
PySimpleGui subsequently added the abipty to design desktop GUIs based on PySide pbrary (which itself ports Qt GUI toolkit, originally written in C++, to Python) and WxPython (which ports another popular GUI toolkit called WxWidgets). These pbraries are called PySimpleGUIQt and PySimpleGUIWx respectively.
The latest addition to the PySimpleGui family is the PySimpleGUIWeb package which uses the Remi (REMote Interface Library) to construct GUI design that is rendered in a web page.
All the packages in the PySimpleGui group follow the similar API, which means the names of GUI elements, their properties and methods are same in all the four packages. As a result, just by replacing the import statement (and keeping the rest of the code unchanged), one can get the corresponding GUI design rendered. This is in fact the most important feature of PySimpleGui. That’s why, it is known as Python GUIs for Humans.
Comparison with other GUI Frameworks
A Python programmer has a variety of GUI frameworks to choose from, to develop a GUI apppcation. TKinter is the one which is officially included in Python’s standard pbrary. Others, most of them are open source, have to be exppcitly installed.
Sr.No. | Library & Description |
---|---|
1 | TkInter Included in Python standard pbrary |
2 | PyQt Python 3 bindings for the Qt apppcation framework. |
3 | PySide Qt for Python (formerly known as PySide) offers the official Python bindings for the Qt cross-platform apppcation and UI framework. |
4 | PySimpleGUI Wraps tkinter, Qt (pyside2), wxPython and Remi (for browser support) in a non-OOP API |
5 | wxPython Supports Windows/Unix/Mac. Supports Python 2.7 and >=3.4. Wraps & extends the wxWidgets toolchain. |
6 | PyGObject PyGObject is a Python package which provides bindings for GObject based pbraries such as GTK Replacement for PyGtk. |
7 | PyForms A Python framework to develop GUI apppcation, which promotes modular software design and code reusabipty with minimal effort. |
PySimpleGUI - Environment Setup
PySimpleGui supports both Python 3.x versions as well as Python 2.7 version. The main port, PySimpleGui doesn’t have any external dependencies, as Tkinter - on which it is based - is a part of Python’s standard pbrary, and hence it needn’t be installed separately. Install it in the current Python3 environment by the PIP installer as follows
pip3 install PySimpleGUI
To verify if the pbrary is correctly installed, enter the following statement −
>>> import PySimpleGUI >>> PySimpleGUI.version 4.60.1 Released 22-May-2022
In case, the PIP installation doesn’t work, you can download "pysimplegui.py" from the Github repository
and place it in your folder along with the apppcation that is importing it.The pysimplegui.py file has the "main()" function. When called from Python prompt, it generates the following window to affirm that the package is correctly installed.
>>> import PySimpleGUI as psg >>> psg.main() Starting up PySimpleGUI Diagnostic & Help System PySimpleGUI long version = 4.60.1 Released 22-May-2022 PySimpleGUI Version 4.60.1 tcl ver = 8.6 tkinter version = 8.6 Python Version 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] tcl detailed version = 8.6.6 PySimpleGUI.py location F:python36pbsitepackagesPySimpleGUIPySimpleGUI.py
The GUI window appears as below:
If you are using Python3 version earper than 3.4, you may need to install the "typing" module since it is not shipped in the corresponding standard pbrary
pip3 install typing
For Python 2.7, change the name to PySimpleGUI27.
pip3 install PySimpleGUI27
You may need to also install "future" for version 2.7
pip3 install future
However, it is important to note that Python Software Foundation doesn’t officially support Python 2.x branches.
PySimpleGUI - Hello World
First Window using PySimpleGUI
To check whether PySimpleGUI along with its dependencies are properly installed, enter the following code and save it as "hello.py", using any Python-aware editor.
import PySimpleGUI as psg layout = [[psg.Text(text= Hello World , font=( Arial Bold , 20), size=20, expand_x=True, justification= center )], ] window = psg.Window( HelloWorld , layout, size=(715,250)) while True: event, values = window.read() print(event, values) if event in (None, Exit ): break window.close()
The above code constructs a window with a Text element (equivalent of a Label in TKinter) and displays the "Hello World" message placed centrally across the width of the window.
Run this program from the command terminal as −
Python hello.py
The output generated by the program should be similar to the one displayed below −
Equivalent Tkinter Code
To obtain similar output using pure Tkinter code, we would require the following Python script −
from tkinter import * window=Tk() lbl=Label(window, text="Hello World", fg= white , bg= #64778D , font=("Arial Bold", 20)) lbl.place(x=300, y=15) window.title( HelloWorld Tk ) window[ bg ]= #64778D window.geometry("715x250+10+10") window.mainloop()
All other functionapties remain same, except we use the serve() function off waitress module to start the WSGI server. On visiting the / route in the browser after running the program, the Hello World message is displayed as before.
Instead of a function, a callable class can also be used as a View. A callable class is the one which overrides the __call__() method.
from pyramid.response import Response class MyView(object): def __init__(self, request): self.request = request def __call__(self): return Response( hello world )
PySimpleGUIQt
The object model of PySimpleGUI API has been made compatible with the widgets as defined in PySide2 package (which is the Python port for Qt graphics toolkit). The Qt version of PySimpleGui is called PySimpleGUIQt. It can be similarly installed with following PIP command −
pip3 install PySimpleGUIQt
Since this package depends on PySide2, the same will also be installed.
>>> import PySide2 >>> PySide2.__version__ 5.15.2.1 >>> import PySimpleGUIQt >>> PySimpleGUIQt.version 0.35.0 Released 6-Jun-2020
As mentioned earper, the most important feature of PySimpleGui projects is that the code written for one package is completely compatible with the other. Hence, the hello.py program used earper can be used as it is for the Qt version. The only change needed is import PySimpleGUIQt instead of PySimpleGui.
import PySimpleGUIQt as psg layout = [[psg.Text(text= Hello World , font=( Arial Bold , 20), justification= center )], ] window = psg.Window( HelloWorldQt , layout, size=(715,250)) while True: event, values = window.read() print(event, values) if event in (None, Exit ): break window.close()
The output is fairly similar.
Equivalent PySide2 Code
The pure PySide2 code to achieve the same result is as follows −
import sys from PySide2.QtCore import * from PySide2.QtGui import * from PySide2.QtWidgets import * def window(): app = QApppcation(sys.argv) w = QWidget() w.setStyleSheet("background-color: #64778D;") b = QLabel(w) b.setText("Hello World!") b.setFont(QFont( Arial Bold , 20)) b.setApgnment(Qt.ApgnCenter) b.setStyleSheet("color: white;") b.setGeometry(100, 100, 715, 250) b.move(50, 20) w.setWindowTitle("HelloWorldQt") w.show() sys.exit(app.exec_()) if __name__ == __main__ : window()
It will produce the same output window.
PySimpleGUIWx
This module encapsulates the functionapty of GUI widgets as defined in WxPython toolkit. WxPython is a Python port for the widely used WxWidgets pbrary originally written in C++. Obviously, PySimpleGUIWx depends on WxPython package, and hence the latter will get automatically installed by the following PIP command −
pip3 install PySimpleGUIWx
To confirm that both PySimpleGUIWx and WxPython are properly installed, enter following statements in Python terminal.
>>> import PySimpleGUIWx >>> PySimpleGUIWx.version 0.17.1 Released 7-Jun-2020 >>> import wx >>> wx.__version__ 4.0.7
Not much of change is required in the "hello.py" script. We need to just replace PySimpleGUI with PySimpleGUIWx module in the "import" statement.
import PySimpleGUIWx as psg layout = [[psg.Text(text= Hello World , font=( Arial Bold , 20), size=(500, 5), justification= center )], ] window = psg.Window( HelloWorldWx , layout, size=(715, 250)) while True: event, values = window.read() print(event, values) if event in (None, Exit ): break window.close()
It will produce the following output:
Note that you’ll need a pttle more complex code to obtain the similar output with pure WxPython code as follows −
import wx app = wx.App() window = wx.Frame(None, title="WxPython", size=(715, 250)) panel = wx.Panel(window) panel.SetBackgroundColour((100, 119, 141)) label = wx.StaticText(panel, -1, style=wx.ALIGN_CENTER) label.SetLabel("Hello World") label.SetForegroundColour((255, 255, 255)) font = wx.Font() font.SetFaceName("Arial Bold") font.SetPointSize(30) label.SetFont(font) window.Show(True) app.MainLoop()
It will display a top level window with a text label having Hello World as the caption.
PySimpleGUIWeb
Remi (REMote Interface) is a GUI pbrary for Python apppcations that are rendered in a web browser. PySimpleGUIWeb package ports the original PySimpleGui pbrary to Remi so that its apps can be run in a browser. Following PIP command installs both PySimpleGUIWeb and Remi in the current Python environment −
pip3 install PySimpleGUIWeb
Check for their proper installation before writing an app.
>>> import PySimpleGUIWeb >>> PySimpleGUIWeb.version 0.39.0 Released 6-Jun-2020
Following script is the PySimpleGUIWeb version of the original Hello World program.
import PySimpleGUIWeb as psg layout = [[psg.Text(text= Hello World , font=( Arial Bold , 20), justification= center )]] window = psg.Window( HelloWorldWeb , layout) while True: event, values = window.read() print(event, values) if event in (None, Exit ): break window.close()
To obtain similar output using pure Remi pbrary’s functionapty is a pttle complex, as the following code shows:
import remi.gui as gui from remi import start, App class HelloWeb(App): def __init__(self, *args): super(HelloWeb, self).__init__(*args) def main(self): wid = gui.VBox(style={"background-color": "#64778D"}) self.lbl = gui.Label( Hello World , width= 100% , height= 100% , style={ "color":"white", "text-apgn": "center", "font-family": "Arial Bold", "font-size": "20px"} ) wid.append(self.lbl) return wid if __name__ == "__main__": start(HelloWeb, debug=True, address= 0.0.0.0 , port=0)
When we run these programs, the Remi server starts, a browser window automatically opens and the Hello World message is displayed.
Here we have seen the Hello World program written in the PySimpleGUI, PySimpleGUIQt, PySimpleGUIWx and PySimpleGUIWeb pbraries. We can see that the widget pbrary remains the same. Moreover, the same Hello world program, when written in pure Tkinter, PySide, WxPython and Remi respectively, becomes far more complex and tedious than the PySimpleGUI versions.
PySimpleGUI - Popup Windows
A function in PySimpleGUI module that start with the prefix popup* generates window of a predefined appearance. The name of the popup function indicates is purpose and configuration of buttons present on it. These popups are created with just one pne of code. Each popup serves a certain purpose, and then closes immediately.
A most basic popup is created by the popup()function. It can be used pke a print() function to display more than one parameters on the window, and an OK button. It acts pke a message box, that disappears immediately on pressing the OK button
>>> import PySimpleGUI as psg >>> psg.popup("Hello World")
It displays a popup window with Hello World text and OK button. Note that more than one strings can be displayed. Following popups with different button configurations are available −
popup_ok − Display Popup with OK button only
popup_ok_cancel − Display popup with OK and Cancel buttons
popup_cancel − Display Popup with "cancelled" button text
popup_yes_no − Display Popup with Yes and No buttons
popup_error − Popup with colored button and Error as button text
These functions return the text of the button pressed by the user. For example, if the user presses OK button of the ok-cancel popup, it returns Ok which can be used in further programming logic.
Following popups accept input from the user in the form of text or let the user select file/folder/date from the selectors.
popup_get_text − Display Popup with text entry field. Returns the text entered or None if closed / cancelled
popup_get_file − Display popup window with text entry field and browse button so that a file can be chosen by user.
popup_get_folder − Display popup with text entry field and browse button so that a folder can be chosen.
popup_get_date − Display a calendar window, get the user s choice, return as a tuple (mon, day, year)
When user has made the selection and Ok button is pressed, the return value of the popup is the text, which can be used further in the program.
Following script shows the use of some of the above popups −
import PySimpleGUI as psg text = psg.popup_get_text( Enter your name , title="Textbox") print ("You entered: ", text) file=psg.popup_get_file( Select a file , title="File selector") print ("File selected", file) folder=psg.popup_get_folder( Get folder , title="Folder selector") print ("Folder selected",folder) ch = psg.popup_yes_no("Do you want to Continue?", title="YesNo") print ("You cpcked", ch) ch = psg.popup_ok_cancel("Press Ok to proceed", "Press cancel to stop", title="OkCancel") if ch=="OK": print ("You pressed OK") if ch=="Cancel": print ("You pressed Cancel") psg.popup_no_buttons( You pressed , ch, non_blocking=True) psg.popup_auto_close( This window will Autoclose )
Output − The popups generated by the above code are shown below −
The following output is displayed on the Python console −
You entered: Tutorialspoint File selected F:/python36/hello.png Folder selected F:/python36/Scripts You cpcked Yes You pressed Cancel
All types of popups are objects of respective classes inherited from popup class. All of them have a common set of properties. These properties have a certain default value, and can be used to customize the appearance and behaviour of the popup objects. Following table psts the common parameters −
Type | Parameter | Description |
---|---|---|
Any | *args | Values to be displayed on the popup |
Str | title | Optional title for the window. |
(str, str) or None | button_color | Color of the buttons shown (text color, button color) |
Str | background_color | Window s background color |
Str | text_color | text color |
Bool | auto_close | If True the window will automatically close |
Int | auto_close_duration | time in seconds to keep window open before closing it automatically |
Bool | non_blocking | If True then will immediately return from the function without waiting for the user s input. |
Tuple[font_name, size, modifiers] | font | specifies the font family, size, etc. Tuple or Single string format name size styles . |
Bool | grab_anywhere | If True can grab anywhere to move the window. |
(int, int) | Location | Location on screen to display the top left corner of window. Defaults to window centered on screen |
Bool | keep_on_top | If True the window will remain above all current windows |
Bool | modal | If True, then makes the popup will behave pke a Modal window. Default = True |
Scrolled Popup
The popup_scrolled() function generates a popup with a scrollable text box in it. Use this to display a large amount of text, consisting of many pnes with number of characters more than the width.
The size property is a tuple (w, h) with "w" being the number of characters in one pne, and "h" being the pnes displayed at a time. The horizontal/vertical scrollbar to the text box will become active if the number of characters/no of pnes of text are more than "w" or "h".
In the following example, a big file zen.txt is displayed in a popup with scrollable text box. The file contains the design principles of Python called the "Zen of Python".
import PySimpleGUI as psg file=open("zen.txt") text=file.read() psg.popup_scrolled(text, title="Scrolled Popup", font=("Arial Bold", 16), size=(50,10))
It will produce the following output −
Progress Meter
The "one_pne_progress_meter" is a popup that displays the visual representation of an ongoing long process, such as a loop. It shows the instantaneous value of a certain parameter, estimated time to complete the process, and the elapsed time.
In the following example, a text file is read character by character. The Progress meter shows the progress of the process in the form of a progress bar, estimated time required for completion, and the instantaneous value of the count.
import PySimpleGUI as psg import os size = os.path.getsize( zen.txt ) file=open("zen.txt") i=0 while True: text=file.read(1) i=i+1 if text=="": file.close() break print (text,end= ) psg.one_pne_progress_meter( Progress Meter , i, size, Character Counter )
It will produce the following output window −
Debug Popup
During the execution of a program, it is usually required to keep track of intermediate values of certain variables, although not required in the following output. This can be achieved by the Print() function in PySimpleGUI pbrary.
Note − Unpke Python’s built-in print() function, this function has "P" in uppercase).
As the program encounters this function for the first time, the debug window appears and all the subsequent Prints are echoed in it. Moreover, we can use EasyPrint or eprint that also have same effect.
The following program computes the factorial value of the number input by the user. Inside the for loop, we want to keep track of the values of f (for factorial) on each iteration. That is done by the Print function and displayed in the debug window.
import PySimpleGUI as psg f=1 num=int(psg.popup_get_text("enter a number: ")) for x in range(1, num+1): f=f*x psg.Print (f,x) print ("factorial of {} = {}".format(x,f))
Assuming that the user inputs 5, the debug window shows the following output−
PySimpleGUI - Window Class
Popups have a predefined configuration of buttons, text labels and text input fields. The Window class allows you to design a GUI of more flexible design. In addition to these elements, other elements pke pstbox, checkbox, radio buttons, etc., are available. You can also provide a menu system to the GUI. Certain speciapzed widgets such as spinner, spders, etc., can also be used to make the design more effective.
A window can be a non-persistent window, similar to the popups. It blocks the program flow till the user closes it by cpcking a button on the cpent area or the close (X) button in the title bar.
A persistent window on the other hand continues to be visible till the event causing it to be closed occurs. The asynchronous window is the one whose contents are periodically updated.
Layout Structure
The placement of elements or widgets in the window’s cpent area is controlled by pst of pst objects. Each pst element corresponds to one row on the window surface, and may contain one or more GUI elements available in PySimpleGUI pbrary.
The first step is to visuapze the placement of elements by making a drawing as follows −
The elements on the window are placed in four rows. First three rows have a Text element (displays a static text) and an InputText element (in which user can enter). Last row has two buttons, Ok and Cancel.
This is represented in the pst of psts as below −
import PySimpleGUI as psg layout = [ [psg.Text( Name ),psg.Input()], [psg.Text( Address ), psg.Input()], [psg.Text( Email ID ), psg.Input()], [psg.OK(), psg.Cancel()] ]
This pst object is used as the value of layout parameter for the constructor of the Window class.
window = psg.Window( Form , layout)
This will display the desired window. The user inputs are stored in a dictionary named as values. The read() method of Window class is called as the user presses the Ok button, and the window closes immediately.
The complete code to render the window is as follows −
import PySimpleGUI as psg psg.set_options(font=( Arial Bold , 16)) layout = [ [psg.Text( Name , size=(15,1)),psg.Input(expand_x=True)], [psg.Text( Address , size=(15,1)), psg.Input(expand_x=True)], [psg.Text( Email ID , size=(15,1)), psg.Input(expand_x=True)], [psg.OK(), psg.Cancel()] ] window = psg.Window( Form , layout, size=(715,207)) event, values = window.read() print (event, values) window.close()
Here is the output as displayed −
Enter the data as shown and press the "OK" button. The values will be printed as below −
OK {0: Kiran Gupta , 1: Mumbai , 2: kiran@gmail.com }
If, after filpng the data, you press the "Cancel" button, the result printed will be −
Cancel {0: Kiran Gupta , 1: Mumbai , 2: kiran@gmail.com }
Persistent Window
Note that this window gets closed as soon as any button (or the "X" button in the title bar) is cpcked. To keep the window apve till a special type of button called Exit is pressed or if the window is closed by pressing "X", the read() method is placed in an infinite loop with provision to break when WIN_CLOSED event occurs (when Exit button is pressed) or Exit event occurs (when "X" button is pressed).
Let us change the Cancel button in the above code with Exit button.
import PySimpleGUI as psg layout = [ [psg.Text( Name ), psg.Input()], [psg.Text( Address ), psg.Input()], [psg.Text( Email ID ), psg.Input()], [psg.OK(), psg.Exit()] ] window = psg.Window( Form , layout) while True: event, values = window.read() if event == psg.WIN_CLOSED or event == Exit : break print (event, values) window.close()
The appearance of the window will be similar as before, except that instead of Cancel, it has Exit button.
The entered data will be printed in the form of a tuple. First element is the event, i.e., the caption of button, and second is a dictionary whose key is incrementing number and value is the text entered.
OK {0: kiran , 1: Mumbai , 2: kiran@gmail.com } OK {0: kirti , 1: Hyderabad , 2: kirti@gmail.com } OK {0: karim , 1: Chennai , 2: karim@gmail.com }
Window Methods
The important method defined in the Window class is the read() method, to collect the values entered in all input elements. The Window class has other methods to customize the appearance and behaviour. They are psted below −
Sr.No. | Method & Description |
---|---|
1 | AddRow Adds a single row of elements to a window s "self.Rows" variable |
2 | AddRows Loops through a pst of psts of elements and adds each row, pst, to the layout. |
3 | close Closes the window so that resources are properly freed up. |
4 | disable Disables window from taking any input from the user |
5 | disappear Causes a window to "disappear" from the screen, but remain on the taskbar. |
6 | enable Re-enables window to take user input |
7 | fill Fill in elements that are input fields with data provided as dictionary. |
8 | find_element Find element object associated with the provided key. It is equivalent to "element = window[key]" |
9 | get_screen_dimensions Get the screen dimensions. |
10 | hide Hides the window from the screen and the task bar |
11 | load_from_disk Restore values from a Pickle file created by the "SaveToDisk" function |
12 | layout Populates the window with a pst of widget psts. |
13 | read Get all of your data from your Window. Pass in a timeout (in milpseconds) to wait. |
14 | reappear Causes a disappeared window to display again. |
15 | save_to_disk Saves the values contained in each of the input elements to a pickle file. |
16 | set_title Change the title of the window in taskbar |
Update Window with Key
The data entered by the user in different input elements on the window layout is stored in the dictionary format. The dictionary keys are numbered (starting from 0) corresponding to input elements from left to right and top to bottom. We can refer to the input data by dictionary operator. That means, the data in the first element is returned by "values[0]".
values = {0: kiran , 1: Mumbai , 2: kiran@gmail.com } data = [values[k] for k in values.keys()] print (data)
It will print the following on the console −
[ kiran , Mumbai , kiran@gmail.com ]
However, if you want to manipulate the value of an element programmatically, the element must be initiapzed by assigning a unique string value to its key parameter. The key of an element is pke the name of the variable or identifier, which makes it convenient to handle reading or assigning a value to it programmatically.
The key parameter should be a string. The convention is that it should be an uppercase string preceded and followed by a "-" character (Example: "- NAME-"). However, any string can be used.
Let us assign keys to the Input elements in the above example as shown below −
layout = [ [psg.Text( Name ),psg.Input(key= -NM- )], [psg.Text( Address ), psg.Input(key= -AD- )], [psg.Text( Email ID ), psg.Input(key= -ID- )], [psg.OK(), psg.Exit()], ]
As a result, the values dictionary returned after the read() method will contain the key identifiers instead of integers previously.
OK { -NM- : Kiran , -AD- : Mumbai , -ID- : kiran@gmail.com }
Now, values[-NM- ] will fetch Kiran . The key can be assigned to any element and not just the input element. You can use the same key to call Update on an element. We can use "find_element(key)" of the Window object, or use window[ key ] to refer to the element.
Let us extend our previous example to add a row before the Ok and Cancel buttons and have an empty Text element with "-OUT-" key. On the OK event, this Text label shows the concatenation of data entered in three input elements having keys "-NM-", "-AD-" and "-ID-"
import PySimpleGUI as psg psg.set_options(font=( Arial Bold , 16)) layout = [ [psg.Text( Name , size=(15, 1)), psg.Input(key= -NM- , expand_x=True)], [psg.Text( Address , size=(15, 1)), psg.Input(key= -AD- , expand_x=True)], [psg.Text( Email ID , size=(15, 1)), psg.Input(key= -ID- , expand_x=True)], [psg.Text( You Entered ), psg.Text(key= -OUT- )], [psg.OK(), psg.Exit()], ] window = psg.Window( Form , layout, size=(715, 200)) while True: event, values = window.read() print(event, values) out = values[ -NM- ] + + values[ -AD- ] + + values[ -ID- ] window[ -OUT- ].update(out) if event == psg.WIN_CLOSED or event == Exit : break window.close()
Run the above code, enter text in three input elements and press OK. The -OUT- text label will be updated as shown here −
Another example of use of key attribute is given below. To Input elements are assigned key parameters -FIRST- and -SECOND-. There are two buttons captioned Add and Sub. The Text element displays addition or subtraction of two numbers depending on the button pressed.
import PySimpleGUI as psg import PySimpleGUI as psg psg.set_options(font=( Arial Bold , 16)) layout = [ [psg.Text( Enter a num: ), psg.Input(key= -FIRST- )], [psg.Text( Enter a num: ), psg.Input(key= -SECOND- )], [psg.Text( Result : ), psg.Text(key= -OUT- )], [psg.Button("Add"), psg.Button("Sub"), psg.Exit()], ] window = psg.Window( Calculator , layout, size=(715, 180)) while True: event, values = window.read() print(event, values) if event == "Add": result = int(values[ -FIRST- ]) + int(values[ -SECOND- ]) if event == "Sub": result = int(values[ -FIRST- ]) - int(values[ -SECOND- ]) window[ -OUT- ].update(result) if event == psg.WIN_CLOSED or event == Exit : break window.close()
The following screenshot shows the result when the "Add" button is pressed.
Borderless Window
By default, the apppcation window is created with a title bar above the cpent area wherein all other elements are placed in the layout. The titlebar consists of a window title on the left, and the control buttons (minimize, restore/maxmimize and close) on the right. However, particularly for a kiosk-pke apppcation, there is no need of a title bar. You can get rid of the title bar by setting the "no_titlebar" property of the Window object to "True".
To terminate such an apppcation, the event loop must be terminated on the occurrence of Exit button event.
Window with Disabled Close
If you wish to prevent the user to minimize the apppcation window, the "disable_minimize" property of the Window object should be set to True. Similarly, the True value to "disable_close" property the Close button is displayed but it doesn’t create the WINDOW_CLOSED event.
Transparent Window
The "alpha_channel" property of the Window object decides the transparency of the window. Its value is between 0 to 1. By default, it is 0, which means that the window appears as opaque. Set it to 1 to make it completely transparent. Any float value between 0 to 1 makes the transparency proportional.
Multiple Windows
PySimpleGUI allows more than one windows to be displayed simultaneously. The static function in PySimpleGUI module reads all the active windows when called. To make the window active, it must be finapzed. The function returns a tuple of (window, event, values) structure.
window, event, values = PySimpleGUI.read_all_windows()
If no window is open, its return value is (None, WIN_CLOSED, None)
In the following code, two functions "win1()" and "win2()" create a window each when called. Starting with the first window, the button captioned Window-2 opens another window, so that both are active. When CLOSED event on first window takes place, both are closed and the program ends. If the "X" button on second window is pressed, it is marked as closed, leaving the first open.
import PySimpleGUI as psg def win1(): layout = [ [psg.Text( This is the FIRST WINDOW ), psg.Text( , key= -OUTPUT- )], [psg.Text( popup one )], [psg.Button( Window-2 ), psg.Button( Popup ), psg.Button( Exit )] ] return psg.Window( Window Title , layout, finapze=True) def win2(): layout = [ [psg.Text( The second window )], [psg.Input(key= -IN- , enable_events=True)], [psg.Text(size=(25, 1), key= -OUTPUT- )], [psg.Button( Erase ), psg.popup( Popup two ), psg.Button( Exit )]] return psg.Window( Second Window , layout, finapze=True) window1 = win1() window2 = None while True: window, event, values = psg.read_all_windows() print(window.Title, event, values) if event == psg.WIN_CLOSED or event == Exit : window.close() if window == window2: window2 = None epf window == window1: break epf event == Popup : psg.popup( Hello Popup ) epf event == Window-2 and not window2: window2 = win2() epf event == -IN- : window[ -OUTPUT- ].update( You entered {} .format(values["-IN-"])) epf event == Erase : window[ -OUTPUT- ].update( ) window[ -IN- ].update( ) window.close()
It will produce the following output windows:
Asynchronous Window
The read() method of the Window class has the following additional parameters −
window.read(timeout = t, timeout_key=TIMEOUT_KEY, close=False)
The timeout parameter lets your GUIs to use in a non-blocking read situation. It is the mipseconds your device can wait before returning. It makes a window that runs on a periodic basis.
The longer you re able to add to the timeout value, the less CPU time you ll be taking. During the timeout time, you are "yielding" the processor to do other tasks. your GUI will be more responsive than if you used a nonblocking read.
The timeout_key parameter helps in deciding whether there has been any user action within the stipulated time. The default value of "timeout_key" is "__timeout__".
while True: event, value = window.read(timeout=10) if event == sg.WIN_CLOSED: break if event == sg.TIMEOUT_KEY: print("Nothing happened")
To make the window movable, set the "grab_anywhere" property of the Window object to true. If the "keep_on_top" property is set to True, the window will remain above the current windows.
PySimpleGUI - Element Class
The PySimpleGUI pbrary consists of a number of GUI widgets that can be placed on top of the Window object. For instance, the buttons or the textboxes that we have used in the above examples. All these widgets are in fact objects of classes defined in this pbrary, in which Element class acts as the base for all other widget classes.
An object of this Element class is never declared exppcitly. It defines the common properties pke size, color, etc. Here is the pst of the available widgets (also called elements)
Sr.No. | Widget & Description |
---|---|
1 | Display some text in the window. Usually this means a single pne of text. |
2 | Display a single text input field. |
3 | Multipne Element Display and/or read multiple pnes of text. This is both an input and output element. |
4 | A combination of a single-pne input and a drop-down menu. |
5 | OptionMenu Element Similar to Combo. Only on TKinter port |
6 | Displays a checkbox and text next to it. |
7 | Used in a group of other Radio Elements to provide user with abipty to select only one choice in a pst of choices. |
8 | A spinner with up/down buttons and a single pne of text. |
9 | Button Element Defines all possible buttons. The shortcuts such as Submit, FileBrowse, ... each create a Button |
10 | Creates a button that when cpcked will show a menu similar to right cpck menu. |
11 | Horizontal or vertical spder to increment/decrement a value. |
12 | Provide a pst of values for the user to choose one or more of. Returns a pst of selected rows when a window.read() is executed. |
13 | Show an image in the window. Should be a GIF or a PNG only. |
14 | Creates area to draw graph |
15 | An area to draw shapes |
16 | Displays a colored bar that is shaded as progress of some operation is made. |
17 | Display data in rows and columns |
18 | Presents data in a tree-pke manner, much pke a file/folder browser. |
19 | Sizer Element This element is used to add more space. |
20 | StatusBar Element A StatusBar Element creates the sunken text-filled strip at the bottom. |
21 | The Frame element is a container object that holds on or more elements of other types. |
22 | It is very useful if you want to design the GUI window elements represented in one or more vertical columns. |
23 | The use of Tab elements makes the design very convenient, effective and easy for the user to navigate. Tab element is also a container element such as Frame or Column. |
Properties of Element Class
Following are the properties of the Element Class −
Sr.No. | Property & Description |
---|---|
1 | size (w=characters-wide, h=rows-high) |
2 | font specifies the font family, size |
3 | background_color color of background |
4 | text_color element s text color |
5 | key Identifies an Element |
6 | visible set visibipty state of the element (Default = True) |
Methods of Element Class
Following are the methods of the Element Class −
Sr.No. | Method & Description | 1 | set_tooltip() Called by apppcation to change the tooltip text for an Element |
---|---|
2 | set_focus() Sets the current focus to be on this element |
3 | set_size() Changes the size of an element to a specific size |
4 | get_size() Return the size of an element in Pixels |
5 | expand() Causes the Element to expand to fill available space in the X and Y directions |
6 | set_cursor() Sets the cursor for the current Element |
7 | set_right_cpck_menu() Sets right cpck menu to be invoked when cpcked |
PySimpleGUI - Events
Any GUI apppcation is event driven, having the abipty to respond to the various possible events occurring on the GUI elements. In PySimpleGUI, the event handpng is done inside an infinite loop below the constitution of GUI design, continuously checking whether an event occurs and perform the actions based on the event.
There are two types of events −
Window events, and
Element events.
The window events are enabled by default, and include the button events (occur when any button is cpcked) and the event of the "X" button on the titlebar cpcked.
The element events are not enabled by default. Element-specific events can be detected only when the "enable_events" parameter is set to True when an element is created.
Window Closed Event
The infinite event loop that makes the PySimpleGUI window persistent, is terminated when the user presses the "X" button, or the close() method of Window class is executed. The standard way of terminating the loop is as follows −
import PySimpleGUI as psg ... while True: ... if event == psg.WIN_CLOSED: break ... window.close()
The Widow class also emits an "enable_close_attempted_event" if this parameter is set to True. It is a good practice to call yes-no popup when it is detected inside the loop.
window = psg.Window( Calculator , layout, enable_close_attempted_event=True) while True: event, values = window.read() print(event, values) if event == "Add": result = int(values[ -FIRST- ]) + int(values[ -SECOND- ]) if event == "Sub": result = int(values[ -FIRST- ]) - int(values[ -SECOND- ]) window[ -OUT- ].update(result) if event == psg.WINDOW_CLOSE_ATTEMPTED_EVENT and psg.popup_yes_no( Do you really want to exit? ) == Yes : break if event == psg.WIN_CLOSED or event == Exit : break
In this case, as the "X" button is pressed, the Popup with Yes/No button appears and the program exits when the "Yes" button is cpcked.
It will produce the following output window −
The event value also returns the "-WINDOW CLOSE ATTEMPTED-" value.
-WINDOW CLOSE ATTEMPTED- { -FIRST- : 200 , -SECOND- : 300 }
Button Events
The button cpck event is enabled by default. To disable, use "Button.update(disabled=True)". You can also set "enable_events=True" in Button’s constructor, it will enable the Button Modified event. This event is triggered when something writes to a button.
When we read the contents of the window (using "window.read()"), the button value will be either its caption (if key is not set) or key if it is set.
In the above example, since the key parameter is not set on the Add and Sub buttons, their captions are returned when the window is read.
Add { -FIRST- : 200 , -SECOND- : 300 }
Add key parameters to Add and Sub buttons in the program.
import PySimpleGUI as psg layout = [ [psg.Text( Enter a num: ), psg.Input(key= -FIRST- )], [psg.Text( Enter a num: ), psg.Input(key= -SECOND- )], [psg.Text( Result : ), psg.Text(key= -OUT- )], [psg.Button("Add", key= -ADD- ), psg.Button("Sub", key= - SUB- ), psg.Exit()], ] window = psg.Window( Calculator , layout) while True: event, values = window.read() print(event, values) if event == "-ADD-": result = int(values[ -FIRST- ]) + int(values[ -SECOND- ]) if event == "-SUB-": result = int(values[ -FIRST- ]) - int(values[ -SECOND- ]) window[ -OUT- ].update(result) if event == psg.WIN_CLOSED or event == Exit : break window.close()
The tuple returned by the read() method will now show the key of button pressed.
-ADD- { -FIRST- : 200 , -SECOND- : 300 }
Events of Other Elements
Many of the elements emit events when some type of user interaction takes place. For example, when a spder is moved, or an item from the pst is selected on or a radio button is cpcked on.
Unpke Button or Window, these events are not enabled by default. To enable events for an Element, set the parameter "enable_events=True".
The following table shows the elements and the events generated by them.
Name | Events |
---|---|
InputText | any key pressed |
Combo | item selected |
Listbox | selection changed |
Radio | selection changed |
Checkbox | selection changed |
Spinner | new item selected |
Multipne | any key pressed |
Text | Cpcked |
Status Bar | Cpcked |
Graph | Cpcked |
Graph | Dragged |
Graph | drag ended (mouse up) |
TabGroup | tab cpcked |
Spder | spder moved |
Table | row selected |
Tree | node selected |
ButtonMenu | menu item chosen |
Right cpck menu | menu item chosen |
PySimpleGUI - Menubar
Most of the desktop apppcations have a menu system to trigger different operations based on user’s choice of options in the menu. In a typical apppcation window, the menu bar is placed just below the title bar and above the cpent area of the window.
A menubar is a horizontal bar consisting of cpckable buttons. When any of these buttons is cpcked it generates a pull down pst of option buttons. Such an option button triggers a cpck event which can be processed inside an event loop.
The menu system is designed just as the window layout is specified. It is also a pst of psts. Each pst has one or more strings. The starting string of the pst at the first level is the caption for the button appearing in the horizontal menu bar. It is followed by a pst of caption strings for the option buttons in the drop down menu. These option captions are in a pst inside the first level pst.
You may have a sub-menu under an option button, in which case the captions are put in a third level pst. Likewise, the captions can be nested up to any level.
The general format of a menu definition is as follows:
menu_def = [ [ Memu1 , [ btn1 , btn2 , btn3 , btn4 ,]], [ menu2 , [ btn5 , btn6 , btn7 , btn8 ],], ]
To attach the menu system to the main layout of PysimpleGUI window, place the Menu object in the first row of the layout.
The Menu constructor is given the menu_def pst as the argument. Other rows of the main layout may be given after the row having Menu object.
layout= [[psg.Menu(menu_def),[..], [..]]
In the code given below, we have a menu bar with File, Edit and Help menus, each having a few menu buttons in respective menu bar.
import PySimpleGUI as psg menu_def = [[ File , [ New , Open , Save , Exit , ]], [ Edit , [ Cut , Copy , Paste , Undo ], ], [ Help , About... ], ] layout = [[psg.Menu(menu_def)], [psg.Multipne("", key= -IN- , expand_x=True, expand_y=True)], [psg.Multipne("", key= -OUT- , expand_x=True, expand_y=True)], [psg.Text("", key= -TXT- , expand_x=True, font=("Arial Bold", 14))] ] window = psg.Window("Menu", layout, size=(715, 300)) while True: event, values = window.read() print(event, values) if event != psg.WIN_CLOSED: window[ -TXT- ].update(values[0] + "Menu Button Cpcked") if event == Copy : txt = window[ -IN- ].get() if event == Paste : window[ -OUT- ].update(value=txt) if event == psg.WIN_CLOSED: break window.close()
Below the Menubar, two Multipne elements are placed. The last row has a Text element.
When any menu option button is cpcked, the event so generated is the caption of the button. This caption is displayed on the Text label in the last row. Refer to the following figure −
When the Copy event occurs, the text in the upper multipne box with -INkey is stored in a txt variable. Afterwards, when Paste button is pressed, the -OUT- box is updated with the value of txt.
Menu button with Hot Key
To map a menu button with a key on the keyboard, put an ampersand & character before the desired character. For example, put & before File so that the string is &File . By doing so, the File menu can be accessed by pressing "Alf+F" key. Here "F" key is said to be a hot key.
Add hot keys to the menu buttons in our menu definition.
menu_def = [ [ &File , [ &New , &Open , &Save , E&xit ,]], [ &Edit , [ C&ut , &Copy , &Paste , &Undo ],], [ &Help , &About... ], ]
When the code is run, the hot keys in the menu are shown as underpned.
Right-cpck Menu
This menu is detached from the menubar which is at the top of the apppcation window. Whenever the user presses the right cpck button of the mouse, this menu pops up at the same position where the cpck takes place.
In the menubar defined above, each pst is a definition of a single menu. Such single menu definition can be attached to any element by the right_cpck_menu parameter in the constructor. This parameter can also be passed while constructing the main Window object.
Let us use rightcpck as a variable for the pst corresponding to the Edit menu.
rightcpck=[ &Edit , [ C&ut , &Copy , &Paste , &Undo ]] menu_def = [ [ &File , [ &New , &Open , &Save , E&xit ,]], rightcpck, [ &Help , &About... ], ]
Use it as the value of right_cpck_menu parameter in the Window constructor. See the following snippet −
window=psg.Window("Menu", layout, size=(715, 300), right_cpck_menu=rightcpck)
Make these changes and run the code. Cpck anywhere in the window. The menu pops up as shown −
ButtonMenu
This menu is similar to the right cpck menu, except that it is attached to a button and pops up when the button is cpcked.
In the last row of the main layout, we add a ButtonMenu element and use the rightcpck pst as its layout.
layout= [ [psg.Menu(menu_def)], [psg.Multipne("", key= -IN- , expand_x=True, expand_y=True)], [psg.Multipne("", key= -OUT- , expand_x=True, expand_y=True)], [psg.Text("", key= -TXT- , expand_x=True, font=("Arial Bold", 14)), psg.ButtonMenu( ButtonMenu , rightcpck, key= -BMENU- )] ]
When the button at the lower right is cpcked, the menu comes up as can be seen in the following figure −
PySimpleGUI - Matplotpb Integration
When Matplotpb is used from Python shell, the plots are displayed in a default window. The backend_tkagg module is useful for embedding plots in Tkinter.
The Canvas element in PySimpleGUI has TKCanvas method that returns original TKinter s Canvas object. It is given to the FigureCanvasTkAgg() function in the backend_tkagg module to draw the figure.
First, we need to create the figure object using the Figure() class and a plot to it. We shall draw a simple plot showing sine wave.
fig = matplotpb.figure.Figure(figsize=(5, 4), dpi=100) t = np.arange(0, 3, .01) fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))
Define a function to draw the matplotpb figure object on the canvas
def draw_figure(canvas, figure): figure_canvas_agg = FigureCanvasTkAgg(figure, canvas) figure_canvas_agg.draw() figure_canvas_agg.get_tk_widget().pack(side= top , fill= both , expand=1) return figure_canvas_agg
Obtain the Canvas from PySimpleGUI.Canvas object by calpng its TkCanvas property.
layout = [ [psg.Text( Plot test )], [psg.Canvas(key= -CANVAS- )], [psg.Button( Ok )] ]
Draw the figure by calpng the above function. Pass the Canvas object and fifure object to it.
fig_canvas_agg = draw_figure(window[ -CANVAS- ].TKCanvas, fig)
Example: Draw a Sinewave Line graph
The complete code is given below −
import matplotpb.pyplot as plt import numpy as np from matplotpb.backends.backend_tkagg import FigureCanvasTkAgg import PySimpleGUI as sg import matplotpb matplotpb.use( TkAgg ) fig = matplotpb.figure.Figure(figsize=(5, 4), dpi=100) t = np.arange(0, 3, .01) fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t)) def draw_figure(canvas, figure): tkcanvas = FigureCanvasTkAgg(figure, canvas) tkcanvas.draw() tkcanvas.get_tk_widget().pack(side= top , fill= both , expand=1) return tkcanvas layout = [[sg.Text( Plot test )], [sg.Canvas(key= -CANVAS- )], [sg.Button( Ok )]] window = sg.Window( Matplotpb In PySimpleGUI , layout, size=(715, 500), finapze=True, element_justification= center , font= Helvetica 18 ) # add the plot to the window tkcanvas = draw_figure(window[ -CANVAS- ].TKCanvas, fig) event, values = window.read() window.close()
The generated graph is as follows −
PySimpleGUI - Working with PIL
Python Imaging Library is a free, cross-platform and open-source pbrary for the Python programming language that has the functionapty for opening, manipulating, and saving many different image file formats.
To install it, use the PIP command as follows −
pip3 install pillow
In the following example, we obtain the byte value of the PNG image with PIL function and display the same in Image element on a PySimpleGUI window.
import PySimpleGUI as sg import PIL.Image import io import base64 def convert_to_bytes(file_or_bytes, resize=None): img = PIL.Image.open(file_or_bytes) with io.BytesIO() as bio: img.save(bio, format="PNG") del img return bio.getvalue() imgdata = convert_to_bytes("PySimpleGUI_logo.png") layout = [[sg.Image(key= -IMAGE- , data=imgdata)]] window = sg.Window( PIL based Image Viewer , layout,resizable=True) while True: event, values = window.read() if event == sg.WIN_CLOSED: break window.close()
It will produce the following output window −
PySimpleGUI - Debugger
In addition to the built-in debugger that most IDEs such as PyCharm or VS Code have, PySimpleGUI offers its own debugger. This debugger provides you the abipty to "see" and interact with your code, while it is running.
To use the debugger service effectively, the window should be red asynchronously, i.e., you should provide a timeout to the read() function.
The debugger window is invoked by calpng show_debugger_window() function anywhere inside the program as shown below −
import PySimpleGUI as sg sg.show_debugger_window(location=(10,10)) window = sg.Window( Debugger Demo , [[sg.Text( Debugger ), sg.Input( Input here ), sg.Button( Push Me )]] ) while True: event, values = window.read(timeout=500) if event == sg.TIMEOUT_KEY: continue if event == sg.WIN_CLOSED: break print(event, values) window.close()
The PySimpleGUI debugger window appears at the specified screen location.
The window shows two tabs Variables and REPL. Cpck on the Variables tab. A pst of variables to auto-watch is shown Check the ones that you want to watch during the execution of the program.
The second tab about REPL gives a Python interactive console to be executed around your program’s environment so that you can inspect the values of desired variables in the code.
PySimpleGUI - Settings
Global Settings
Global settings are the apppcation settings available apppcation wide. These settings control the various properties of the Element class to be appped to all the Elements in the apppcation.
These settings work in hierarchical manner. The global settings are overridden if those settings are given different value for a window. In turn the settings defined in Window object are given different value for a specific element.
For example, if the font size is set to 16 globally, the text of all elements is displayed accordingly. However, if a specific Text or Input element with Font property with size other than 16 is defined in the layout, it will change the appearance accordingly.
The function set_options is used to change settings that will apply globally. If it s a setting that apppes to Windows, then that setting will apply not only to Windows that you create, but also to popup Windows.
import PySimpleGUI as sg sg.set_options(font=( Arial Bold , 16))
User Settings
"User settings" is a dictionary that is automatically written to your hard drive. User settings are stored in a Python dictionary which is saved to and loaded from the disk. Inspanidual settings are thus keys into a dictionary.
List of user setting functions −
Sr.No. | Function & Description |
---|---|
1 | user_settings Returns settings as a dictionary |
2 | user_settings_delete_entry Deletes a setting |
3 | user_settings_delete_filename Deletes the settings file |
4 | user_settings_file_exists Returns True if settings file specified exists |
5 | user_settings_filename Returns full path and filename of settings file |
6 | user_settings_get_entry Returns value for a setting. If no setting found, then specified default value is returned |
7 | user_settings_load Loads dictionary from the settings file. |
8 | user_settings_save Saves settings to current or newly specified file. |
9 | user_settings_set_entry Sets an entry to a particular value |
10 | user_settings_write_new_dictionary Writes a specified dictionary to settings file |
Create the User Settings object.
settings = sg.UserSettings()
Use the dictionary-style [ ] syntax to read a setting. If the item s name is - item- , then reading the value is achieved by writing
item_value = settings[ -item- ]
Following sttement is used to Write the setting.
settings[ -item- ] = new_value
To delete an item, again the dictionary style syntax is used.
del settings[ -item- ]
You can also call the delete_entry method to delete the entry.
settings.delete_entry( -item- )
The following simple program demonstrates load/saving of user settings
import PySimpleGUI as sg import json sg.set_options(font=( Arial Bold , 16)) layout = [ [sg.Text( Settings , justification= left )], [sg.Text( User name , size=(10, 1), expand_x=True), sg.Input(key= -USER- )], [sg.Text( email ID , size=(10, 1), expand_x=True), sg.Input(key= -ID- )], [sg.Text( Role , size=(10, 1), expand_x=True), sg.Input(key= -ROLE- )], [sg.Button("LOAD"), sg.Button( SAVE ), sg.Button( Exit )] ] window = sg.Window( User Settings Demo , layout, size=(715, 200)) # Event Loop while True: event, values = window.read() if event in (sg.WIN_CLOSED, Exit ): break if event == LOAD : f = open("settings.txt", r ) settings = json.load(f) window[ -USER- ].update(value=settings[ -USER- ]) window[ -ID- ].update(value=settings[ -ID- ]) window[ -ROLE- ].update(value=settings[ -ROLE- ]) if event == SAVE : settings = { -USER- : values[ -USER- ], -ID- : values[ -ID- ], -ROLE- : values[ -ROLE- ]} f = open("settings.txt", w ) json.dump(settings, f) f.close() window.close()
Enter the data in the input boxes and cpck the "Save" button.
A JSON file will be saved. To load the previously saved settings, cpck the "Load" button.
Advertisements