Web Analytics Made Easy - Statcounter
Skip to content

Getting Started

All of your PySimpleGUI programs will utilize one of these 2 design patterns depending on the type of window you're implementing. The two types of windows are:

  1. One-shot
  2. Persistent

The One-shot window is one that pops up, collects some data, and then disappears. It is more or less a 'form' meant to quickly grab some information and then be closed.

The Persistent window is one that sticks around. With these programs, you loop, reading and processing "events" such as button clicks. It's more like a typical Windows/Mac/Linux program.

If you are writing a "typical Windows program" where the window stays open while you collect multiple button clicks and input values, then you'll want Recipe Pattern 2B.

Pattern 1A - "One-shot Window" - (The Simplest Pattern)

SNAG-0682

SNAG-0683

This will be the most common pattern you'll follow if you are not using an "event loop" (not reading the window multiple times). The window is read and then closed.

When you "read" a window, you are returned a tuple consisting of an event and a dictionary of values.

The event is what caused the read to return. It could be a button press, some text clicked, a list item chosen, etc, or WIN_CLOSED if the user closes the window using the X.

The values is a dictionary of values of all the input-style elements. Dictionaries use keys to define entries. If your elements do not specificy a key, one is provided for you. These auto-numbered keys are ints starting at zero.

This design pattern does not specify a key for the InputText element, so its key will be auto-numbered and is zero in this case. Thus the design pattern can get the value of whatever was input by referencing values[0]

import PySimpleGUI as sg      

layout = [[sg.Text('My one-shot window.')],      
                 [sg.InputText()],      
                 [sg.Submit(), sg.Cancel()]]      

window = sg.Window('Window Title', layout)    

event, values = window.read()    
window.close()

text_input = values[0]    
sg.popup('You entered', text_input)

If you want to use a key instead of an auto-generated key:

import PySimpleGUI as sg      

layout = [[sg.Text('My one-shot window.')],      
                 [sg.InputText(key='-IN-')],      
                 [sg.Submit(), sg.Cancel()]]      

window = sg.Window('Window Title', layout)    

event, values = window.read()    
window.close()

text_input = values['-IN-']    
sg.popup('You entered', text_input)

Pattern 1B - "One-shot Window" - (Self-closing, single line)

For a much more compact window, it's possible to create, display, read, and close a window in a single line of code.

import PySimpleGUI as sg

event, values = sg.Window('Login Window',
                  [[sg.T('Enter your Login ID'), sg.In(key='-ID-')],
                  [sg.B('OK'), sg.B('Cancel') ]]).read(close=True)

login_id = values['-ID-']

The important part of this bit of code is close=True. This is the parameter that instructs PySimpleGUI to close the window just before the read returns.

This is a single line of code, broken up to make reading the window layout easier. It will display a window, let the user enter a value, click a button and then the window will close and execution will be returned to you with the variables event and values being returned.

Notice use of Element name "Shortcuts" (uses B rather than Button, T instead of Text, In rather than InputText, etc.). These shortcuts are fantastic to use when you have complex layouts. Being able to "see" your entire window's definition on a single screen of code has huge benefits. It's another tool to help you achieve simple code.

Pattern 2A - Persistent window (multiple reads using an event loop)

image

The more advanced/typical GUI programs operate with the window remaining visible on the screen. Input values are collected, but rather than closing the window, it is kept visible acting as a way to both input and output information. In other words, a typical Window, Mac or Linux window.

Let this sink in for a moment.... in 10 lines of Python code, you can display and interact with your own custom GUI window. You are writing "real GUI code" (as one user put it) that will look and act like other windows you're used to using daily.

This code will present a window and will print values until the user clicks the exit button or closes window using an X.

import PySimpleGUI as sg      

sg.theme('DarkAmber')    # Keep things interesting for your users

layout = [[sg.Text('Persistent window')],      
          [sg.Input(key='-IN-')],      
          [sg.Button('Read'), sg.Exit()]]      

window = sg.Window('Window that stays open', layout)      

while True:                             # The Event Loop
    event, values = window.read() 
    print(event, values)       
    if event == sg.WIN_CLOSED or event == 'Exit':
        break      

