Save time and effort. This is probably the fastest way to write GUI in Python

GUI instance

The address of PySimpleGUI on GitHub is:

<span style="color:#444444"><span style="background-color:#f6f6f6"><span style="color:#333333"><strong>https</strong></span>:<span style="color:#888888">//github.com/PySimpleGUI/PySimpleGUI</span>
</span></span>

You can visit it. Its home page is as follows:

There's a lot of content, isn't it?

There is an important content in this folder. Under the DemoPrograms folder, this folder is some demo instances written by the author. The author really understands the psychology of us slackers. Even with such a simple and easy-to-use GUI framework, when we want to write examples, we may search for examples on the network and adopt them. The framework author may have expected this, so he wrote many different examples for you to really use. CV Dafa

There are about 300 instances in this folder, which can basically include all kinds of components and layouts we can encounter when using python to write GUI.

Let's have a look

With this artifact, we only need to copy the items on the GitHub locally, and then run these instances to roughly know what each instance u contains. Later, when we want to write the GUI ourselves, we just need to find the corresponding instance and copy the code. Isn't it simple?

Let me run a few demo s to show you what the examples look like.

Chat interface

Let's copy the source code first:

<span style="color:#444444"><span style="background-color:#f6f6f6"><code>#!/usr/bin/env python
<strong>import</strong> PySimpleGUI <strong><span style="color:#333333"><strong>as</strong></span></strong> sg

<span style="color:#880000">''</span><span style="color:#880000">'</span>
<span style="color:#880000">A chatbot with history</span>
<span style="color:#880000">Scroll up and down through prior commands using the arrow keys</span>
<span style="color:#880000">Special keyboard keys:</span>
<span style="color:#880000">    Up arrow - scroll up in commands</span>
<span style="color:#880000">    Down arrow - scroll down in commands</span>
<span style="color:#880000">    Escape - clear current command</span>
<span style="color:#880000">    Control C - exit form</span>
<span style="color:#880000">'</span><span style="color:#880000">''</span>


