GUI 实例
PySimpleGUI 在GitHub上的地址是:
<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>
大家可以访问看看,其首页是这样的:
有很多内容是不是?
这里面有一个重要的内容,在 DemoPrograms 文件夹下,这个文件夹是作者写的一些 demo 实例。作者真的是深谙我们这些懒虫的心理,即使有了这么简单好用的 GUI 框架,到了要写实例的时候,我们也可能会去网络上搜索实例,然后采用 。框架作者可能料想到这一点,所以他自己写了很多不同的实例,让你真正的拿来即用。CV大法
这个文件夹下大概有300多个实例,基本上可以囊括我们平时使用 python 写 GUI 所能遇到的各种组件和布局了。
CV 几个看看
有了这个神器,我们只需要把这个 GitHub 上的项目给复制到本地,然后将这些实例运行一遍,大致知道每个实例u哪些内容。后续当我们自己要写 GUI 时,我们只需要找到对应的实例,然后复制代码就可以了。是不是很简单?
下面我来运行几个 demo ,给大家展示一下这里面的实例都是什么样子的。
聊天界面
我们先复制一下源码:
<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>
运行一下,看看效果:
这是一个带历史记录的聊天软件,如果你需要做一个类似的软件的话,可以直接复制代码,然后稍微改动一下。
组件大全
我们再来看一个例子:
<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>
我们来看看运行之后的效果:
这个 demo 是 PySimpleGUI 所有组件的集合,每一个 tab 都是一个分类。这里面包括进度条、画布、主题、滚动条等等。如果你想要找界面组件,到这个 demo 的源码里面找就对了。
总结
这里面还有更多实例,大家就自己去探索吧!这里主要是给大家介绍一个快速开发 GUI 的方法,俗称 。不过这只是一种快速开发方式,大家有时间还是去看看源码,了解一下原理比较好!CV大法