window.close()

Here is some sample output from this code:

Read {'-IN-': 'typed into input field'}
Read {'-IN-': 'More typing'}
Exit {'-IN-': 'clicking the exit button this time'}

The first thing printed is the "event" which in this program is the buttons. The next thing printed is the values variable that holds the dictionary of return values from the read. This dictionary has only 1 entry. The "key" for the entry is '-IN-' and matches the key passed into the Input element creation on this line of code:

          [sg.Input(key='-IN-')],      

If the window was close using the X, then the output of the code will be:

None {'-IN-': None}

The event returned from the read is set to None (the variable WIN_CLOSED) and so are the input fields in the window. This None event is super-important to check for. It must be detected in your windows or else you'll be trying to work with a window that's been destroyed and your code will crash. This is why you will find this check after every window.read() call you'll find in sample PySimpleGUI code.

In some cirsumstances when a window is closed with an X, both of the return values from window.read() will be None. This is why it's important to check for event is None before attempting to access anything in the values variable.

Pattern 2B - Persistent window (multiple reads using an event loop + updates data in window)

image

This is a slightly more complex, but more realistic version that reads input from the user and displays that input as text in the window. Your program is likely to be doing both of those activities so this pattern will likely be your starting point.

Do not worry yet what all of these statements mean. Just copy the template so you can start to experiment and discover how PySimpleGUI programs work.

import PySimpleGUI as sg

sg.theme('BluePurple')

layout = [[sg.Text('Your typed chars appear here:'), sg.Text(size=(15,1), key='-OUTPUT-')],
          [sg.Input(key='-IN-')],
          [sg.Button('Show'), sg.Button('Exit')]]

window = sg.Window('Pattern 2B', layout)

while True:  # Event Loop
    event, values = window.read()
    print(event, values)
    if event == sg.WIN_CLOSED or event == 'Exit':
        break
    if event == 'Show':
        # Update the "output" text element to be the value of "input" element
        window['-OUTPUT-'].update(values['-IN-'])

window.close()

To modify an Element in a window, you call its update method. This is done in 2 steps. First you lookup the element, then you call that element's update method.

The way we're achieving output here is by changing a Text Element with this statement:

window['-OUTPUT-'].update(values['-IN-'])

window['-OUTPUT-'] returns the element that has the key '-OUTPUT-'. Then the update method for that element is called so that the value of the Text Element is modified. Be sure you have supplied a size that is large enough to display your output. If the size is too small, the output will be truncated.

There are two important concepts when updating elements!

  1. If you need to interact with elements prior to calling window.read() you will need to "finalize" your window first using the finalize parameter when you create your Window. "Interacting" means calling that element's methods such as update, expand, draw_line, etc.
  2. Your change will not be visible in the window until you either:
    A. Call window.read() again
    B. Call window.refresh()

Inside your event loop

For persistent windows, after creating the window, you have an event loop that runs until you exit the window. Inside this loop you will read values that are returned from reading the window and you'll operate on elements in your window. To operate on elements, you look them up and call their method functions such as update.

Old Style Element Lookups - FindElement

The original / old-style way of looking up elements using their key was to call window.FindElement or the shortened window.Element, passing in the element's key.

These 3 lines of code do the same thing. The first line is the currently accepted way of performing this lookup operation and what you'll find in all of the current demos.

window['-OUTPUT-']
window.FindElement('-OUTPUT-')
window.find_element('-OUTPUT-')
window.Element('-OUTPUT-')

Element Operations

Once you lookup an element, the most often performed operation is update. There are other element methods you can call such as set_tooltip(). You'll find the list of operations available for each element in the call summary at the end of the main documentation.

To call any of these other methods, you do the element lookup, then add on the call such as this call to set_tooltip.

window[my_key].set_tooltip('New Tooltip')

NOTE!

Operations on elements will not appear in your window immediately. If you wish for them to appear immediately, prior to your next window.read() call, you must call window.refresh(). A call to read or refresh causes your changes to be displayed.


Exiting a Window