<strong>def</strong> <strong>ChatBotWithHistory</strong>():
    # -------  Make <span style="color:#333333"><strong>a</strong></span> <span style="color:#333333"><strong>new</strong></span> Window  ------- #
    # give our form <span style="color:#333333"><strong>a</strong></span> spiffy <span style="color:#333333"><strong>set</strong></span> of colors
    sg.theme(<span style="color:#880000">'GreenTan'</span>)

    layout = [[sg.Text(<span style="color:#880000">'Your output will go here'</span>, size=(<span style="color:#880000">40</span>, <span style="color:#880000">1</span>))],
              [sg.Output(size=(<span style="color:#880000">127</span>, <span style="color:#880000">30</span>), font=(<span style="color:#880000">'Helvetica 10'</span>))],
              [sg.Text(<span style="color:#880000">'Command History'</span>),
               sg.Text(<span style="color:#880000">''</span>, size=(<span style="color:#880000">20</span>, <span style="color:#880000">3</span>), key=<span style="color:#880000">'history'</span>)],
              [sg.ML(size=(<span style="color:#880000">85</span>, <span style="color:#880000">5</span>), enter_submits=<strong>True</strong>, key=<span style="color:#880000">'query'</span>, do_not_clear=<strong>False</strong>),
               sg.Button(<span style="color:#880000">'SEND'</span>, button_color=(sg.YELLOWS[<span style="color:#880000">0</span>], sg.BLUES[<span style="color:#880000">0</span>]), bind_return_key=<strong>True</strong>),
               sg.Button(<span style="color:#880000">'EXIT'</span>, button_color=(sg.YELLOWS[<span style="color:#880000">0</span>], sg.GREENS[<span style="color:#880000">0</span>]))]]

    window = sg.Window(<span style="color:#880000">'Chat window with history'</span>, layout,
                       default_element_size=(<span style="color:#880000">30</span>, <span style="color:#880000">2</span>),
                       font=(<span style="color:#880000">'Helvetica'</span>, <span style="color:#880000">' 13'</span>),
                       default_button_element_size=(<span style="color:#880000">8</span>, <span style="color:#880000">2</span>),
                       return_keyboard_events=<strong>True</strong>)

    # ---===--- Loop taking in user <span style="color:#397300">input</span> <span style="color:#397300">and</span> using it  --- #
    command_history = []
    history_offset = <span style="color:#880000">0</span>

    <strong><span style="color:#333333"><strong>while</strong></span></strong> <strong>True</strong>:
        event, value = window.<span style="color:#333333"><strong>read</strong></span>()

        <strong><span style="color:#333333"><strong>if</strong></span></strong> event == <span style="color:#880000">'SEND'</span>:
            query = value[<span style="color:#880000">'query'</span>].rstrip()
            # EXECUTE YOUR COMMAND HERE
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">'The command you entered was {}'</span>.format(query))
            command_history.<span style="color:#333333"><strong>append</strong></span>(query)
            history_offset = <span style="color:#397300">len</span>(command_history)-<span style="color:#880000">1</span>
            # manually clear <span style="color:#397300">input</span> because keyboard events blocks clear
            window[<span style="color:#880000">'query'</span>].<span style="color:#333333"><strong>update</strong></span>(<span style="color:#880000">''</span>)
            window[<span style="color:#880000">'history'</span>].<span style="color:#333333"><strong>update</strong></span>(<span style="color:#880000">'\n'</span>.<span style="color:#333333"><strong>join</strong></span>(command_history[-<span style="color:#880000">3</span>:]))
        
        <strong>elif</strong> event <strong>in</strong> (sg.WIN_CLOSED, <span style="color:#880000">'EXIT'</span>):            # <span style="color:#333333"><strong>quit</strong></span> <span style="color:#333333"><strong>if</strong></span> <span style="color:#333333"><strong>exit</strong></span> event <span style="color:#397300">or</span> <span style="color:#333333"><strong>X</strong></span>
            <strong><span style="color:#333333"><strong>break</strong></span></strong>
        
        <strong>elif</strong> <span style="color:#880000">'Up'</span> <strong>in</strong> event <strong><span style="color:#397300">and</span></strong> <span style="color:#397300">len</span>(command_history):
            <span style="color:#333333"><strong>command</strong></span> = command_history[history_offset]
            # decrement <span style="color:#333333"><strong>is</strong></span> not zero
            history_offset -= <span style="color:#880000">1</span> * (history_offset > <span style="color:#880000">0</span>)
            window[<span style="color:#880000">'query'</span>].<span style="color:#333333"><strong>update</strong></span>(<span style="color:#333333"><strong>command</strong></span>)
        
        <strong>elif</strong> <span style="color:#880000">'Down'</span> <strong>in</strong> event <strong><span style="color:#397300">and</span></strong> <span style="color:#397300">len</span>(command_history):
            # increment <span style="color:#333333"><strong>up</strong></span> <span style="color:#333333"><strong>to</strong></span> end of <span style="color:#333333"><strong>list</strong></span>
            history_offset += <span style="color:#880000">1</span> * (history_offset < <span style="color:#397300">len</span>(command_history)-<span style="color:#880000">1</span>)
            <span style="color:#333333"><strong>command</strong></span> = command_history[history_offset]
            window[<span style="color:#880000">'query'</span>].<span style="color:#333333"><strong>update</strong></span>(<span style="color:#333333"><strong>command</strong></span>)
        
        <strong>elif</strong> <span style="color:#880000">'Escape'</span> <strong>in</strong> even<span style="color:#bc6060">t:</span>
            window[<span style="color:#880000">'query'</span>].<span style="color:#333333"><strong>update</strong></span>(<span style="color:#880000">''</span>)


ChatBotWithHistory()

</code></span></span>

Run it to see the effect:

This is a chat software with history. If you need to make a similar software, you can copy the code directly and change it a little.

Complete set of components

Let's take another example:

