forked from PySimpleGUI/PySimpleGUI
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
4255 lines (4048 loc) · 278 KB
/
index.html
File metadata and controls
4255 lines (4048 loc) · 278 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="None">
<link rel="shortcut icon" href="img/favicon.ico">
<title>My Docs</title>
<link href="css/bootstrap-custom.min.css" rel="stylesheet">
<link href="css/font-awesome.min.css" rel="stylesheet">
<link href="css/base.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<script src="js/jquery-1.10.2.min.js" defer></script>
<script src="js/bootstrap-3.0.3.min.js" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</head>
<body class="homepage">
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<!-- Collapsed navigation -->
<div class="navbar-header">
<!-- Expander button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href=".">My Docs</a>
</div>
<!-- Expanded navigation -->
<div class="navbar-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav">
<li class="active">
<a href=".">Home</a>
</li>
<li >
<a href="architecture/">Architecture</a>
</li>
<li >
<a href="cookbook/">Cookbook</a>
</li>
<li >
<a href="tutorial/">Tutorial</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="#" data-toggle="modal" data-target="#mkdocs_search_modal">
<i class="fa fa-search"></i> Search
</a>
</li>
<li class="disabled">
<a rel="next" >
<i class="fa fa-arrow-left"></i> Previous
</a>
</li>
<li >
<a rel="prev" href="architecture/">
Next <i class="fa fa-arrow-right"></i>
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="container">
<div class="col-md-3"><div class="bs-sidebar hidden-print affix well" role="complementary">
<ul class="nav bs-sidenav">
<li class="main active"><a href="#pysimplegui">PySimpleGUI</a></li>
<li><a href="#supports-both-python-27-3-when-using-tkinter">Supports both Python 2.7 & 3 when using tkinter</a></li>
<li><a href="#supports-both-pyside2-and-pyqt5-limited-support">Supports both PySide2 and PyQt5 (limited support)</a></li>
<li><a href="#effortlessly-move-across-tkinter-qt-wxpython-and-the-web-remi-by-changing-only-the-import-statement">Effortlessly move across tkinter, Qt, WxPython, and the Web (Remi) by changing only the import statement</a></li>
<li><a href="#the-only-way-to-write-both-desktop-and-web-based-guis-at-the-same-time">The only way to write both desktop and web based GUIs at the same time</a></li>
<li class="main "><a href="#qt-version">Qt Version</a></li>
<li><a href="#source-code-compatibility">Source code compatibility</a></li>
<li class="main "><a href="#wxpython-version">WxPython Version</a></li>
<li class="main "><a href="#web-version-remi">Web Version (Remi)</a></li>
<li class="main "><a href="#replit-version">repl.it Version</a></li>
<li class="main "><a href="#support">Support</a></li>
<li class="main "><a href="#platforms">Platforms</a></li>
<li><a href="#features">Features</a></li>
<li class="main "><a href="#getting-started-with-pysimplegui">Getting Started with PySimpleGUI</a></li>
<li><a href="#installing-pysimplegui">Installing PySimpleGUI</a></li>
<li><a href="#using-python-3">Using - Python 3</a></li>
<li><a href="#using-python-27">Using - Python 2.7</a></li>
<li><a href="#code-samples-assume-python-3">Code Samples Assume Python 3</a></li>
<li class="main "><a href="#apis">APIs</a></li>
<li><a href="#python-language-features">Python Language Features</a></li>
<li class="main "><a href="#high-level-api-calls-popups">High Level API Calls - Popup's</a></li>
<li><a href="#popup-output">Popup Output</a></li>
<li><a href="#popup-input">Popup Input</a></li>
<li class="main "><a href="#progress-meters">Progress Meters!</a></li>
<li class="main "><a href="#debug-output">Debug Output</a></li>
<li class="main "><a href="#custom-window-api-calls-your-first-window">Custom window API Calls (Your First window)</a></li>
<li><a href="#the-window-designer">The window Designer</a></li>
<li class="main "><a href="#copy-these-design-patterns">Copy these design patterns!</a></li>
<li><a href="#pattern-1-one-shot-window-read-into-list-or-dictionary-the-most-common-pattern">Pattern 1 - "One-shot Window" - Read into list or dictionary (The Most Common Pattern)</a></li>
<li><a href="#pattern-2-a-persistent-window-multiple-reads-using-an-event-loop">Pattern 2 A - Persistent window (multiple reads using an event loop)</a></li>
<li><a href="#pattern-2-b-persistent-window-multiple-reads-using-an-event-loop-updates-data-in-window">Pattern 2 B - Persistent window (multiple reads using an event loop + updates data in window)</a></li>
<li><a href="#how-gui-programming-in-python-should-look-at-least-for-beginners">How GUI Programming in Python Should Look? At least for beginners ?</a></li>
<li><a href="#return-values">Return values</a></li>
<li><a href="#events">Events</a></li>
<li><a href="#the-event-loop-callback-functions">The Event Loop / Callback Functions</a></li>
<li><a href="#all-widgets-elements">All Widgets / Elements</a></li>
<li class="main "><a href="#building-custom-windows">Building Custom Windows</a></li>
<li><a href="#synchronous-windows">Synchronous windows</a></li>
<li class="main "><a href="#window-object-beginning-a-window">Window Object - Beginning a window</a></li>
<li><a href="#window-location">Window Location</a></li>
<li><a href="#window-size">Window Size</a></li>
<li><a href="#element-sizes">Element Sizes</a></li>
<li><a href="#no-titlebar">No Titlebar</a></li>
<li><a href="#grab-anywhere">Grab Anywhere</a></li>
<li><a href="#always-on-top">Always on top</a></li>
<li><a href="#focus">Focus</a></li>
<li><a href="#window-methods-things-you-can-do-with-a-window-object">Window Methods (things you can do with a Window object)</a></li>
<li><a href="#window-methods">Window Methods</a></li>
<li class="main "><a href="#elements">Elements</a></li>
<li><a href="#common-element-parameters">Common Element Parameters</a></li>
<li><a href="#shortcut-functions-multiple-function-names">Shortcut Functions / Multiple Function Names</a></li>
<li><a href="#text-element">Text Element</a></li>
<li><a href="#multiline-text-element">Multiline Text Element</a></li>
<li><a href="#output-element">Output Element</a></li>
<li><a href="#input-elements">Input Elements</a></li>
<li><a href="#text-input-element-shortcuts-input-in">Text Input Element Shortcuts (Input, In)</a></li>
<li><a href="#combo-element">Combo Element</a></li>
<li><a href="#listbox-element">Listbox Element</a></li>
<li><a href="#slider-element">Slider Element</a></li>
<li><a href="#radio-button-element">Radio Button Element</a></li>
<li><a href="#checkbox-element">Checkbox Element</a></li>
<li><a href="#spin-element">Spin Element</a></li>
<li><a href="#image-element">Image Element</a></li>
<li><a href="#button-element">Button Element</a></li>
<li><a href="#buttonmenu-element">ButtonMenu Element</a></li>
<li><a href="#vertical-separator-element">Vertical Separator Element</a></li>
<li><a href="#progressbar-element">ProgressBar Element</a></li>
<li><a href="#column-element">Column Element</a></li>
<li><a href="#frame-element-labelled-frames-frames-with-a-title">Frame Element (Labelled Frames, Frames with a title)</a></li>
<li><a href="#canvas-element">Canvas Element</a></li>
<li><a href="#graph-element">Graph Element</a></li>
<li><a href="#table-element">Table Element</a></li>
<li><a href="#tree-element">Tree Element</a></li>
<li><a href="#tab-and-tab-group-elements">Tab and Tab Group Elements</a></li>
<li><a href="#pane-element">Pane Element</a></li>
<li><a href="#colors_1">Colors</a></li>
<li class="main "><a href="#systemtray">SystemTray</a></li>
<li><a href="#system-tray-design-pattern">System Tray Design Pattern</a></li>
<li><a href="#menu-definition">Menu Definition</a></li>
<li><a href="#systemtray-methods">SystemTray Methods</a></li>
<li class="main "><a href="#global-settings">Global Settings</a></li>
<li class="main "><a href="#persistent-windows-window-stays-open-after-button-click">Persistent windows (Window stays open after button click)</a></li>
<li><a href="#readtimeout-t-timeout_keytimeout">Read(timeout = t, timeout_key='timeout')</a></li>
<li><a href="#non-blocking-windows-asynchronous-reads">Non-Blocking Windows (Asynchronous reads)</a></li>
<li><a href="#sgtimeout_key">sg.TIMEOUT_KEY</a></li>
<li><a href="#persistent-window-example-running-timer-that-updates">Persistent Window Example - Running timer that updates</a></li>
<li><a href="#instead-of-a-non-blocking-read-use-change_submits-true-or-return_keyboard_events-true">Instead of a Non-blocking Read --- Use change_submits = True or return_keyboard_events = True</a></li>
<li class="main "><a href="#updating-elements-changing-elements-in-active-window">Updating Elements (changing elements in active window)</a></li>
<li><a href="#locating-elements">Locating Elements</a></li>
<li><a href="#progressbar-progress-meters">ProgressBar / Progress Meters</a></li>
<li class="main "><a href="#keyboard-mouse-capture">Keyboard & Mouse Capture</a></li>
<li><a href="#realtime-keyboard-capture">Realtime Keyboard Capture</a></li>
<li class="main "><a href="#menus">Menus</a></li>
<li><a href="#menubar">MenuBar</a></li>
<li><a href="#buttonmenus">ButtonMenus</a></li>
<li><a href="#right-click-menus">Right Click Menus</a></li>
<li><a href="#menu-shortcut-keys">Menu Shortcut keys</a></li>
<li><a href="#disabled-menu-entries">Disabled Menu Entries</a></li>
<li><a href="#keys-for-menus">Keys for Menus</a></li>
<li class="main "><a href="#running-multiple-windows">Running Multiple Windows</a></li>
<li><a href="#multi-window-design-pattern-1-both-windows-active">Multi-Window Design Pattern 1 - both windows active</a></li>
<li><a href="#multi-window-design-pattern-2-only-1-active-window">Multi-Window Design Pattern 2 - only 1 active window</a></li>
<li class="main "><a href="#sample-applications">Sample Applications</a></li>
<li><a href="#packages-used-in-demos">Packages Used In Demos</a></li>
<li class="main "><a href="#creating-a-windows-exe-file">Creating a Windows .EXE File</a></li>
<li class="main "><a href="#creating-a-mac-app-file">Creating a Mac App File</a></li>
<li><a href="#fun-stuff">Fun Stuff</a></li>
<li class="main "><a href="#known-issues">Known Issues</a></li>
<li><a href="#do-not-attempt-to-call-pysimplegui-from-multiple-threads-its-tkinter-based-and-tkinter-has-issues-with-multiple-threads">Do not attempt to call PySimpleGUI from multiple threads! It's tkinter based and tkinter has issues with multiple threads</a></li>
<li><a href="#contributing">Contributing</a></li>
<li><a href="#versions">Versions</a></li>
<li><a href="#release-notes">Release Notes</a></li>
<li><a href="#3180-11-dec-2018">3.18.0 11-Dec-2018</a></li>
<li><a href="#3192-13-dec-2018">3.19.2 13-Dec-2018</a></li>
<li><a href="#3200-1200-18-dec-2018">3.20.0 & 1.20.0 18-Dec-2018</a></li>
<li><a href="#3210-1210-28-dec-2018">3.21.0 & 1.21.0 28-Dec-2018</a></li>
<li class="main "><a href="#3220-pysimplegui-1220-pysimplegui27">3.22.0 PySimpleGUI / 1.22.0 PySimpleGUI27</a></li>
<li class="main "><a href="#3230-pysimplegui-1230-pysimplegui27-16-jan-2019">3.23.0 PySimpleGUI / 1.23.0 PySimpleGUI27 16-Jan-2019</a></li>
<li class="main "><a href="#3240-1240-16-jan-2019">3.24.0 1.24.0 16-Jan-2019</a></li>
<li class="main "><a href="#325-125-20-feb-2019">3.25 & 1.25 20-Feb-2019</a></li>
<li><a href="#upcoming">Upcoming</a></li>
<li><a href="#code-condition">Code Condition</a></li>
<li><a href="#design">Design</a></li>
<li><a href="#author">Author</a></li>
<li><a href="#demo-code-contributors">Demo Code Contributors</a></li>
<li><a href="#license">License</a></li>
<li><a href="#acknowledgments">Acknowledgments</a></li>
</ul>
</div></div>
<div class="col-md-9" role="main">
<p><img alt="pysimplegui_logo" src="https://user-images.githubusercontent.com/13696193/43165867-fe02e3b2-8f62-11e8-9fd0-cc7c86b11772.png" /> </p>
<p><a href="http://pepy.tech/project/pysimplegui"><img alt="Downloads" src="http://pepy.tech/badge/pysimplegui" /></a> tkinter
<a href="https://pepy.tech/project/pysimplegui27"><img alt="Downloads " src="https://pepy.tech/badge/pysimplegui27" /></a> tkinter 2.7
<a href="https://pepy.tech/project/pysimpleguiqt"><img alt="Downloads" src="https://pepy.tech/badge/pysimpleguiqt" /></a> Qt
<a href="https://pepy.tech/project/pysimpleguiWx"><img alt="Downloads" src="https://pepy.tech/badge/pysimpleguiwx" /></a> WxPython
<a href="https://pepy.tech/project/pysimpleguiWeb"><img alt="Downloads" src="https://pepy.tech/badge/pysimpleguiweb" /></a> Web (Remi)
<img alt="Documentation Status" src="https://readthedocs.org/projects/pysimplegui/badge/?version=latest" /> <br />
<img alt="Awesome Meter" src="https://img.shields.io/badge/Awesome_meter-100-yellow.svg" /> <br />
<img alt="Python Version" src="https://img.shields.io/badge/Python-2.7_3.x-yellow.svg" /> </p>
<h1 id="pysimplegui">PySimpleGUI</h1>
<h2 id="supports-both-python-27-3-when-using-tkinter">Supports both Python 2.7 & 3 when using tkinter</h2>
<h2 id="supports-both-pyside2-and-pyqt5-limited-support">Supports both PySide2 and PyQt5 (limited support)</h2>
<h2 id="effortlessly-move-across-tkinter-qt-wxpython-and-the-web-remi-by-changing-only-the-import-statement">Effortlessly move across tkinter, Qt, WxPython, and the Web (Remi) by changing only the import statement</h2>
<h2 id="the-only-way-to-write-both-desktop-and-web-based-guis-at-the-same-time">The <em>only</em> way to write both desktop and web based GUIs at the same time</h2>
<p><img alt="Python Version" src="https://img.shields.io/badge/PySimpleGUI_For_Python_3.x_Version-3.25.0-red.svg?longCache=true&style=for-the-badge" /> </p>
<p><img alt="Python Version" src="https://img.shields.io/badge/PySimpleGUI_For_Python_2.7_Version-1.25.0-blue.svg?longCache=true&style=for-the-badge" /> </p>
<p><img alt="Python Version" src="https://img.shields.io/badge/PySimpleGUIQt_Version-0.22.0-orange.svg?longCache=true&style=for-the-badge" /> </p>
<p><img alt="Python Version" src="https://img.shields.io/badge/PySimpleGUIWx_version-0.3.0-orange.svg?longCache=true&style=for-the-badge" /></p>
<p><img alt="Python Version" src="https://img.shields.io/badge/PySimpleGUIWeb_Version-0.10.0-orange.svg?longCache=true&style=for-the-badge" /></p>
<p><a href="https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142">Announcements of Latest Developments</a> </p>
<p><a href="http://pysimplegui.readthedocs.io/">ReadTheDocs</a> </p>
<p><a href="https://pysimplegui.readthedocs.io/cookbook/">COOKBOOK!</a> </p>
<p><a href="https://pysimplegui.readthedocs.io/tutorial/">Brief Tutorial</a> </p>
<p><a href="https://github.com/MikeTheWatchGuy/PySimpleGUI">Latest Demos and Master Branch on GitHub</a> </p>
<p><a href="https://github.com/MikeTheWatchGuy/PySimpleGUI/tree/master/docs">Docs in PDF Format</a> </p>
<p><a href="https://repl.it/@PySimpleGUI">Repl.it Home for PySimpleGUI</a></p>
<p>Super-simple GUI to use... Powerfully customizable </p>
<p>Home of the 1-line custom GUI & 1-line progress meter </p>
<p>The native GUI framework for perfectionists with deadlines </p>
<p>Actively developed and supported (It's 2019 and still going strong)</p>
<h4 id="note-regarding-python-versions">Note regarding Python versions</h4>
<p>As of 9/25/2018 <strong>both Python 3 and Python 2.7 are supported</strong>! The Python 3 version is named <code>PySimpleGUI</code>. The Python 2.7 version is <code>PySimpleGUI27</code>. They are installed separately and the imports are different. See instructions in Installation section for more info. </p>
<h1 id="qt-version">Qt Version</h1>
<p>Check out the new PySimpleGUI port to the Qt GUI Framework. You can learn more on the <a href="https://github.com/MikeTheWatchGuy/PySimpleGUI/tree/master/PySimpleGUIQt">PySimpleGUIQt GitHub site</a>. <strong>There is a separate Readme file for the Qt version</strong> that you'll find there. </p>
<p>Give it a shot if you're looking for something a bit more "modern". PySimpleGUIQt is currently in Alpha. All of the widgets are operational but some may not yet be full-featured. If one is missing and your project needs it, log an Issue and you'll likely get priority support. </p>
<p>Here is a summary of the Qt Elements</p>
<p><img alt="scrolling graphics" src="https://user-images.githubusercontent.com/13696193/48665874-8bfd0e00-ea84-11e8-880d-8e164d9fea34.gif" /></p>
<p>Are there enough things on there to cover your GUI solution?</p>
<h2 id="source-code-compatibility">Source code compatibility</h2>
<p>Your source code is completely portable from one platform to another by simply changing the import statement.</p>
<h1 id="wxpython-version">WxPython Version</h1>
<p><a href="https://github.com/PySimpleGUI/PySimpleGUI/tree/master/PySimpleGUIWx">PySimpleGUIWx GitHub site</a>. <strong>There is a separate Readme file for the WxPython version</strong>.</p>
<p>Started in late December 2018 PySimpleGUIWx started with the SystemTray Icon feature. This enabled the package to have one fully functioning feature that can be used along with tkinter to provide a complete program. The System Tray feature is complete and working very well.</p>
<p>The Windowing code is coming together with Reads now operational which means Popups work. The elements are getting completed on a regular basis. 3 more were just checked in. At least 1 new element is getting completed a week. </p>
<h1 id="web-version-remi">Web Version (Remi)</h1>
<p><a href="https://github.com/PySimpleGUI/PySimpleGUI/tree/master/PySimpleGUIWeb">PySimpleGUIWeb GitHub site</a>. <strong>There is a separate Readme file for the Web version</strong>.</p>
<p>New for 2019, PySimpleGUIWeb. This is an exciting development! PySimpleGUI in your Web Browser!</p>
<p>The underlying framework supplying the web capability is the Python package Remi. https://github.com/dddomodossola/remi Remi provides the widgets as well as a web server for you to connect to. It's an exiting new platform to be running on and has temporarily bumped the WxPython port from the highest priority. PySimpleGUIWeb is the current high priority project.</p>
<p>Read on and you'll understand even more why this is an important project...</p>
<h1 id="replit-version">repl.it Version</h1>
<p><strong><em>Want to really get your mind blown?</em></strong> Check out this <a href="https://repl.it/@PySimpleGUI/PySimpleGUIWeb-Demos">PySimpleGUI program</a> running in your web browser.</p>
<p>Thanks to the magic of repl.it and Remi it's possible to run PySimpleGUI code in a browser window without having Python running on your computer. </p>
<p>The programs you write using repl.it will automatically download and install the latest PySimpleGUIWeb from PyPI onto a virtual Python environment. All that is required is to type <code>import PySimpleGUIWeb</code> you'll have a Python environment up and running with the latest PyPI release of PySimpleGUIWeb. </p>
<p>This is an exciting new development that's opening up all kinds of possibilities for new ways to program and learn PySimpleGUI. Stayed tuned, much more to be posted about this in the near future. </p>
<p>Educators in particular should be interested. Students can not only post their homework easily for their teacher to access, but teachers can also run the students programs online. No downloading needed. Run it and check the results.</p>
<p>Depending on how you're viewing this document, you may or may not see an embedded browser window below that is running PySimpleGUI code.</p>
<iframe height="1000px" width="100%" src="https://repl.it/@PySimpleGUI/PySimpleGUIWeb-Demos?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe>
<h1 id="support">Support</h1>
<p>PySimpleGUI is an active project. Bugs are fixed, features are added, often. Should you run into trouble, open an issue on the GitHub site and you'll receive help by someone in the community. </p>
<h1 id="platforms">Platforms</h1>
<p>It's surprising that Python GUI code is completely cross platform from Windows to Mac to Linux. No source code changes. This is true for both PySimpleGUI and PySimpleGUIQt.</p>
<p>However, <strong>Macs</strong> suck. They suck on tkinter in particular. The "Look and feel" calls are disabled for Macs. Colored buttons in particular are broken. Not in the PySimpleGUI code, of course. It's mostly because Macs suck. Consider using Qt instead of tkinter on the Mac. Or, if using tkinter, bring your own button images. </p>
<hr />
<p>Looking for a GUI package? Are you </p>
<ul>
<li>looking to take your Python code from the world of command lines and into the convenience of a GUI? * </li>
<li>sitting on a Raspberry <strong>Pi</strong> with a touchscreen that's going to waste because you don't have the time to learn a GUI SDK? </li>
<li>into Machine Learning and are sick of the command line? </li>
<li>wanting to distribute your Python code to Windows users as a single .EXE file that launches straight into a GUI, much like a WinForms app? </li>
<li>would like to run a program in the system tray?</li>
<li>a teacher wanting to teach your students how to program using a GUI?</li>
<li>a student that wants to put a GUI onto their project?</li>
<li>looking for an active project?</li>
</ul>
<p>Look no further, <strong>you've found your GUI package</strong>. </p>
<pre><code>import PySimpleGUI as sg
sg.Popup('Hello From PySimpleGUI!', 'This is the shortest GUI program ever!')
</code></pre>
<p><img alt="hello world" src="https://user-images.githubusercontent.com/13696193/44960047-1f7f6380-aec6-11e8-9d5e-12ef935bcade.jpg" /> </p>
<p>Or how about a <strong><em>custom GUI</em></strong> in 1 line of code? </p>
<pre><code>import PySimpleGUI as sg
event, (filename,) = sg.Window('Get filename example'). Layout([[sg.Text('Filename')], [sg.Input(), sg.FileBrowse()], [sg.OK(), sg.Cancel()] ]).Read()
</code></pre>
<p><img alt="get filename" src="https://user-images.githubusercontent.com/13696193/44960039-f1018880-aec5-11e8-8a43-3d7f8ff93b67.jpg" /> </p>
<p>Build beautiful customized windows that fit your specific problem. Let PySimpleGUI solve your GUI problem while you solve your real problems. Look through the Cookbook, find a matching recipe, copy, paste, run within minutes. This is the process PySimpleGUI was designed to facilitate. </p>
<p>Your windows don't have to look like "boring" old windows. Add a few custom graphics to your windows to polish things up.</p>
<p><img alt="batterup2" src="https://user-images.githubusercontent.com/13696193/50378902-6aa2bb00-060a-11e9-8f2f-d746694fa4ee.gif" /></p>
<p><img alt="uno_final" src="https://user-images.githubusercontent.com/13696193/49945232-67952580-feba-11e8-90c8-7dc31c5f7c67.gif" /> </p>
<p>PySimpleGUI wraps tkinter or Qt so that you get all the same widgets as you would tkinter/Qt, but you interact with them in a more friendly way. It does the layout and boilerplate code for you and presents you with a simple, efficient interface. </p>
<p><img alt="everything dark theme" src="https://user-images.githubusercontent.com/13696193/44959854-b1d23800-aec3-11e8-90b6-5af915a86d15.jpg" /> </p>
<p>Perhaps you're looking for a way to interact with your <strong>Raspberry Pi</strong> in a more friendly way. The same for shown as on Pi (roughly the same) </p>
<p><img alt="raspberry pi everything demo" src="https://user-images.githubusercontent.com/13696193/44279694-5b58ce80-a220-11e8-9ab6-d6021f5a944f.jpg" /> </p>
<p>In addition to a primary GUI, you can add a Progress Meter to your code with ONE LINE of code. Slide this line into any of your <code>for</code> loops and get a nice meter: </p>
<pre><code>OneLineProgressMeter('My meter title', current_value, max value, 'key')
</code></pre>
<p><img alt="easyprogressmeter" src="https://user-images.githubusercontent.com/13696193/44960065-83099100-aec6-11e8-8aa8-96e4b100a0e4.jpg" /> </p>
<p>It's simple to show animated GIFs. </p>
<p><img alt="loading animation" src="https://user-images.githubusercontent.com/13696193/51280871-d2041e80-19ae-11e9-8757-802eb95352ed.gif" /> </p>
<p>How about embedding a game inside of a GUI? This game of Pong is written in tkinter and then dropped into the PySimpleGUI window creating a game that has an accompanying GUI. </p>
<p><img alt="pong" src="https://user-images.githubusercontent.com/13696193/45860012-2d8d0b00-bd33-11e8-9efd-3eaf4c30f324.gif" /> </p>
<p>Combining PySimpleGUI with PyInstaller creates something truly remarkable and special, a Python program that looks like a Windows WinForms application. This application with working menu was created in 20 lines of Python code. It is a single .EXE file that launches straight into the screen you see. And more good news, the only icon you see on the taskbar is the window itself... there is no pesky shell window. </p>
<p><img alt="menu demo" src="https://user-images.githubusercontent.com/13696193/45923097-8fbc4c00-beaa-11e8-87d2-01a5331811c8.gif" /> </p>
<p>## Background <br />
I was frustrated by having to deal with the dos prompt when I had a powerful Windows machine right in front of me. Why is it SO difficult to do even the simplest of input/output to a window in Python?? </p>
<p>There are a number of 'easy to use' Python GUIs, but they were too limited for my requirements. PySimpleGUI aims for the same simplicity found in packages like <code>EasyGUI</code>and <code>WxSimpleGUI</code> , both really handy but limited, and adds the ability to define your own layouts. This ability to make your own windows using a large palette of widgets is but one difference between the existing "simple" packages and <code>PySimpleGUI</code>. </p>
<p>With a simple GUI, it becomes practical to "associate" .py files with the python interpreter on Windows. Double click a py file and up pops a GUI window, a more pleasant experience than opening a dos Window and typing a command line. </p>
<p>The <code>PySimpleGUI</code> package is focused on the <strong><em>developer</em></strong>. </p>
<blockquote>
<p>Create a custom GUI with as little and as simple code as possible. </p>
</blockquote>
<p>This was the primary focus used to create PySimpleGUI. </p>
<blockquote>
<p>"Do it in a Python-like way" </p>
</blockquote>
<p>was the second. </p>
<h2 id="features">Features</h2>
<p>While simple to use, PySimpleGUI has significant depth to be explored by more advanced programmers. The feature set goes way beyond the requirements of a beginner programmer, and into the required features needed for complex GUIs. </p>
<pre><code>Features of PySimpleGUI include:
Support for Python versions 2.7 and 3
Text
Single Line Input
Buttons including these types:
File Browse
Files Browse
Folder Browse
SaveAs
Non-closing return
Close window
Realtime
Calendar chooser
Color chooser
Button Menu
Checkboxes
Radio Buttons
Listbox
Option Menu
Menubar
Button Menu
Slider
Dial
Graph
Frame with title
Icons
Multi-line Text Input
Scroll-able Output
Images
Tables
Trees
Progress Bar Async/Non-Blocking Windows
Tabbed windows
Paned windows
Persistent Windows
Redirect Python Output/Errors to scrolling window
'Higher level' APIs (e.g. MessageBox, YesNobox, ...)
Single-Line-Of-Code Proress Bar & Debug Print
Complete control of colors, look and feel
Selection of pre-defined palettes
Button images
Horizontal and Verticle Separators
Return values as dictionary
Set focus
Bind return key to buttons
Group widgets into a column and place into window anywhere
Scrollable columns
Keyboard low-level key capture
Mouse scroll-wheel support
Get Listbox values as they are selected
Get slider, spinner, combo as they are changed
Update elements in a live window
Bulk window-fill operation
Save / Load window to/from disk
Borderless (no titlebar) windows
Always on top windows
Menus with ALT-hotkey
Right click pop-up menu
Tooltips
Clickable links
Transparent windows
Movable windows
Animated GIFs
No async programming required (no callbacks to worry about)
</code></pre>
<p>An example of many widgets used on a single window. A little further down you'll find the 21 lines of code required to create this complex window. Try it if you don't believe it. Install PySimpleGUI then : </p>
<blockquote>
<p>Start Python, copy and paste the code below into the >>> prompt and hit enter. This will pop up... <br />
</p>
</blockquote>
<p><img alt="everything example" src="https://user-images.githubusercontent.com/13696193/43097412-0a4652aa-8e8a-11e8-8e09-939484e3c568.jpg" /> </p>
<pre><code>import PySimpleGUI as sg
layout = [[sg.Text('All graphic widgets in one window!', size=(30, 1), font=("Helvetica", 25), text_color='blue')],
[sg.Text('Here is some text.... and a place to enter text')],
[sg.InputText()],
[sg.Checkbox('My first checkbox!'), sg.Checkbox('My second checkbox!', default=True)],
[sg.Radio('My first Radio! ', "RADIO1", default=True), sg.Radio('My second Radio!', "RADIO1")],
[sg.Multiline(default_text='This is the default Text shoulsd you decide not to type anything',)],
[sg.InputCombo(['Combobox 1', 'Combobox 2'], size=(20, 3)),
sg.Slider(range=(1, 100), orientation='h', size=(35, 20), default_value=85)],
[sg.Listbox(values=['Listbox 1', 'Listbox 2', 'Listbox 3'], size=(30, 6)),
sg.Slider(range=(1, 100), orientation='v', size=(10, 20), default_value=25),
sg.Slider(range=(1, 100), orientation='v', size=(10, 20), default_value=75),
sg.Slider(range=(1, 100), orientation='v', size=(10, 20), default_value=10)],
[sg.Text('_' * 100, size=(70, 1))],
[sg.Text('Choose Source and Destination Folders', size=(35, 1))],
[sg.Text('Source Folder', size=(15, 1), auto_size_text=False, justification='right'), sg.InputText('Source'),
sg.FolderBrowse()],
[sg.Text('Destination Folder', size=(15, 1), auto_size_text=False, justification='right'), sg.InputText('Dest'),
sg.FolderBrowse()],
[sg.Submit(), sg.Cancel(), sg.Button('Customized', button_color=('white', 'green'))]]
event, values = sg.Window('Everything bagel', auto_size_text=True, default_element_size=(40, 1)).Layout(layout).Read()
</code></pre>
<hr />
<h3 id="design-goals">Design Goals</h3>
<blockquote>
<p>Copy, Paste, Run. </p>
</blockquote>
<p><code>PySimpleGUI's</code> goal with the API is to be easy on the programmer, and to function in a Python-like way. Since GUIs are visual, it was desirable for the code to visually match what's on the screen. By providing a significant amount of documentation and an easy to use Cookbook, it's possible to see your first GUI within 5 minutes of beginning the installation. </p>
<blockquote>
<p>Be Pythonic </p>
</blockquote>
<p>Be Pythonic... Attempted to use language constructs in a natural way and to exploit some of Python's interesting features. Python's lists and optional parameters make PySimpleGUI work smoothly. </p>
<ul>
<li>windows are represented as Python lists. <ul>
<li>A window is a list of rows </li>
</ul>
</li>
<li>A row is a list of elements </li>
<li>Return values are a list of button presses and input values. </li>
<li>Return values can also be represented as a dictionary </li>
<li>The SDK calls collapse down into a single line of Python code that presents a custom GUI and returns values </li>
<li>Linear programming instead of callbacks </li>
</ul>
<p>#### Lofty Goals </p>
<blockquote>
<p>Change Python </p>
</blockquote>
<p>The hope is not that <strong><em>this</em></strong> package will become part of the Python Standard Library. </p>
<p>The hope is that Python will become <strong><em>the</em></strong> go-to language for creating GUI programs that run on Windows, Mac, and Linux <em>for all levels of developer</em>. </p>
<p>The hope is that beginners that are interested in graphic design will have an easy way to express themselves, right from the start of their Python experience. </p>
<p>There is a noticeable gap in the Python GUI solution. Fill that gap and who knows what will happen. </p>
<p>Maybe there's no "there there". <strong><em>Or</em></strong> maybe a simple GUI API will enable Python to dominate yet another computing discipline like it has so many others. This is my attempt to find out. </p>
<hr />
<h1 id="getting-started-with-pysimplegui">Getting Started with PySimpleGUI</h1>
<h2 id="installing-pysimplegui">Installing PySimpleGUI</h2>
<h3 id="installing-python-3">Installing Python 3</h3>
<pre><code>pip install --upgrade PySimpleGUI
</code></pre>
<p>On some systems you need to run pip3. </p>
<pre><code>pip3 install --upgrade PySimpleGUI
</code></pre>
<p>On a Raspberry Pi, this is should work: </p>
<pre><code>sudo pip3 install --upgrade pysimplegui
</code></pre>
<p>Some users have found that upgrading required using an extra flag on the pip <code>--no-cache-dir</code>. </p>
<pre><code>pip install --upgrade --no-cache-dir
</code></pre>
<p>On some versions of Linux you will need to first install pip. Need the Chicken before you can get the Egg (get it... Egg?) </p>
<p><code>sudo apt install python3-pip</code> </p>
<p>If for some reason you are unable to install using <code>pip</code>, don't worry, you can still import PySimpleGUI by downloading the file PySimleGUI.py and placing it in your folder along with the application that is importing it. </p>
<p><code>tkinter</code> is a requirement for PySimpleGUI (the only requirement). Some OS variants, such as Ubuntu, do not some with <code>tkinter</code> already installed. If you get an error similar to: </p>
<pre><code>ImportError: No module named tkinter
</code></pre>
<p>then you need to install <code>tkinter</code>.
For python 2.7</p>
<p><code>sudo apt-get install python-tk</code> </p>
<p>For python 3
<code>sudo apt-get install python3-tk</code> </p>
<p>More information about installing tkinter can be found here: https://www.techinfected.net/2015/09/how-to-install-and-use-tkinter-in-ubuntu-debian-linux-mint.html</p>
<h3 id="installing-for-python-27">Installing for Python 2.7</h3>
<p><code>pip install --upgrade PySimpleGUI27</code> <br />
or <br />
<code>pip2 install --upgrade PySimpleGUI27</code> </p>
<p>You may need to also install "future" for version 2.7 </p>
<pre><code>pip install future
</code></pre>
<p>or <br />
<code>pip2 install future</code> </p>
<p>Python 2.7 support is relatively new and the bugs are still being worked out. I'm unsure what may need to be done to install tkinter for Python 2.7. Will update this readme when more info is available </p>
<p>Like above, you may have to install either pip or tkinter. To do this on Python 2.7: </p>
<p><code>sudo apt install python-pip</code> </p>
<p><code>sudo apt install python-tkinter</code> </p>
<h3 id="testing-your-installation">Testing your installation</h3>
<p>Once you have installed, or copied the .py file to your app folder, you can test the installation using python. At the command prompt start up Python. </p>
<h4 id="instructions-for-python-27">Instructions for Python 2.7:</h4>
<pre><code>python
>>> import PySimpleGUI27
>>> PySimpleGUI27.main()
</code></pre>
<h4 id="instructions-for-python-3">Instructions for Python 3:</h4>
<pre><code>python3
>>> import PySimpleGUI
>>> PySimpleGUI.main()
</code></pre>
<p>You will see a sample window in the center of your screen. If it's not installed correctly you are likely to get an error message during one of those commands </p>
<p>Here is the window you should see: </p>
<p><img alt="sample window" src="https://user-images.githubusercontent.com/13696193/46097669-79efa500-c190-11e8-885c-e5d4d5d09ea6.jpg" /> </p>
<h3 id="prerequisites">Prerequisites</h3>
<p>Python 2.7 or Python 3 <br />
tkinter </p>
<p>PySimpleGUI Runs on all Python3 platforms that have tkinter running on them. It has been tested on Windows, Mac, Linux, Raspberry Pi. Even runs on <code>pypy3</code>. </p>
<h3 id="exe-file-creation">EXE file creation</h3>
<p>If you wish to create an EXE from your PySimpleGUI application, you will need to install <code>PyInstaller</code>. There are instructions on how to create an EXE at the bottom of this ReadMe </p>
<h2 id="using-python-3">Using - Python 3</h2>
<p>To use in your code, simply import.... <br />
<code>import PySimpleGUI as sg</code> </p>
<p>Then use either "high level" API calls or build your own windows. </p>
<pre><code>sg.Popup('This is my first Popup')
</code></pre>
<p><img alt="first popup" src="https://user-images.githubusercontent.com/13696193/44957300-c7813680-ae9e-11e8-9a8c-c70198db7907.jpg" /> </p>
<p>Yes, it's just that easy to have a window appear on the screen using Python. With PySimpleGUI, making a custom window appear isn't much more difficult. The goal is to get you running on your GUI within <strong><em>minutes</em></strong>, not hours nor days. </p>
<h2 id="using-python-27">Using - Python 2.7</h2>
<p>Those using Python 2.7 will import a different module name <br />
<code>import PySimpleGUI27 as sg</code> </p>
<h2 id="code-samples-assume-python-3">Code Samples Assume Python 3</h2>
<p>While all of the code examples you will see in this Readme and the Cookbook assume Python 3 and thus have an <code>import PySimpleGUI</code> at the top, you can run <strong><em>all</em></strong> of this code on Python 2.7 by changing the import statement to <code>import PySimpleGUI27</code> </p>
<hr />
<h1 id="apis">APIs</h1>
<p>PySimpleGUI can be broken down into 2 types of API's: <br />
* High Level single call functions (The <code>Popup</code> calls) <br />
* Custom window functions </p>
<h3 id="python-language-features">Python Language Features</h3>
<p>There are a number of Python language features that PySimpleGUI utilizes heavily for API access that should be understood... <br />
* Variable number of arguments to a function call <br />
* Optional parameters to a function call <br />
* Dictionaries </p>
<h4 id="variable-number-of-arguments">Variable Number of Arguments</h4>
<p>The "High Level" API calls that <em>output</em> values take a variable number of arguments so that they match a "print" statement as much as possible. The idea is to make it simple for the programmer to output as many items as desired and in any format. The user need not convert the variables to be output into the strings. The PySimpleGUI functions do that for the user. </p>
<pre><code>sg.Popup('Variable number of parameters example', var1, var2, "etc")
</code></pre>
<p>Each new item begins on a new line in the Popup </p>
<p><img alt="snap0179" src="https://user-images.githubusercontent.com/13696193/43658129-f6ca49c6-9725-11e8-9317-1f77443eb04a.jpg" /> </p>
<h4 id="optional-parameters-to-a-function-call">Optional Parameters to a Function Call</h4>
<p>This feature of the Python language is utilized <strong><em>heavily</em></strong> as a method of customizing windows and window Elements. Rather than requiring the programmer to specify every possible option for a widget, instead only the options the caller wants to override are specified. </p>
<p>Here is the function definition for the Popup function. The details aren't important. What is important is seeing that there is a long list of potential tweaks that a caller can make. However, they don't <em>have</em> to be specified on each and every call. </p>
<pre><code>def Popup(*args,
button_color=None,
button_type=MSG_BOX_OK,
auto_close=False,
auto_close_duration=None,
icon=DEFAULT_WINDOW_ICON,
line_width=MESSAGE_BOX_LINE_WIDTH,
font=None):
</code></pre>
<p>If the caller wanted to change the button color to be black on yellow, the call would look something like this: </p>
<pre><code>sg.Popup('This box has a custom button color', button_color=('black', 'yellow'))
</code></pre>
<p><img alt="snap0180" src="https://user-images.githubusercontent.com/13696193/43658171-13a72bfe-9726-11e8-8c7a-0a46e46fb202.jpg" /> </p>
<h4 id="dictionaries">Dictionaries</h4>
<p>Dictionaries are used by more advanced PySimpleGUI users. You'll know that dictionaries are being used if you see a <code>key</code> parameter on any Element. Dictionaries are used in 2 ways: <br />
1. To identify values when a window is read <br />
2. To identify Elements so that they can be "updated" </p>
<hr />
<h1 id="high-level-api-calls-popups">High Level API Calls - Popup's</h1>
<p>"High level calls" are those that start with "Popup". They are the most basic form of communications with the user. They are named after the type of window they create, a pop-up window. These windows are meant to be short lived while, either delivering information or collecting it, and then quickly disappearing. </p>
<h2 id="popup-output">Popup Output</h2>
<p>Think of the <code>Popup</code> call as the GUI equivalent of a <code>print</code> statement. It's your way of displaying results to a user in the windowed world. Each call to Popup will create a new Popup window. </p>
<p><code>Popup</code> calls are normally blocking. your program will stop executing until the user has closed the Popup window. A non-blocking window of Popup discussed in the async section. </p>
<p>Just like a print statement, you can pass any number of arguments you wish. They will all be turned into strings and displayed in the popup window. </p>
<p>There are a number of Popup output calls, each with a slightly different look (e.g. different button labels). </p>
<p>The list of Popup output functions are </p>
<pre><code>Popup
PopupOk
PopupYesNo
PopupCancel
PopupOkCancel
PopupError
PopupTimed, PopupAutoClose
PopupNoWait, PopupNonBlocking
</code></pre>
<p>The trailing portion of the function name after Popup indicates what buttons are shown. <code>PopupYesNo</code> shows a pair of button with Yes and No on them. <code>PopupCancel</code> has a Cancel button, etc. </p>
<p>While these are "output" windows, they do collect input in the form of buttons. The Popup functions return the button that was clicked. If the Ok button was clicked, then Popup returns the string 'Ok'. If the user clicked the X button to close the window, then the button value returned is <code>None</code>. </p>
<p>The function <code>PopupTimed</code> or <code>PopupAutoClose</code> are popup windows that will automatically close after come period of time. </p>
<p>Here is a quick-reference showing how the Popup calls look. </p>
<pre><code>sg.Popup('Popup') - Shows OK button
sg.PopupOk('PopupOk') - Shows OK button
sg.PopupYesNo('PopupYesNo') - Shows Yes and No buttons
sg.PopupCancel('PopupCancel') - Shows Cancelled button
sg.PopupOKCancel('PopupOKCancel') - Shows OK and Cancel buttons
sg.PopupError('PopupError') - Shows red error button
sg.PopupTimed('PopupTimed') - Automatically closes
sg.PopupAutoClose('PopupAutoClose') - Same as PopupTimed
</code></pre>
<p><img alt="snap0256" src="https://user-images.githubusercontent.com/13696193/44957394-1380ab00-aea0-11e8-98b1-1ab7d7bd5b37.jpg" /> </p>
<p><img alt="snap0257" src="https://user-images.githubusercontent.com/13696193/44957400-167b9b80-aea0-11e8-9d42-2314f24e62de.jpg" /> </p>
<p><img alt="snap0258" src="https://user-images.githubusercontent.com/13696193/44957399-154a6e80-aea0-11e8-9580-e716f839d400.jpg" /> </p>
<p><img alt="snap0259" src="https://user-images.githubusercontent.com/13696193/44957398-14b1d800-aea0-11e8-9e88-c2b36a248447.jpg" /> </p>
<p><img alt="snap0260" src="https://user-images.githubusercontent.com/13696193/44957397-14b1d800-aea0-11e8-950b-6d0b4f33841a.jpg" /> </p>
<p><img alt="snap0261" src="https://user-images.githubusercontent.com/13696193/44957396-14194180-aea0-11e8-8eef-bb2e1193ecfa.jpg" /> </p>
<p><img alt="snap0264" src="https://user-images.githubusercontent.com/13696193/44957595-9e15da00-aea1-11e8-8909-6b6121b74509.jpg" /> </p>
<pre><code>Popup(*args, Variable number of arguments you want to display
button_color=None, Color of buttons (text_color, background_color)
background_color=None, Color of background
text_color=None, Color of text
button_type=POPUP_BUTTONS_OK, Type of button layout
auto_close=False, If True window will automatically close
auto_close_duration=None, Number of seconds for autoclose
non_blocking=False, If True returns immediately
icon=DEFAULT_WINDOW_ICON, Icon to use on the taskbar
line_width=None, Width of lines in characters
font=None, Font to use for characters
no_titlebar=False, If True no titlebar will be shown
grab_anywhere=False, If True can move window by grabbing anywhere
keep_on_top=False, If True window will be on top of other windows
location=(None,None)): (x,y) coordinates to show the window
</code></pre>
<p>The other output Popups are variations on parameters. Usually the button_type parameter is the primary one changed. </p>
<p>The choices for button_type are: </p>
<pre><code>POPUP_BUTTONS_YES_NO
POPUP_BUTTONS_CANCELLED
POPUP_BUTTONS_ERROR
POPUP_BUTTONS_OK_CANCEL
POPUP_BUTTONS_OK
POPUP_BUTTONS_NO_BUTTONS
</code></pre>
<p>Note that you should not call Popup yourself with different button_types. Rely on the Popup function named that sets that value for you. For example PopupYesNo will set the button type to POPUP_BUTTONS_YES_NO for you. </p>
<h4 id="scrolled-output">Scrolled Output</h4>
<p>There is a scrolled version of Popups should you have a lot of information to display. </p>
<pre><code class="python">PopupScrolled(*args, button_color=None, yes_no=False, auto_close=False, auto_close_duration=None, size=(None, None), location=(None, None), title=None, non_blocking=False)
</code></pre>
<p>Typical usage:</p>
<pre><code>sg.PopupScrolled(my_text)
</code></pre>
<p><img alt="scrolledtextbox 2" src="https://user-images.githubusercontent.com/13696193/43667324-712aa0d4-9745-11e8-83a9-a0d0570d0865.jpg" /> </p>
<p>The <code>PopupScrolled</code> will auto-fit the window size to the size of the text. Specify <code>None</code> in the height field of a <code>size</code> parameter to get auto-sized height. </p>
<p>This call will create a scrolled box 80 characters wide and a height dependent upon the number of lines of text. </p>
<p>sg.PopupScrolled(my_text, size=(80, None)) </p>
<p>Note that the default max number of lines before scrolling happens is set to 50. At 50 lines the scrolling will begin. </p>
<p>If <code>non_blocking</code> parameter is set, then the call will not blocking waiting for the user to close the window. Execution will immediately return to the user. Handy when you want to dump out debug info without disrupting the program flow.</p>
<h3 id="popupnowait">PopupNoWait</h3>
<p>The Popup call PopupNoWait or PopupNonBlocking will create a popup window and then immediately return control back to you. All other popup functions will block, waiting for the user to close the popup window. </p>
<p>This function is very handy for when you're <strong>debugging</strong> and want to display something as output but don't want to change the programs's overall timing by blocking. Think of it like a <code>print</code> statement. There are no return values on one of these Popups. </p>
<h2 id="popup-input">Popup Input</h2>
<p>There are Popup calls for single-item inputs. These follow the pattern of <code>Popup</code> followed by <code>Get</code> and then the type of item to get. There are 3 of these input Popups to choose from, each with settings enabling customization. </p>
<ul>
<li><code>PopupGetText</code> - get a single line of text </li>
<li><code>PopupGetFile</code> - get a filename </li>
<li><code>PopupGetFolder</code> - get a folder name </li>
</ul>
<p>Use these Popups instead of making a custom window to get one data value, call the Popup input function to get the item from the user. If you find the parameters are unable to create the kind of window you are looking for, then it's time for you to create your own window. </p>
<h3 id="popupgettext">PopupGetText</h3>
<p>Use this Popup to get a line of text from the user. </p>
<pre><code>PopupGetText(message,The message you wish to display with the input field
default_text='', Text to initially fill into the input field
password_char='', Passwork character if this is a password field
size=(None,None), Size of the window
button_color=None, Color to use for buttons (foreground, background)
background_color=None, Background color for window
text_color=None, Text color for window
icon=DEFAULT_WINDOW_ICON, Icon to display on taskbar
font=None, Font to use for text
no_titlebar=False, If True no titlebar will be shown
grab_anywhere=False, If True can grab anywhere to move the window
keep_on_top=False, If True window will stay on top of other windows
location=(None,None)) Location on screen to display window
</code></pre>
<pre><code>import PySimpleGUI as sg
text = sg.PopupGetText('Title', 'Please input something')
sg.Popup('Results', 'The value returned from PopupGetText', text)
</code></pre>
<p><img alt="popupgettext" src="https://user-images.githubusercontent.com/13696193/44957281-8721b880-ae9e-11e8-98cd-d06369f4187e.jpg" /> </p>
<p><img alt="popup gettext response" src="https://user-images.githubusercontent.com/13696193/44957282-8721b880-ae9e-11e8-84ae-dc8bb30504a0.jpg" /> </p>
<h3 id="popupgetfile">PopupGetFile</h3>
<p>Gets a filename from the user. There are options to configure the type of dialog box to show. Normally an "Open File" dialog box is shown </p>
<pre><code>PopupGetFile(message, Message to show in the window
default_path='', Path browsing should start from
default_extension='', Which filetype is the default
save_as=False, Determines which dialog box stype to show
file_types=(("ALL Files", "*.*"),), Which filetypes are displayed
no_window=False, if True no window is displayed except the dialog box
size=(None,None), Size of window
button_color=None, Color of buttons
background_color=None, Color of window background
text_color=None, Color of text in window
icon=DEFAULT_WINDOW_ICON, Icon to show on taskbar
font=None, Font to use
no_titlebar=False, If True does not display a titlebar
grab_anywhere=False, if True can grab window anywhere to move it
keep_on_top=False, if True window will be on top of others
location=(None,None)) Location on screen to show window
</code></pre>
<p>If configured as an Open File Popup then (save_as is not True) the dialog box will look like this </p>
<p><img alt="snag-0060" src="https://user-images.githubusercontent.com/13696193/46761050-9831c680-cca1-11e8-8de9-68b15efe2c46.jpg" /> </p>
<p>If you set the parameter save_As to True, then the dialog box looks like this: </p>
<p><img alt="snag-0061" src="https://user-images.githubusercontent.com/13696193/46761330-2b6afc00-cca2-11e8-953b-f6b5c5ce57f5.jpg" /> </p>
<p>If you choose a filename that already exists, you'll get a warning popup box asking if it's OK. You can also specify a file that doesn't exist. With an "Open" dialog box you cannot choose a non-existing file. </p>
<p>A typical call produces this window. </p>
<pre><code>text = sg.PopupGetFile('Please enter a file name')
sg.Popup('Results', 'The value returned from PopupGetFile', text)
</code></pre>
<p><img alt="popupgetfile" src="https://user-images.githubusercontent.com/13696193/44957857-2fd31680-aea5-11e8-8eb7-f6b91c202cc8.jpg" /> </p>
<h3 id="popupgetfolder">PopupGetFolder</h3>
<p>The window created to get a folder name looks the same as the get a file name. The difference is in what the browse button does. <code>PopupGetFile</code> shows an Open File dialog box while <code>PopupGetFolder</code> shows an Open Folder dialog box. </p>
<pre><code>PopupGetFolder(message, Message to display in window
default_path='', Path to start browsing
no_window=False, If True no window will be shown
size=(None,None), Size of window
button_color=None, Color of buttons
background_color=None, Background color of window
text_color=None, Color of window text
icon=DEFAULT_WINDOW_ICON, Icon to show on taskbar
font=None, Font to use for window
no_titlebar=False, If True no titlebar will be shown
grab_anywhere=False, If True can grab anywhere on window to move
keep_on_top=False, If True window will be on top
location=(None, None)) Location on screen to create window
</code></pre>
<p>This is a typpical call </p>
<pre><code>text = sg.PopupGetFolder('Please enter a folder name')
sg.Popup('Results', 'The value returned from PopupGetFolder', text)
</code></pre>
<p><img alt="popupgetfolder" src="https://user-images.githubusercontent.com/13696193/44957861-45484080-aea5-11e8-926c-cf607a45251c.jpg" /> </p>
<h3 id="popupanimated">PopupAnimated</h3>
<p><img alt="ring" src="https://user-images.githubusercontent.com/13696193/51296743-6ee4ad00-19eb-11e9-91f5-cd8086ad1b50.gif" /></p>
<p>The animated Popup enables you to easily display a "loading" style animation specified through a GIF file that is either stored in a file or a base64 variable.</p>
<pre><code class="python">def PopupAnimated(image_source,
message=None,
background_color=None,
text_color=None,
font=None,
no_titlebar=True,
grab_anywhere=True,
keep_on_top=True,
location=(None, None),
alpha_channel=.8,
time_between_frames=0)
</code></pre>
<p>image_source - The GIF file specified as a string filename or a base64 variable
message - optional text message to be displayed under the animation
background_color - the background color to use for the window and all of the other parts of the window
text_color - color to use for optional text
font - font to use for the optional text
no_titlebar - no titlebar window setting
location - location to show the window
alpha_channel - alpha channel to use for the window
time_between_frames - amount of time in milliseconds to use between frames</p>
<p><strong><em>To close animated popups</em></strong>, call PopupAnimated with <code>image_source=None</code>. This will close all of the currently open PopupAnimated windows.</p>
<h1 id="progress-meters">Progress Meters!</h1>
<p>We all have loops in our code. 'Isn't it joyful waiting, watching a counter scrolling past in a text window? How about one line of code to get a progress meter, that contains statistics about your code? </p>
<pre><code>OneLineProgressMeter(title,
current_value,
max_value,
key,
*args,
orientation=None,
bar_color=DEFAULT_PROGRESS_BAR_COLOR,
button_color=None,
size=DEFAULT_PROGRESS_BAR_SIZE,
border_width=DEFAULT_PROGRESS_BAR_BORDER_WIDTH):
</code></pre>
<p>Here's the one-line Progress Meter in action! </p>
<pre><code>for i in range(1,10000):
sg.OneLineProgressMeter('My Meter', i+1, 10000, 'key','Optional message')
</code></pre>
<p>That line of code resulted in this window popping up and updating. </p>
<p><img alt="preogress meter" src="https://user-images.githubusercontent.com/13696193/43667625-d47da702-9746-11e8-91e6-e5177883abae.jpg" /> </p>
<p>A meter AND fun statistics to watch while your machine grinds away, all for the price of 1 line of code. <br />
With a little trickery you can provide a way to break out of your loop using the Progress Meter window. The cancel button results in a <code>False</code> return value from <code>OneLineProgressMeter</code>. It normally returns <code>True</code>. </p>
<p><strong><em>Be sure and add one to your loop counter</em></strong> so that your counter goes from 1 to the max value. If you do not add one, your counter will never hit the max value. Instead it will go from 0 to max-1. </p>
<h1 id="debug-output">Debug Output</h1>
<p>Another call in the 'Easy' families of APIs is <code>EasyPrint</code>. It will output to a debug window. If the debug window isn't open, then the first call will open it. No need to do anything but stick a 'print' call in your code. You can even replace your 'print' calls with calls to EasyPrint by simply sticking the statement </p>
<pre><code>print = sg.EasyPrint
</code></pre>
<p>at the top of your code. </p>
<p>There are a number of names for the same EasyPrint function. <code>Print</code> is one of the better ones to use as it's easy to remember. It is simply <code>print</code> with a capital P. </p>
<pre><code>import PySimpleGUI as sg
for i in range(100):
sg.Print(i)
</code></pre>
<p><img alt="snap0125" src="https://user-images.githubusercontent.com/13696193/43114979-a696189e-8ecf-11e8-83c7-473fcf0ccc66.jpg" /> </p>
<p>Or if you didn't want to change your code: </p>
<pre><code>import PySimpleGUI as sg
print=sg.Print
for i in range(100):
print(i)
</code></pre>
<p>Just like the standard print call, <code>EasyPrint</code> supports the <code>sep</code> and <code>end</code> keyword arguments. Other names that can be used to call <code>EasyPrint</code> include <code>Print</code>, <code>eprint</code>, If you want to close the window, call the function <code>EasyPrintClose</code>. </p>
<p>You can change the size of the debug window using the <code>SetOptions</code> call with the <code>debug_win_size</code> parameter. </p>
<p>There is an option to tell PySimpleGUI to reroute all of your stdout and stderr output to this window. To do so call EasyPrint with the parameter <code>do_not_reroute_stdout</code> set to True. After calling it once with this parameter set to True, all future calls to a normal<code>print</code> will go to the debug window.</p>
<p>If you close the debug window it will re-open the next time you Print to it.</p>
<hr />
<h1 id="custom-window-api-calls-your-first-window">Custom window API Calls (Your First window)</h1>
<p>This is the FUN part of the programming of this GUI. In order to really get the most out of the API, you should be using an IDE that supports auto complete or will show you the definition of the function. This will make customizing go smoother. </p>
<p>This first section on custom windows is for your typical, blocking, non-persistent window. By this I mean, when you "show" the window, the function will not return until the user has clicked a button or closed the window. When this happens, the window will be automatically closed. </p>
<p>Two other types of windows exist. <br />
1. Persistent window - rather than closing on button clicks, the show window function returns and the window continues to be visible. This is good for applications like a chat window. <br />
2. Asynchronous window - the trickiest of the lot. Great care must be exercised. Examples are an MP3 player or status dashboard. Async windows are updated (refreshed) on a periodic basis. </p>
<p>It's both not enjoyable nor helpful to immediately jump into tweaking each and every little thing available to you. </p>
<h2 id="the-window-designer">The window Designer</h2>
<p>The good news to newcomers to GUI programming is that PySimpleGUI has a window designer. Better yet, the window designer requires no training, no downloads, and everyone knows how to use it. </p>
<p><img alt="gui0_1" src="https://user-images.githubusercontent.com/13696193/44159598-e2257400-a085-11e8-9b02-343e72cc75c3.JPG" /> </p>
<p>It's a manual process, but if you follow the instructions, it will take only a minute to do and the result will be a nice looking GUI. The steps you'll take are: <br />
1. Sketch your GUI on paper <br />
2. Divide your GUI up into rows <br />
3. Label each Element with the Element name <br />
4. Write your Python code using the labels as pseudo-code </p>
<p>Let's take a couple of examples. </p>
<p><strong>Enter a number</strong>.... Popular beginner programs are often based on a game or logic puzzle that requires the user to enter something, like a number. The "high-low" answer game comes to mind where you try to guess the number based on high or low tips. </p>
<p><strong>Step 1- Sketch the GUI</strong> <br />
<img alt="gui1_1" src="https://user-images.githubusercontent.com/13696193/44160127-6a584900-a087-11e8-8fec-09099a8e16f6.JPG" /> </p>
<p><strong>Step 2 - Divide into rows</strong> </p>
<p><img alt="gui2_1" src="https://user-images.githubusercontent.com/13696193/44160128-6a584900-a087-11e8-9973-af866fb94c56.JPG" /> </p>
<p>Step 3 - Label elements </p>
<p><img alt="gui6_1" src="https://user-images.githubusercontent.com/13696193/44160116-64626800-a087-11e8-8b57-671c0461b508.JPG" /> </p>
<p>Step 4 - Write the code <br />
The code we're writing is the layout of the GUI itself. This tutorial only focuses on getting the window code written, not the stuff to display it, get results. </p>
<p>We have only 1 element on the first row, some text. Rows are written as a "list of elements", so we'll need [ ] to make a list. Here's the code for row 1 </p>
<pre><code>[ sg.Text('Enter a number') ]
</code></pre>
<p>Row 2 has 1 elements, an input field. </p>
<pre><code>[ sg.Input() ]
</code></pre>
<p>Row 3 has an OK button </p>
<pre><code>[ sg.OK() ]
</code></pre>
<p>Now that we've got the 3 rows defined, they are put into a list that represents the entire window. </p>
<pre><code>layout = [ [sg.Text('Enter a Number')],
[sg.Input()],
[sg.OK()] ]
</code></pre>
<p>Finally we can put it all together into a program that will display our window. </p>
<pre><code>import PySimpleGUI as sg
layout = [[sg.Text('Enter a Number')],
[sg.Input()],
[sg.OK()] ]
event, (number,) = sg.Window('Enter a number example').Layout(layout).Read()
sg.Popup(event, number)
</code></pre>
<h3 id="example-2-get-a-filename">Example 2 - Get a filename</h3>
<p>Let's say you've got a utility you've written that operates on some input file and you're ready to use a GUI to enter than filename rather than the command line. Follow the same steps as the previous example - draw your window on paper, break it up into rows, label the elements. </p>
<p><img alt="gui4_1" src="https://user-images.githubusercontent.com/13696193/44160132-6a584900-a087-11e8-862f-7d791a67ee5d.JPG" /> <br />
<img alt="gui5_1" src="https://user-images.githubusercontent.com/13696193/44160133-6af0df80-a087-11e8-9dec-bb4d4c59393d.JPG" /> </p>
<p>Writing the code for this one is just as straightforward. There is one tricky thing, that browse for a file button. Thankfully PySimpleGUI takes care of associating it with the input field next to it. As a result, the code looks almost exactly like the window on the paper. </p>
<pre><code>import PySimpleGUI as sg
layout = [[sg.Text('Filename')],
[sg.Input(), sg.FileBrowse()],
[sg.OK(), sg.Cancel()] ]
event, (number,) = sg.Window('Get filename example').Layout(layout).Read()
sg.Popup(event, number)
</code></pre>
<p>Read on for detailed instructions on the calls that show the window and return your results. </p>
<h1 id="copy-these-design-patterns">Copy these design patterns!</h1>
<p>All of your PySimpleGUI programs will utilize one of these 2 design patterns depending on the type of window you're implementing. </p>
<h2 id="pattern-1-one-shot-window-read-into-list-or-dictionary-the-most-common-pattern">Pattern 1 - "One-shot Window" - Read into list or dictionary (<strong>The Most Common</strong> Pattern)</h2>
<p>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 closes.</p>
<p>It's unusual to assign the values returned from the read call directly into user variables. Usually the variables are grouped together into a list or dictionary of multiple return values. </p>
<pre><code class="python">import PySimpleGUI as sg
window_rows = [[sg.Text('SHA-1 and SHA-256 Hashes for the file')],
[sg.InputText(), sg.FileBrowse()],
[sg.Submit(), sg.Cancel()]]
window = sg.Window('SHA-1 & 256 Hash').Layout(window_rows)
event, values = window.Read()
window.Close()
source_filename = values[0]
</code></pre>
<h2 id="pattern-2-a-persistent-window-multiple-reads-using-an-event-loop">Pattern 2 A - Persistent window (multiple reads using an event loop)</h2>
<p>Some of the more advanced 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 output information to the user and gather input data. </p>
<p>This code will present a window and will print values until the user clicks the exit button or closes window using an X. </p>
<pre><code class="python">import PySimpleGUI as sg
layout = [[sg.Text('Persistent window')],
[sg.Input(do_not_clear=True)],
[sg.Button('Read'), sg.Exit()]]
window = sg.Window('Window that stays open').Layout(layout)
while True:
event, values = window.Read()
if event is None or event == 'Exit':
break
print(event, values)
window.Close()
</code></pre>
<h2 id="pattern-2-b-persistent-window-multiple-reads-using-an-event-loop-updates-data-in-window">Pattern 2 B - Persistent window (multiple reads using an event loop + updates data in window)</h2>
<p>This is a slightly more complex, but maybe 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 will give you a big jump-start.</p>
<p>Do not worry yet what all of these statements mean. Just copy it so you can begin to play with it, make some changes. Experiment to see how thing work.</p>
<p>A final note... the parameter <code>do_not_clear</code> in the input call determines the action of the input field after a button event. If this value is True, the input value remains visible following button clicks. If False, then the input field is CLEARED of whatever was input. If you are building a "Form" type of window with data entry, you likely want False, the default setting (you can remove the parameter completely).</p>
<pre><code class="python">import sys
if sys.version_info[0] >= 3:
import PySimpleGUI as sg
else:
import PySimpleGUI27 as sg
layout = [[sg.Text('Your typed chars appear here:'), sg.Text('', key='_OUTPUT_') ],
[sg.Input(do_not_clear=True, key='_IN_')],
[sg.Button('Show'), sg.Button('Exit')]]
window = sg.Window('Window Title').Layout(layout)
while True: # Event Loop
event, values = window.Read()
print(event, values)
if event is None or event == 'Exit':
break
if event == 'Show':
# change the "output" element to be the value of "input" element
window.FindElement('_OUTPUT_').Update(values['_IN_'])
window.Close()
</code></pre>
<h2 id="how-gui-programming-in-python-should-look-at-least-for-beginners">How GUI Programming in Python Should Look? At least for beginners ?</h2>
<p>While one goal was making it simple to create a GUI another just as important goal was to do it in a Pythonic manner. Whether it achieved these goals is debatable, but it was an attempt just the same. </p>
<p>The key to custom windows in PySimpleGUI is to view windows as ROWS of GUI Elements. Each row is specified as a list of these Elements. Put the rows together and you've got a window. This means the GUI is defined as a series of Lists, a Pythonic way of looking at things. </p>
<p>Let's dissect this little program <br />
```python <br />
import PySimpleGUI as sg </p>
<pre><code>layout = [[sg.Text('Rename files or folders')],
[sg.Text('Source for Folders', size=(15, 1)), sg.InputText(), sg.FolderBrowse()],
[sg.Text('Source for Files ', size=(15, 1)), sg.InputText(), sg.FolderBrowse()],
[sg.Submit(), sg.Cancel()]]
window = sg.Window('Rename Files or Folders')
event, values = window.Layout(layout).Read()
</code></pre>
<p>``` </p>
<p><img alt="snap0131" src="https://user-images.githubusercontent.com/13696193/43417007-df6d8408-9407-11e8-9986-30f0415f08a5.jpg" /> </p>
<p>Let's agree the window has 4 rows. </p>
<p>The first row only has <strong>text</strong> that reads <code>Rename files or folders</code> </p>
<p>The second row has 3 elements in it. First the <strong>text</strong> <code>Source for Folders</code>, then an <strong>input</strong> field, then a <strong>browse</strong> button. </p>
<p>Now let's look at how those 2 rows and the other two row from Python code: </p>
<pre><code>layout = [[sg.Text('Rename files or folders')],
[sg.Text('Source for Folders', size=(15, 1)), sg.InputText(), sg.FolderBrowse()],
[sg.Text('Source for Files ', size=(15, 1)), sg.InputText(), sg.FolderBrowse()],
[sg.Submit(), sg.Cancel()]]
</code></pre>
<p>See how the source code mirrors the layout? You simply make lists for each row, then submit that table to PySimpleGUI to show and get values from. </p>
<p>And what about those return values? Most people simply want to show a window, get the input values and do something with them. So why break up the code into button callbacks, etc, when I simply want my window's input values to be given to me. </p>
<p>For return values the window is scanned from top to bottom, left to right. Each field that's an input field will occupy a spot in the return values. </p>
<p>In our example window, there are 2 fields, so the return values from this window will be a list with 2 values in it. <br />
<code>python
event, values = window.Read()
folder_path, file_path = values</code> </p>
<p>In one statement we both show the window and read the user's inputs. In the next the <em>list</em> of return values is split into individual variables <code>folder_path</code> and <code>file_path</code>. </p>
<p>Isn't this what a Python programmer looking for a GUI wants? Something easy to work with to get the values and move on to the rest of the program, where the real action is taking place. Why write pages of GUI code when the same layout can be achieved with PySimpleGUI in 3 or 4 lines of code. 4 lines or 40? Most would choose 4. </p>
<h2 id="return-values">Return values</h2>
<p>As of version 2.8 there are 2 forms of return values, list and dictionary. </p>
<h3 id="two-return-values">Two Return Values</h3>
<p>All Window Read calls return 2 values. By convention a read statement is written: </p>
<pre><code class="python">event, values = window.Read()
</code></pre>
<p>You don't HAVE to write your reads in this way. You can name your variables however you want. But if you want to code them in a way that other programmers using PySimpleGUI are used to, then use these statements. </p>
<h2 id="events">Events</h2>
<p>The first parameter <code>event</code> describes <strong>why</strong> the read completed. Events are one of these: </p>
<p>For all Windows: </p>
<ul>
<li>Button click </li>
<li>Window closed using X </li>
</ul>
<p>For Windows that have specifically enabled these. Please see the appropriate section in this document to learn about how to enable these and what the event return values are. </p>
<ul>
<li>Keyboard key press </li>
<li>Mouse wheel up/down </li>