For persistent windows, you will find this if statement immediately following every window.read call you'll find in this document and likely all of the demo programs:

if event in (sg.WIN_CLOSED, 'Quit'):
    break

or this version which is easier for beginners to understand. They perfect exactly the same check.

if event == sg.WIN_CLOSED or event == 'Quit':
    break

This is your user's "way out". Always give a way out to your user or else they will be using task manager or something else, all the while cursing you.

Beginners to Python may not understand this statement and it's important to understand it so that you don't simply ignore it because you don't understand the syntax.

The if statement is identical to this if statement:

if event == sg.WIN_CLOSED or event == 'Quit':
    break

The event in (sg.WIN_CLOSED, 'Quit') simply means is the value of the event variable in the list of choices shown, in this case WIN_CLOSED or Quit. If so, then break out of the Event Loop and likely exit the program when that happens for simple programs.

You may find 'Exit' instead of 'Quit' in some programs. Or may find only WIN_CLOSED is checked. Exit & Quit in this case refer to a Quit/Exit button being clicked. If your program doesn't have one, then you don't need to include it.

Close Your Windows

When you're done with your window, close it.

window.close()

The reason is that for some ports, like PySimpleGUIWeb, you cannot exit the program unless the window is closed. It's nice to clean up after yourself too.


Coding Conventions

By following some simple coding conventions you'll be able to copy / paste demo program code into your code with minimal or no modifications. Your code will be understandable by other PySimpleGUI programmers as well.

The primary suggested conventions are:

  • import PySimpleGUI as sg
  • Name your Window window
  • Name the return values from reading your window event and values
  • Name your layout layout
  • Use window[key] to lookup elements
  • For keys that are strings, follow this pattern '-KEY-'

Of course you don't have to follow any of these. They're suggestions, but if you do follow them, your code is a lot easier to understand by someone else.

Coding Tips