<span style="color:#444444"><span style="background-color:#f6f6f6"><code>#!/usr/bin/env <span style="color:#333333"><strong>python</strong></span>
<span style="color:#880000">""</span><span style="color:#880000">"</span>
<span style="color:#880000">    Example of (almost) all Elements, that you can use in PySimpleGUI.</span>
<span style="color:#880000">    Shows you the basics including:</span>
<span style="color:#880000">        Naming convention for keys</span>
<span style="color:#880000">        Menubar format</span>
<span style="color:#880000">        Right click menu format</span>
<span style="color:#880000">        Table format</span>
<span style="color:#880000">        Running an async event loop</span>
<span style="color:#880000">        Theming your application (requires a window restart)</span>
<span style="color:#880000">        Displays the values dictionary entry for each element</span>
<span style="color:#880000">        And more!</span>

<span style="color:#880000">    Copyright 2021 PySimpleGUI</span>
<span style="color:#880000">"</span><span style="color:#880000">""</span>

<strong>import</strong> PySimpleGUI <strong><span style="color:#333333"><strong>as</strong></span></strong> sg

<strong>def</strong> <strong>make_window</strong>(theme):
    sg.theme(theme)
    menu_def = [[<span style="color:#880000">'&Application'</span>, [<span style="color:#880000">'E&xit'</span>]],
                [<span style="color:#880000">'&Help'</span>, [<span style="color:#880000">'&About'</span>]] ]
    right_click_menu_def = [[], [<span style="color:#880000">'Nothing'</span>,<span style="color:#880000">'More Nothing'</span>,<span style="color:#880000">'Exit'</span>]]

    # Table Data
    data = [[<span style="color:#880000">"John"</span>, <span style="color:#880000">10</span>], [<span style="color:#880000">"Jen"</span>, <span style="color:#880000">5</span>]]
    headings = [<span style="color:#880000">"Name"</span>, <span style="color:#880000">"Score"</span>]

    input_layout =  [[sg.Menu(menu_def, key=<span style="color:#880000">'-MENU-'</span>)],
                [sg.Text(<span style="color:#880000">'Anything that requires user-input is in this tab!'</span>)], 
                [sg.Input(key=<span style="color:#880000">'-INPUT-'</span>)],
                [sg.Slider(orientation=<span style="color:#880000">'h'</span>, key=<span style="color:#880000">'-SKIDER-'</span>),
                 sg.Image(data=sg.DEFAULT_BASE64_LOADING_GIF, enable_events=<strong>True</strong>, key=<span style="color:#880000">'-GIF-IMAGE-'</span>),],
                [sg.Checkbox(<span style="color:#880000">'Checkbox'</span>, default=<strong>True</strong>, <span style="color:#333333"><strong>k</strong></span>=<span style="color:#880000">'-CB-'</span>)],
                [sg.Radio(<span style="color:#880000">'Radio1'</span>, <span style="color:#880000">"RadioDemo"</span>, default=<strong>True</strong>, size=(<span style="color:#880000">10</span>,<span style="color:#880000">1</span>), <span style="color:#333333"><strong>k</strong></span>=<span style="color:#880000">'-R1-'</span>), sg.Radio(<span style="color:#880000">'Radio2'</span>, <span style="color:#880000">"RadioDemo"</span>, default=<strong>True</strong>, size=(<span style="color:#880000">10</span>,<span style="color:#880000">1</span>), <span style="color:#333333"><strong>k</strong></span>=<span style="color:#880000">'-R2-'</span>)],
                [sg.Combo(<span style="color:#397300">values</span>=(<span style="color:#880000">'Combo 1'</span>, <span style="color:#880000">'Combo 2'</span>, <span style="color:#880000">'Combo 3'</span>), default_value=<span style="color:#880000">'Combo 1'</span>, readonly=<strong>True</strong>, <span style="color:#333333"><strong>k</strong></span>=<span style="color:#880000">'-COMBO-'</span>),
                 sg.OptionMenu(<span style="color:#397300">values</span>=(<span style="color:#880000">'Option 1'</span>, <span style="color:#880000">'Option 2'</span>, <span style="color:#880000">'Option 3'</span>),  <span style="color:#333333"><strong>k</strong></span>=<span style="color:#880000">'-OPTION MENU-'</span>),],
                [sg.Spin([i <strong><span style="color:#333333"><strong>for</strong></span></strong> i <strong>in</strong> <span style="color:#397300">range</span>(<span style="color:#880000">1</span>,<span style="color:#880000">11</span>)], initial_value=<span style="color:#880000">10</span>, <span style="color:#333333"><strong>k</strong></span>=<span style="color:#880000">'-SPIN-'</span>), sg.Text(<span style="color:#880000">'Spin'</span>)],
                [sg.Multiline(<span style="color:#880000">'Demo of a Multi-Line Text Element!\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\nYou get the point.'</span>, size=(<span style="color:#880000">45</span>,<span style="color:#880000">5</span>), <span style="color:#333333"><strong>k</strong></span>=<span style="color:#880000">'-MLINE-'</span>)],
                [sg.Button(<span style="color:#880000">'Button'</span>), sg.Button(<span style="color:#880000">'Popup'</span>), sg.Button(image_data=sg.DEFAULT_BASE64_ICON, key=<span style="color:#880000">'-LOGO-'</span>)]]

    asthetic_layout = [[sg.T(<span style="color:#880000">'Anything that you would use for asthetics is in this tab!'</span>)],
               [sg.Image(data=sg.DEFAULT_BASE64_ICON,  <span style="color:#333333"><strong>k</strong></span>=<span style="color:#880000">'-IMAGE-'</span>)],
               [sg.ProgressBar(<span style="color:#880000">1000</span>, orientation=<span style="color:#880000">'h'</span>, size=(<span style="color:#880000">20</span>, <span style="color:#880000">20</span>), key=<span style="color:#880000">'-PROGRESS BAR-'</span>), sg.Button(<span style="color:#880000">'Test Progress bar'</span>)]]

    logging_layout = [[sg.Text(<span style="color:#880000">"Anything printed will display here!"</span>)], [sg.Output(size=(<span style="color:#880000">60</span>,<span style="color:#880000">15</span>), font=<span style="color:#880000">'Courier 8'</span>)]]
    
    graphing_layout = [[sg.Text(<span style="color:#880000">"Anything you would use to graph will display here!"</span>)],
                      [sg.Graph((<span style="color:#880000">200</span>,<span style="color:#880000">200</span>), (<span style="color:#880000">0</span>,<span style="color:#880000">0</span>),(<span style="color:#880000">200</span>,<span style="color:#880000">200</span>),background_color=<span style="color:#880000">"black"</span>, key=<span style="color:#880000">'-GRAPH-'</span>, enable_events=<strong>True</strong>)],
                      [sg.T(<span style="color:#880000">'Click anywhere on graph to draw a circle'</span>)],
                      [sg.Table(<span style="color:#397300">values</span>=data, headings=headings, max_col_width=<span style="color:#880000">25</span>,
                                background_color=<span style="color:#880000">'black'</span>,
                                auto_size_columns=<strong>True</strong>,
                                display_row_numbers=<strong>True</strong>,
                                justification=<span style="color:#880000">'right'</span>,
                                num_rows=<span style="color:#880000">2</span>,
                                alternating_row_color=<span style="color:#880000">'black'</span>,
                                key=<span style="color:#880000">'-TABLE-'</span>,
                                row_height=<span style="color:#880000">25</span>)]]

    specalty_layout = [[sg.Text(<span style="color:#880000">"Any \"special\" elements will display here!"</span>)],
                      [sg.Button(<span style="color:#880000">"Open Folder"</span>)],
                      [sg.Button(<span style="color:#880000">"Open File"</span>)]]
    
    theme_layout = [[sg.Text(<span style="color:#880000">"See how elements look under different themes by choosing a different theme here!"</span>)],
                    [sg.Listbox(<span style="color:#397300">values</span> = sg.theme_list(), 
                      size =(<span style="color:#880000">20</span>, <span style="color:#880000">12</span>), 
                      key =<span style="color:#880000">'-THEME LISTBOX-'</span>,
                      enable_events = <strong>True</strong>)],
                      [sg.Button(<span style="color:#880000">"Set Theme"</span>)]]
    
    layout = [[sg.Text(<span style="color:#880000">'Demo Of (Almost) All Elements'</span>, size=(<span style="color:#880000">38</span>, <span style="color:#880000">1</span>), justification=<span style="color:#880000">'center'</span>, font=(<span style="color:#880000">"Helvetica"</span>, <span style="color:#880000">16</span>), relief=sg.RELIEF_RIDGE, <span style="color:#333333"><strong>k</strong></span>=<span style="color:#880000">'-TEXT HEADING-'</span>, enable_events=<strong>True</strong>)]]
    layout +=[[sg.TabGroup([[  sg.Tab(<span style="color:#880000">'Input Elements'</span>, input_layout),
                               sg.Tab(<span style="color:#880000">'Asthetic Elements'</span>, asthetic_layout),
                               sg.Tab(<span style="color:#880000">'Graphing'</span>, graphing_layout),
                               sg.Tab(<span style="color:#880000">'Specialty'</span>, specalty_layout),
                               sg.Tab(<span style="color:#880000">'Theming'</span>, theme_layout),
                               sg.Tab(<span style="color:#880000">'Output'</span>, logging_layout)]], key=<span style="color:#880000">'-TAB GROUP-'</span>)]]
              
    <strong><span style="color:#333333"><strong>return</strong></span></strong> sg.Window(<span style="color:#880000">'All Elements Demo'</span>, layout, right_click_menu=right_click_menu_def)


