Transforms the tkinter, Qt, WxPython, and Remi (browser-based) GUI frameworks into a simpler interface. The window definition is simplified by using Python core data types understood by beginners (lists and dictionaries). Further simplification happens by changing event handling from a callback-based model to a message passing one.
Your code is not required to have an object oriented architecture which makes the package usable by a larger audience. While the architecture is simple to understand, it does not necessarily limit you to only simple problems.
Some programs are not well-suited for PySimpleGUI however. By definition, PySimpleGUI implements a subset of the underlying GUI frameworks' capabilities. It's difficult to define exactly which programs are well suited for PySimpleGUI and which are not. It depends on the details of your program. Duplicating Excel in every detail is an example of something not well suited for PySimpleGUI.
Japanese version of this readme.
I could use a coffee! It fuels consultants, editors, domain registration and so many other things required for PySimpleGUI to be a thriving project.
tkinter
tkinter 2.7
Qt
WxPython
Web (Remi)
PySimpleGUI is a Python package that enables Python programmers of all levels to create GUIs. You specify your GUI window using a "layout" which contains widgets (they're called "Elements" in PySimpleGUI). Your layout is used to create a window using one of the 4 supported frameworks to display and interact with your window. Supported frameworks include tkinter, Qt, WxPython, or Remi. The term "wrapper" is sometimes used for these kinds of packages.
Your PySimpleGUI code is simpler and shorter than writing directly using the underlying framework because PySimpleGUI implements much of the "boilerplate code" for you. Additionally, interfaces are simplified to require as little code as possible to get the desired result. Depending on the program and framework used, a PySimpleGUI program may require 1/2 to 1/10th amount of code to create an identical window using one of the frameworks directly.
While the goal is to encapsulate/hide the specific objects and code used by the GUI framework you are running on top of, if needed you can access the frameworks' dependent widgets and windows directly. If a setting or feature is not yet exposed or accessible using the PySimpleGUI APIs, you are not walled off from the framework. You can expand capabilities without directly modifying the PySimpleGUI package itself.
Python has brought a large number of people into the programming community. The number of programs and the range of areas it touches is mindboggling. But more often than not, these and technologies are out of reach of all but a handful of people. The majority of Python programs are "command line" based. This isn't a problem for programmer-types as we're all used to interacting with computers through a text interface. While programmers don't have a problem with command-line interfaces, most "normal people" do. This creates a digital divide, a "GUI Gap".
Adding a GUI to a program opens that program up to a wider audience. It becomes more approachable. GUIs can also make interacting with some programs easier, even for those that are comfortable with a command-line interface. And finally, some problems require a GUI.
Hi there! I'm Mike. You'll find me right here, on the PySimpleGUI GitHub, solving problems and continuously pushing PySimpleGUI forward. I've dedicated my days, nights, and weekends to the project and PySimpleGUI users. Our successes are ultimately shared. I'm successful when you're successful.
While a relative newcomer to Python, I've been writing software since the 70s. The majority of my career was spent creating products in Silicon Valley. I bring to PySimpleGUI the same professionalism and dedication as I did to the corporate products I developed. You are my customers now.
Two of the more important goals of the PySimpleGUI project:
- Having fun
- Your success
Fun as a goal on a serious project sounds odd, but it's a serious goal. I find writing these GUI programs to be a lot of fun. One reason is how little time it takes to write a complete solution. If we're not enjoying the process then someone's going to give up.
There is a significant amount of documentation, a cookbook, 100's of demo programs to get you immediately running, a detailed call reference, YouTube videos, online Trinket demos, and more... all working to create... a fun experience.
Your Success is a shared goal. PySimpleGUI was built for developers. You're my peeps. It's been an unexpected reward to see the results of the combined effort of users and PySimpleGUI. Use the documentation & other materials to help build your application. If you run into trouble, help is available by opening on Issue on the PySimpleGUI GitHub. Take a look at the section on Support below.
www.PySimpleGUI.org is easy to remember and is where the documentation is located. You'll find tabs across the top that represent several different documents. The documentation is located on "Read The Docs" so that there is a table of contents for each document and they are easy to search.
There are 100s of pages of written documentation and 100s of example programs that will help you be effective very quickly. Rather than requiring days or weeks of investment to learn a single GUI package, you may be able to complete your project in a single afternoon when using PySimpleGUI.
This type of program is called a "one-shot" window because the window is displayed one time, the values collected, and then it is closed. It doesn't remain open for a long time like you would in a Word Processor.
There are 5 sections to a PySimpleGUI program
import PySimpleGUI as sg # Part 1 - The import
# Define the window's contents
layout = [ [sg.Text("What's your name?")], # Part 2 - The Layout
[sg.Input()],
[sg.Button('Ok')] ]
# Create the window
window = sg.Window('Window Title', layout) # Part 3 - Window Defintion
# Display and interact with the Window
event, values = window.read() # Part 4 - Event loop or Window.read call
# Do something with the information gathered
print('Hello', values[0], "! Thanks for trying PySimpleGUI")
# Finish up by removing from the screen
window.close() # Part 5 - Close the Window
The code produces this window
In this example, our window will remain on the screen until the user closes the window or clicks the Quit button. The main difference between the one-shot window you saw earlier and an interactive window is the addition of an "Event Loop". The Event Loop reads events and inputs from your window. The heart of your application lives in the event loop.
import PySimpleGUI as sg
# Define the window's contents
layout = [[sg.Text("What's your name?")],
[sg.Input(key='-INPUT-')],
[sg.Text(size=(40,1), key='-OUTPUT-')],
[sg.Button('Ok'), sg.Button('Quit')]]
# Create the window
window = sg.Window('Window Title', layout)
# Display and interact with the Window using an Event Loop
while True:
event, values = window.read()
# See if user wants to quit or window was closed
if event == sg.WINDOW_CLOSED or event == 'Quit':
break
# Output a message to the window
window['-OUTPUT-'].update('Hello ' + values['-INPUT-'] + "! Thanks for trying PySimpleGUI")
# Finish up by removing from the screen
window.close()
This is the window that Example 2 produces.
And here's what it looks like after you enter a value into the Input field and click the Ok button.
Let's take a quick look at some of the differences between this example and the one-shot window.
First, you'll notice differences in the layout. Two changes in particular are important. One is the addition of the key
parameter to the Input
element and one of the Text
elements. A key
is like a name for an element. Or, in Python terms, it's like a dictionary key. The Input
element's key will be used as a dictionary key later in the code.
Another difference is the addition of this Text
element:
[sg.Text(size=(40,1), key='-OUTPUT-')],
There are 2 parameters, the key
we already covered. The size
parameter defines the size of the element in characters. In this case, we're indicating that this Text
element is 40 characters wide, by 1 character high. Notice that there is no text string specified which means it'll be blank. You can easily see this blank row in the window that's created.
We also added a button, "Quit".
The Event Loop has our familiar window.read()
call.
Following the read is this if statement:
if event == sg.WINDOW_CLOSED or event == 'Quit':
break
This code is checking to see if the user closed the window by clicking the "X" or if they clicked the "Quit" button. If either of these happens, then the code will break out of the event loop.
If the window wasn't closed nor the Quit button clicked, then execution continues. The only thing that could have happened is the user clicked the "Ok" button. The last statement in the Event Loop is this one:
window['-OUTPUT-'].update('Hello ' + values['-INPUT-'] + "! Thanks for trying PySimpleGUI")
This statement updates the Text
element that has the key -OUTPUT-
with a string. window['-OUTPUT-']
finds the element with the key -OUTPUT-
. That key belongs to our blank Text
element. Once that element is returned from the lookup, then its update
method is called. Nearly all elements have an update
method. This method is used to change the value of the element or to change some configuration of the element.
If we wanted the text to be yellow, then that can be accomplished by adding a text_color
parameter to the update
method so that it reads:
window['-OUTPUT-'].update('Hello ' + values['-INPUT-'] + "! Thanks for trying PySimpleGUI",
text_color='yellow')
After adding the text_color
parameter this is our new resulting window:
The parameters available for each element are documented in both the call reference documentation as well as the docstrings. PySimpleGUI has extensive documentation to help you understand all of the options available to you. If you lookup the update
method for the Text
element, you'll find this definition for the call:
As you can see several things can be changed for a Text
element. The call reference documentation is a valuable resource that will make programming in PySimpleGUI, uhm, simple.
Your window's layout is a "list of lists" (LOL). Windows are broken down into "rows". Each row in your window becomes a list in your layout. Concatenate together all of the lists and you've got a layout...a list of lists.
Here is the same layout as before with an extra Text
element added to each row so that you can more easily see how rows are defined:
layout = [ [sg.Text('Row 1'), sg.Text("What's your name?")],
[sg.Text('Row 2'), sg.Input()],
[sg.Text('Row 3'), sg.Button('Ok')] ]
Each row of this layout is a list of elements that will be displayed on that row in your window.
Using lists to define your GUI has some huge advantages over how GUI programming is done using other frameworks. For example, you can use Python's list comprehension to create a grid of buttons in a single line of code.
These 3 lines of code:
import PySimpleGUI as sg
layout = [[sg.Button(f'{row}, {col}') for col in range(4)] for row in range(4)]
event, values = sg.Window('List Comprehensions', layout).read(close=True)
produces this window which has a 4 x 4 grid of buttons:
Recall how "fun" is one of the goals of the project. It's fun to directly apply Python's powerful basic capabilities to GUI problems. Instead of pages of code to create a GUI, it's a few (or often 1) lines of code.
It's possible to condense a window's code down to a single line of code. The layout definition, window creation, display, and data collection can all be written in this line of code:
event, values = sg.Window('Window Title', [[sg.Text("What's your name?")],[sg.Input()],[sg.Button('Ok')]]).read(close=True)
The same window is shown and returns the same values as the example showing the sections of a PySimpleGUI program. Being able to do so much with so little enables you to quickly and easily add GUIs to your Python code. If you want to display some data and get a choice from your user, it can be done in a line of code instead of a page of code.
By using short-hand aliases, you can save even more space in your code by using fewer characters. All of the Elements have one or more shorter names that can be used. For example, the Text
element can be written simply as T
. The Input
element can be written as I
and the Button
as B
. Your single-line window code thus becomes:
event, values = sg.Window('Window Title', [[sg.T("What's your name?")],[sg.I()],[sg.B('Ok')]]).read(close=True)
PySimpleGUI is currently capable of running on 4 Python GUI Frameworks. The framework to use is specified using the import statement. Change the import and you'll change the underlying GUI framework. For some programs, no other changes are needed than the import statement to run on a different GUI framework. In the example above, changing the import from PySimpleGUI
to PySimpleGUIQt
, PySimpleGUIWx
, PySimpleGUIWeb
will change the framework.
Import Statement | Resulting Window |
---|---|
PySimpleGUI | ![]() |
PySimpleGUIQt | ![]() |
PySimpleGUIWx | ![]() |
PySimpleGUIWeb | ![]() |
Porting GUI code from one framework to another (e.g. moving your code from tkinter to Qt) usually requires a rewrite of your code. PySimpleGUI is designed to enable you to enable easy movement between the frameworks. Sometimes some changes are required of you, but the goal is to have highly portable code with minimal changes.
Some features, like a System Tray Icon, are not available on all of the ports. The System Tray Icon feature is available on the Qt and WxPython ports. A simulated version is available on tkinter. There is no support for a System Tray icon in the PySimpleGUIWeb port.
Environment | Supported |
---|---|
Python | Python 3.4+ |
Operating Systems | Windows, Linux, Mac |
Hardware | Desktop PCs, Laptops, Raspberry Pi, Android devices running PyDroid3 |
Online | repli.it, Trinket.com (both run tkinter in a browser) |
GUI Frameworks | tkinter, pyside2, WxPython, Remi |
Among the more than 200 "Demo Programs" you'll find examples of how to integrate many popular Python packages into your GUI.
Want to embed a Matplotlib drawing into your window? No problem, copy the demo code and instantly have a Matplotlib drawing of your dreams into your GUI.
These packages and more are ready for you to put into your GUI as there are demo programs or a demo repo available for each:
Package | Description |
---|---|
Matplotlib | Many types of graphs and plots |
OpenCV | Computer Vision (often used for AI) |
VLC | Video playback |
pymunk | Physics engine |
psutil | System environment statistics |
prawn | Reddit API |
json | PySimpleGUI wraps a special API to store "User Settings" |
weather | Integrates with several weather APIs to make weather apps |
mido | MIDI playback |
beautiful soup | Web Scraping (GitHub issue watcher example) |
Two common ways of installing PySimpleGUI:
- pip to install from PyPI
- Download the file PySimpleGUI.py and place in your application's folder
The current suggested way of invoking the pip
command is by running it as a module using Python. Previously the command pip
or pip3
was directly onto a command-line / shell. The suggested way
Initial install for Windows:
python -m pip install PySimpleGUI
Initial install for Linux and MacOS:
python3 -m pip install PySimpleGUI
To upgrade using pip
you simply 2 parameters to the line --upgrade --no-cache-dir
.
Upgrade installation on Windows:
python -m pip install --upgrade --no-cache-dir PySimpleGUI
Upgrade for Linux and MacOS:
python3 -m pip install --upgrade --no-cache-dir PySimpleGUI
PySimpleGUI was created as a single .py file so that it would be very easy for you to install it, even on systems that are not connected to the internet like a Raspberry Pi. It's as simple as placing the PySimpleGUI.py file into the same folder as your application that imports it. Python will use your local copy when performing the import.
When installing using just the .py file, you can get it from either PyPI or if you want to run the most recent unreleased version then you'll download it from GitHub.
To install from PyPI, download either the wheel or the .gz file and unzip the file. If you rename the .whl file to .zip you can open it just like any normal zip file. You will find the PySimpleGUI.py file in one of the folders. Copy this file to your application's folder and you're done.
The PyPI link for the tkinter version of PySimpleGUI is: https://pypi.org/project/PySimpleGUI/#files
The GitHub repo's latest version can be found here: https://raw.githubusercontent.com/PySimpleGUI/PySimpleGUI/master/PySimpleGUI.py
Now some of you are thinking, "yea, but, wait, having a single huge source file is a terrible idea". And, yea, sometimes it can be a terrible idea. In this case, the benefits greatly outweighed the downside. Lots of concepts in computer science are tradeoffs or subjective. As much as some would like it to be, not everything is black and white. Many times the answer to a question is "it depends".
Work on a more formal gallery of user-submitted GUIs as well as those found on GitHub is underway but as of this writing is not complete. There are currently 2 places you can go to see some screenshots in a centralized way. Hopefully, a Wiki or other mechanism can be released soon to do justice to the awesome creations people are making.
The first is a user submitted screenshots issue located on the GitHub. It's an informal way for people to show off what they've made. It's not ideal, but it was a start.
The second is a massive gallery of over 3,000 images scraped from 1,000 projects on GitHub that are reportedly using PySimpleGUI. It's not been hand-filtered and there are plenty of old screenshots that were used in the early documentation. But, you may find something in there that sparks your imagination.
The following sections showcase a fraction of the uses for PySimpleGUI. There are over 1,000 projects on GitHub alone that use PySimpleGUI. It's truly amazing the possibilities that have opened up for so many people. Many users have spoken about previously attempting to create a GUI in Python and failing, but finally achieving their dreams when they tried PySimpleGUI.
Of course one of the best uses of PySimpleGUI is getting you into making GUIs for your Python projects. You can start as small as requesting a filename. For this, you only need to make a single call to one of the "high-level functions" called popup
. There are all kinds of popups, some collect information.
popup
but itself makes a window to display information. You can pass multiple parameters just like a print. If you want to get information, then you will call functions that start with popup_get_
such as popup_get_filename
.
Adding a single line to get a filename instead of specifying a filename on the command line can transform your program into one that "normal people" will feel comfortable using.
import PySimpleGUI as sg
filename = sg.popup_get_file('Enter the file you wish to process')
sg.popup('You entered', filename)
This code will display 2 popup windows. One to get the filename, which can be browsed to or pasted into the input box.
The other window will output what is collected.
The default settings for GUI frameworks don't tend to produce the nicest looking windows. However, with some attention to detail, you can do several things to make windows look attractive. PySimpleGUI makes it easier to manipulate colors and features like removing the title bar. The result is windows that don't look like your typical tkinter windows.
Here is an example of how you can create windows that don't look like your typical tkinter in windows. In this example, the windows have their titlebars removed. The result is windows that look much like those found when using Rainmeter, a desktop widget program.
You can easily set the transparency of a window as well. Here are more examples of desktop widgets in the same Rainmeter style. Some are dimmed appearing because they are semi-transparent.
Both of these effects, removing the titlebar and making a window semi-transparent, are achieved by setting 2 parameters when creating the window. This is an example of how PySimpleGUI enables easy access to features. And because PySimpleGUI code is portable across the GUI frameworks, these same parameters work for the other ports such as Qt.
Changing the Window creation call in Example 1 to this line of code produces a similar semi-transparent window:
window = sg.Window('My window', layout, no_titlebar=True, alpha_channel=0.5)