A few tips that have worked well for others. In the same spirit as the coding conventions, these a few observations that may speed up your development or make it easier for others to understand your code. They're guidelines / tips / suggestions / ideas... meant to help you.

  • Stay simple at every opportunity
  • Read or search the documentation (http://www.PySimpleGUI.org)
  • Use the coding conventions outlined above
  • Write compact layouts
  • Use "user defined elements" when you find yourself repeating parameters many times (functions that return elements)
  • Use PySimpleGUI constructs rather than other GUI frameworks' constructs
  • Use reasonable timeout values (as large of non-zero values as possible... be a good CPU citizen)
  • Do not try to make any PySimpleGUI call from a thread
  • Close your windows before exiting
  • Make linear event loops
  • Use the values dictionary rather than Element.get methods
  • Look through Demo Programs for more tips / techniques (http://Demos.PySimpleGUI.org)

Most of these are self-explanatory or will be understood as you learn more about PySimpleGUI. You won't now what a timeout value is at this point, but if/when you do use reads with timeouts, then you'll understand the tip.

A little more detail on a few of them that aren't obvious.

Write compact layouts

Try to keep your layout definitions to a single screen of code. Don't put every parameter on a new line. Don't add tons of whitespace.

If you've got a lot of elements, use the shortcut names (e.g. using sg.B rather than sg.Button saves 5 characters per button in your layout).

The idea here to be able to see your entire window in your code without having to scroll.

Use PySimpleGUI constructs

PySimpleGUI programs were not designed using the same OOP design as the other Python GUI frameworks. Trying to force fit them into an OOP design doesn't buy anything other then lots of self. scattered in your code, more complexity, and possibly more confusion

Of course your overall design can be OOP.

The point is that there is no concept of an "App" or a never-ending event loop or callback functions. PySimpleGUI is different than tkinter and Qt. Trying to code in that style is likely to not result in success. If you're writing a subclass for Window as a starting point, it's highly likely you're doing something wrong.


Environment Setup & Best Practices

If you're going to be doing a moderate to high amount of PySimpleGUI programming or simply want to get the most out of your PySimpleGUI experience, there are a few steps you can take that will make a big difference.

Using an IDE(Integrated Development Environment) to edit and run your PySimpleGUI programs is highly recommended. PySimpleGUI was written so that it integrates with PyCharm particularly well. For all classes and functions PyCharm shows you the documentation in the window as you're writing your code. It's the exact same documentation that you'll find in the Call Reference portion of the PySimpleGUI documentation. Each parameter is described in detail and PyCharm does type-checking and highlights errors in your code before you even try to run it.

You can learn the basics of using PyCharm in a couple of hours. The most you'll need to do is:
* Set up the interpreter (you can use the system interpreter or a virtual one) * Create a project * Add your Python files to your project * Learn how to run your program

With an IDE you will save a LOT of time, every time you work on your program. Big time savers include:
* Code completion feature (Control+Space) * Viewing documentation of a class or function (Control+Q) * Quickly navigating to a variable, class, function definition (control+click) * Jump to error when there's a crash (click on the error message)

Here is a sample program shown in PyCharm. The Text element's documentation is shown when the cursor is on a Text element in your program. You're able to write & run your code as well as look at the documentation all within the PyCharm window.

pycharm

Editor and Explorer

PySimpleGUI tightly integrates with your editor and file explorer programs. You can set these in the PySimpleGUI Global Settings accessible through the Home Window (sg.main(), psgmain, psghome are all ways of getting to the Home Window) or running command line program psgsettings.

The Editor Settings tab is where you set up your editor program. Note that you should use quotes around the invoke command if there are spaces anywhere. The Editor Format String specifies the command line parameters used by your editor program to launch it in a manner that will start editing at a particular line number within a particular file.

GlobalSettings

The Explorer Program tab is where you specify the name of the program that you use to browse for files on your OS. For Windows, the value is simply explorer.

Error Popups

The editor and explorer are used by the Demo Browser as well as the PySimpleGUI Error with Traceback Popup window. This popup is used internally within PySimpleGUI and you can also use the same popup. To use this popup, call popup_error_with_traceback like in this example:

    try:
        a = 1/0
    except Exception as e:
        sg.popup_error_with_traceback('Error in the event loop', e, emoji=sg.EMOJI_BASE64_SCREAM)

ErrorPopup

If you have your editor set up then clicking "Take Me To Error" will open your editor to the line number in your code with the error.

Application Right Click Menus

If you do a lot of PySimpleGUI programming, then you may find using the pre-defined right-click menus and code that processes them to be a real time-saver.

Try adding to your Window creation the parameter right_click_menu=sg.MENU_RIGHT_CLICK_EDITME_VER_EXIT. Then in your event loop, add this code:

if event == 'Edit Me':
    sg.execute_editor(__file__)
elif event == 'Version':
    sg.popup_scrolled(__file__, sg.get_versions(), location=window.current_location(), keep_on_top=True, non_blocking=True)

Right clicking your application will show a menu rightclick

This enables you to right click the application when it's running and choosing "Edit Me" or "Version". It can save a lot of time, especially if you're running lots of PySimpleGUI programs located in different folders on your system. Rather than opening your editor, and navigating to your program's location and opening the file to edit it, simply right click on the running application and choose "Edit Me". The sg.execute_editor call will open your editor for you to the correct file and location.

For "Gadgets"/"Desktop Widget" programs that have no titlebar, using a right click menu with an Exit option is really important as there is no taskbar icon nor titlebar that can be used to close the application. Always give a way out for your users!

Working with Images and Icons

Image files can be easily lost when copying projects or converting them into packages. Icons on your windows can be tricky because a PySimpleGUI program can run on multiple operating systems as well as being turned into an executable by tools like PyInstaller.

The easiest solution to these problems is to convert your icons and images from PNG files into Base64 and including them directly in your PySimpleGUI application source file. The psgresizer application makes converting your images very easy.

Once converted to Base64, paste the into your source and then use with both Window creation and popup calls. You can also set the application-wide icon so that all windows created by the application use the same icon. Using files for icons has the downside of each OS having a unique format. Windows uses ICO files, Linux uses PNG files and Mac uses... uhm.... just use Base64 encoded icons and you'll save yourself a lot of headaches.