<strong>def</strong> <strong>main</strong>():
    window = make_window(sg.theme())
    
    # This <span style="color:#333333"><strong>is</strong></span> <span style="color:#333333"><strong>an</strong></span> Event Loop 
    <strong><span style="color:#333333"><strong>while</strong></span></strong> <strong>True</strong>:
        event, <span style="color:#397300">values</span> = window.<span style="color:#333333"><strong>read</strong></span>(timeout=<span style="color:#880000">100</span>)
        # keep <span style="color:#333333"><strong>an</strong></span> animation running <span style="color:#333333"><strong>so</strong></span> show things are happening
        window[<span style="color:#880000">'-GIF-IMAGE-'</span>].update_animation(sg.DEFAULT_BASE64_LOADING_GIF, time_between_frames=<span style="color:#880000">100</span>)
        <strong><span style="color:#333333"><strong>if</strong></span></strong> event <strong>not</strong> <strong>in</strong> (sg.TIMEOUT_EVENT, sg.WIN_CLOSED):
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">'============ Event = '</span>, event, <span style="color:#880000">' =============='</span>)
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">'-------- Values Dictionary (key=value) --------'</span>)
            <strong><span style="color:#333333"><strong>for</strong></span></strong> key <strong>in</strong> value<span style="color:#bc6060">s:</span>
                <span style="color:#333333"><strong>print</strong></span>(key, <span style="color:#880000">' = '</span>,<span style="color:#397300">values</span>[key])
        <strong><span style="color:#333333"><strong>if</strong></span></strong> event <strong>in</strong> (<strong>None</strong>, <span style="color:#880000">'Exit'</span>):
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"[LOG] Clicked Exit!"</span>)
            <strong><span style="color:#333333"><strong>break</strong></span></strong>
        <strong>elif</strong> event == <span style="color:#880000">'About'</span>:
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"[LOG] Clicked About!"</span>)
            sg.<span style="color:#333333"><strong>popup</strong></span>(<span style="color:#880000">'PySimpleGUI Demo All Elements'</span>,
                     <span style="color:#880000">'Right click anywhere to see right click menu'</span>,
                     <span style="color:#880000">'Visit each of the tabs to see available elements'</span>,
                     <span style="color:#880000">'Output of event and values can be see in Output tab'</span>,
                     <span style="color:#880000">'The event and values dictionary is printed after every event'</span>)
        <strong>elif</strong> event == <span style="color:#880000">'Popup'</span>:
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"[LOG] Clicked Popup Button!"</span>)
            sg.<span style="color:#333333"><strong>popup</strong></span>(<span style="color:#880000">"You pressed a button!"</span>)
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"[LOG] Dismissing Popup!"</span>)
        <strong>elif</strong> event == <span style="color:#880000">'Test Progress bar'</span>:
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"[LOG] Clicked Test Progress Bar!"</span>)
            progress_bar = window[<span style="color:#880000">'-PROGRESS BAR-'</span>]
            <strong><span style="color:#333333"><strong>for</strong></span></strong> i <strong>in</strong> <span style="color:#397300">range</span>(<span style="color:#880000">1000</span>):
                <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"[LOG] Updating progress bar by 1 step ("</span>+str(i)+<span style="color:#880000">")"</span>)
                progress_bar.UpdateBar(i + <span style="color:#880000">1</span>)
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"[LOG] Progress bar complete!"</span>)
        <strong>elif</strong> event == <span style="color:#880000">"-GRAPH-"</span>:
            graph = window[<span style="color:#880000">'-GRAPH-'</span>]       # <span style="color:#397300">type</span>: sg.Graph
            graph.draw_circle(<span style="color:#397300">values</span>[<span style="color:#880000">'-GRAPH-'</span>], fill_color=<span style="color:#880000">'yellow'</span>, radius=<span style="color:#880000">20</span>)
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"[LOG] Circle drawn at: "</span> + str(<span style="color:#397300">values</span>[<span style="color:#880000">'-GRAPH-'</span>]))
        <strong>elif</strong> event == <span style="color:#880000">"Open Folder"</span>:
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"[LOG] Clicked Open Folder!"</span>)
            folder_or_file = sg.popup_get_folder(<span style="color:#880000">'Choose your folder'</span>)
            sg.<span style="color:#333333"><strong>popup</strong></span>(<span style="color:#880000">"You chose: "</span> + str(folder_or_file))
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"[LOG] User chose folder: "</span> + str(folder_or_file))
        <strong>elif</strong> event == <span style="color:#880000">"Open File"</span>:
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"[LOG] Clicked Open File!"</span>)
            folder_or_file = sg.popup_get_file(<span style="color:#880000">'Choose your file'</span>)
            sg.<span style="color:#333333"><strong>popup</strong></span>(<span style="color:#880000">"You chose: "</span> + str(folder_or_file))
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"[LOG] User chose file: "</span> + str(folder_or_file))
        <strong>elif</strong> event == <span style="color:#880000">"Set Theme"</span>:
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"[LOG] Clicked Set Theme!"</span>)
            theme_chosen = <span style="color:#397300">values</span>[<span style="color:#880000">'-THEME LISTBOX-'</span>][<span style="color:#880000">0</span>]
            <span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"[LOG] User Chose Theme: "</span> + str(theme_chosen))
            window.<span style="color:#333333"><strong>close</strong></span>()
            window = make_window(theme_chosen)

    window.<span style="color:#333333"><strong>close</strong></span>()
    <span style="color:#333333"><strong>exit</strong></span>(<span style="color:#880000">0</span>)

<strong><span style="color:#333333"><strong>if</strong></span></strong> __name__ == <span style="color:#880000">'__main__'</span>:
    main()

</code></span></span>

Let's see the effect after running:

This demo is a collection of all components of PySimpleGUI, and each tab is a category. This includes progress bar, canvas, theme, scroll bar, etc. If you want to find interface components, just look in the source code of this demo.

summary

There are more examples here. Let's explore it by ourselves! Here is mainly to introduce a method of rapid GUI development, commonly known as. However, this is only a rapid development method. If you have time, you'd better go to see the source code and understand the principle! CV Dafa

Keywords: Python Back-end

Added by podarum on Thu, 13 Jan 2022 15:09:49 +0200