Form Designer, auto packer, new color options, new predefined look and feel
Some really cool features for changing how things look. Directions on how to use the new PySimpleGUI Form Designer
This commit is contained in:
parent
6a6ed02a02
commit
15cd0ed7f3
183
readme.md
183
readme.md
|
@ -144,7 +144,6 @@ You will see a number of different styles of buttons, data entry fields, etc, in
|
|||
- Return values are a list of button presses and input values.
|
||||
- Return values can also be represented as a dictionary
|
||||
|
||||
It's stunning that after so many years Python still hasn't put forth a GUI framework that truly fits the language's basic data structures, especially lists. It's hard to argue with the success to be had in quickly building GUI applications using this package's syntax.
|
||||
|
||||
-----
|
||||
## Getting Started with PySimpleGUI
|
||||
|
@ -380,7 +379,89 @@ Two other types of forms exist.
|
|||
1. Persistent form - rather than closing on button clicks, the show form function returns and the form continues to be visible. This is good for applications like a chat window.
|
||||
2. Asynchronous form - the trickiest of the lot. Great care must be exercised. Examples are an MP3 player or status dashboard. Async forms are updated (refreshed) on a periodic basis.
|
||||
|
||||
It's both not enjoyable nor helpful to immediately jump into tweaking each and every little thing available to you. Let's start with a basic Browse for a file and do something with it.
|
||||
It's both not enjoyable nor helpful to immediately jump into tweaking each and every little thing available to you.
|
||||
|
||||
## The Form Designer
|
||||
The good news to newcomers to GUI programming is that PySimpleGUI has a form designer. Better yet, the form designer requires no training and everyone knows how to use it.
|
||||
|
||||
![gui0_1](https://user-images.githubusercontent.com/13696193/44159598-e2257400-a085-11e8-9b02-343e72cc75c3.JPG)
|
||||
|
||||
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:
|
||||
1. Sketch your GUI on paper
|
||||
2. Divide your GUI up into rows
|
||||
3. Label each Element with the Element name
|
||||
4. Write your Python code using the labels as pseudo-code
|
||||
|
||||
Let's take a couple of examples.
|
||||
|
||||
**Enter a number**.... 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.
|
||||
|
||||
**Step 1- Sketch the GUI**
|
||||
![gui1_1](https://user-images.githubusercontent.com/13696193/44160127-6a584900-a087-11e8-8fec-09099a8e16f6.JPG)
|
||||
|
||||
**Step 2 - Divide into rows**
|
||||
|
||||
![gui2_1](https://user-images.githubusercontent.com/13696193/44160128-6a584900-a087-11e8-9973-af866fb94c56.JPG)
|
||||
|
||||
Step 3 - Label elements
|
||||
|
||||
![gui6_1](https://user-images.githubusercontent.com/13696193/44160116-64626800-a087-11e8-8b57-671c0461b508.JPG)
|
||||
|
||||
Step 4 - Write the code
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
[ sg.Text('Enter a number') ]
|
||||
|
||||
Row 2 has 1 elements, an input field.
|
||||
|
||||
[ sg.Input() ]
|
||||
Row 3 has an OK button
|
||||
|
||||
[ sg.OK() ]
|
||||
|
||||
Now that we've got the 3 rows defined, they are put into a list that represents the entire window.
|
||||
|
||||
layout = [ [sg.Text('Enter a Number')],
|
||||
[sg.Input()],
|
||||
[sg.OK()] ]
|
||||
|
||||
Finally we can put it all together into a program that will display our window.
|
||||
|
||||
import PySimpleGUI as sg
|
||||
|
||||
layout = [[sg.Text('Enter a Number')],
|
||||
[sg.Input()],
|
||||
[sg.OK()] ]
|
||||
|
||||
button, (number,) = sg.FlexForm('Enter a number example').LayoutAndRead(layout)
|
||||
|
||||
sg.MsgBox(button, number)
|
||||
|
||||
### Example 2 - Get a filename
|
||||
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 form on paper, break it up into rows, label the elements.
|
||||
|
||||
![gui4_1](https://user-images.githubusercontent.com/13696193/44160132-6a584900-a087-11e8-862f-7d791a67ee5d.JPG)
|
||||
![gui5_1](https://user-images.githubusercontent.com/13696193/44160133-6af0df80-a087-11e8-9dec-bb4d4c59393d.JPG)
|
||||
|
||||
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 form on the paper.
|
||||
|
||||
import PySimpleGUI as sg
|
||||
|
||||
layout = [[sg.Text('Filename')],
|
||||
[sg.Input(), sg.FileBrowse()],
|
||||
[sg.OK(), sg.Cancel()] ]
|
||||
|
||||
button, (number,) = sg.FlexForm('Get filename example').LayoutAndRead(layout)
|
||||
|
||||
sg.MsgBox(button, number)
|
||||
|
||||
|
||||
Read on for detailed instructions on the calls that show the form and return your results.
|
||||
|
||||
|
||||
|
||||
# Copy these design patterns!
|
||||
## Pattern 1 - With Context Manager
|
||||
|
||||
|
@ -451,6 +532,24 @@ In the statement that shows and reads the form, the two input fields are directl
|
|||
Isn't this what almost every 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 tkinter code when the same layout can be achieved with PySimpleGUI in 3 or 4 lines of code. 4 lines or 40? I chose 4.
|
||||
|
||||
|
||||
|
||||
|
||||
### The Auto-Packer
|
||||
|
||||
Once you've laid out your elements into, it's the job of the Auto-Packer to place your elements into a window frame.
|
||||
|
||||
The layout of custom GUIs is made trivial by the use of the Auto-Packer. GUI frameworks often use a grid system and sometimes have a "pack" function that's used to place widgets into a window. It's almost always a confusing exercise to use them.
|
||||
|
||||
PySimpleGUI uses a "row by row" approach to building GUIs. When you were to sketch your GUI out on a sheet of paper and then draw horizontal lines across the page under each widget then you would have a several "rows" of widgets.
|
||||
|
||||
For each row in your GUI, you will have a list of elements. In Python this list is a simple Python list. An entire GUI window is a list of rows, one after another.
|
||||
|
||||
This is how your GUI is created, one row at a time, with one row stacked on top of another. This visual form of coding makes GUI creation go so much quicker.
|
||||
|
||||
layout = [ [ Row 1 Elements],
|
||||
[ Row 2 Elements] ]
|
||||
|
||||
|
||||
### Laying out your form
|
||||
Your form is a 2 dimensional list in Python. The first dimension are rows, the second is a list of Elements for each row. The first thing you want to do is layout your form on paper.
|
||||
|
||||
|
@ -1247,24 +1346,27 @@ Let's have some fun customizing! Make PySimpleGUI look the way you want it to l
|
|||
auto_size_buttons=None
|
||||
font=None
|
||||
border_width=None
|
||||
slider_border_width=None
|
||||
slider_relief=None
|
||||
slider_orientation=None
|
||||
autoclose_time=None
|
||||
message_box_line_width=None
|
||||
progress_meter_border_depth=None
|
||||
progress_meter_style=None
|
||||
progress_meter_relief=None
|
||||
progress_meter_color=None
|
||||
progress_meter_size=None
|
||||
text_justification=None
|
||||
background_color=None
|
||||
element_background_color=None
|
||||
text_element_background_color=None
|
||||
input_elements_background_color=None
|
||||
scrollbar_color=None, text_color=None
|
||||
debug_win_size=(None,None)
|
||||
window_location=(None,None)
|
||||
slider_border_width=None
|
||||
slider_relief=None
|
||||
slider_orientation=None
|
||||
autoclose_time=None
|
||||
message_box_line_width=None
|
||||
progress_meter_border_depth=None
|
||||
progress_meter_style=None
|
||||
progress_meter_relief=None
|
||||
progress_meter_color=None
|
||||
progress_meter_size=None
|
||||
text_justification=None
|
||||
text_color=None
|
||||
background_color=None
|
||||
element_background_color=None
|
||||
text_element_background_color=None
|
||||
input_elements_background_color=None
|
||||
element_text_color=None
|
||||
input_text_color=None
|
||||
scrollbar_color=None, text_color=None
|
||||
debug_win_size=(None,None)
|
||||
window_location=(None,None)
|
||||
|
||||
Explanation of parameters
|
||||
|
||||
|
@ -1291,6 +1393,8 @@ Explanation of parameters
|
|||
element_background_color - Background color of the elements
|
||||
text_element_background_color - Text element background color
|
||||
input_elements_background_color - Input fields background color
|
||||
element_text_color - Text color of elements that have text, like Radio Buttons
|
||||
input_text_color - Color of the text that you type in
|
||||
scrollbar_color - Color for scrollbars (may not always work)
|
||||
text_color - Text element default text color
|
||||
text_justification - justification to use on Text Elements. Values are strings - 'left', 'right', 'center'
|
||||
|
@ -1315,7 +1419,7 @@ When do you use a non-blocking form? A couple of examples are
|
|||
* Progress Meters - when you want to make your own progress meters
|
||||
* Output using print to a scrolled text element. Good for debugging.
|
||||
|
||||
Word of warning... version 2.2, the currently released, and upcoming version 2.3 differ in the return code for the `ReadNonBlocking` call. Previously the function returned 2 values, except when the form is closed using the "X" which returned a single value of `None`. The *new* way is that `ReadNonBlocking` always returns 2 values. If the user closed the form with the "X" then the return values will be None, None. You will want to key off the second value to catch this case.
|
||||
Word of warning... starting with version 2.2 there is a change in the return values from the`ReadNonBlocking` call. Previously the function returned 2 values, except when the form is closed using the "X" which returned a single value of `None`. The *new* way is that `ReadNonBlocking` always returns 2 values. If the user closed the form with the "X" then the return values will be None, None. You will want to key off the second value to catch this case.
|
||||
The proper code to check if the user has exited the form will be a polling-loop that looks something like this:
|
||||
|
||||
while True:
|
||||
|
@ -1394,13 +1498,19 @@ That's it... this example follows the async design pattern well.
|
|||
## Sample Applications
|
||||
Use the example programs as a starting basis for your GUI. Copy, paste, modify and run! The demo files are:
|
||||
|
||||
`Demo Recipes.py` - Sample forms for all major form types and situations. This is the place to get your code template from. Includes asynchronous forms, etc.
|
||||
`Demo_Recipes.py` - Sample forms for all major form types and situations. This is the place to get your code template from. Includes asynchronous forms, etc. Start here!
|
||||
|
||||
`Demo DisplayHash1and256.py` - Demonstrates using High Level API calls to get a filename
|
||||
`Demo_Compare_Files` - Takes 2 filenames as input. Does a byte for byte compare and returns the results.
|
||||
|
||||
`Demo DupliucateFileFinder.py` - Demonstrates High Level API to get a folder & Easy Progress Meter to show progress of the file scanning
|
||||
`Demo_Dictionary` - Simple form demonstrating how return values in dictionary form work.
|
||||
|
||||
`Demo HowDoI.py` - An amazing little application. Acts as a front-end to HowDoI. This one program could forever change how you code. It does searches on Stack Overflow and returns the CODE found in the best answer for your query. If anyone wants to help me package this application up, I could use a hand.
|
||||
`Demo_DisplayHash1and256` - Presents 3 methods of gathering the same user input using both high-level APIs and lower-level.
|
||||
|
||||
Demo_Func_Callback_Simulation - Shows how callback functions can be simulated. This is particularly good for the Raspberry Pi and other embedded type applications.
|
||||
|
||||
`Demo_DuplicateFileFinder.py` - Demonstrates High Level API to get a folder & Easy Progress Meter to show progress of the file scanning
|
||||
|
||||
`Demo_HowDoI.py` - An amazing little application. Acts as a front-end to HowDoI. This one program **could forever change how you code**. It does searches on Stack Overflow and returns the CODE found in the best answer for your query. If anyone wants to help me package this application up and release as a standalone application, then speak up on the GitHub!
|
||||
|
||||
## Fun Stuff
|
||||
Here are some things to try if you're bored or want to further customize
|
||||
|
@ -1417,6 +1527,22 @@ This will turn all of your print statements into prints that display in a window
|
|||
|
||||
**Look and Feel**
|
||||
Dial in the look and feel that you like with the `SetOptions` function. You can change all of the defaults in one function call. One line of code to customize the entire GUI.
|
||||
Or beginning in version 2.9 you can choose from a look and feel using pre-defined color schemes. Call ChangeLookAndFeel with a description string.
|
||||
|
||||
sg.ChangeLookAndFeel('GreenTan')
|
||||
|
||||
Valid values for the description string are:
|
||||
|
||||
GreenTan
|
||||
LightGreen
|
||||
BluePurple
|
||||
Purple
|
||||
BlueMono
|
||||
GreenMono
|
||||
BrownBlue
|
||||
BrightColors
|
||||
TealMono
|
||||
|
||||
|
||||
**ObjToString**
|
||||
Ever wanted to easily display an objects contents easily? Use ObjToString to get a nicely formatted recursive walk of your objects.
|
||||
|
@ -1470,7 +1596,7 @@ A MikeTheWatchGuy production... entirely responsible for this code.... unless it
|
|||
| 2.6.0 | July 27, 2018 - auto_size_button setting. License changed to LGPL 3+
|
||||
| 2.7.0 | July 30, 2018 - realtime buttons, window_location default setting
|
||||
| 2.8.0 | Aug 9, 2018 - New None default option for Checkbox element, text color option for all elements, return values as a dictionary, setting focus, binding return key
|
||||
| 2.9.0 | Aug XX,2018 - Screen flash fix, `do_not_clear` input field option, `autosize_text` defaults to `True` now, return values as ordered dict,
|
||||
| 2.9.0 | Aug XX,2018 - Screen flash fix, `do_not_clear` input field option, `autosize_text` defaults to `True` now, return values as ordered dict, removed text target from progress bar, rework of return values and initial return values, removed legacy Form.Refresh() method (replaced by Form.ReadNonBlockingForm()), COLUMN elements!!,
|
||||
|
||||
|
||||
### Release Notes
|
||||
|
@ -1522,6 +1648,9 @@ In Python, functions behave just like object. When you're placing a Text Element
|
|||
**Lists**
|
||||
It seemed quite natural to use Python's powerful list constructs when possible. The form is specified as a series of lists. Each "row" of the GUI is represented as a list of Elements. When the form read returns the results to the user, all of the results are presented as a single list. This makes reading a form's values super-simple to do in a single line of Python code.
|
||||
|
||||
**Dictionaries**
|
||||
Want to view your form's results as a dictionary instead of a list... no problem, just use the `key` keyword on your elements. For complex forms with a lot of values that need to be changed frequently, this is by far the best way of consuming the results.
|
||||
|
||||
|
||||
## Authors
|
||||
MikeTheWatchGuy
|
||||
|
@ -1558,4 +1687,4 @@ For Python questions, I simply start my query with 'Python'. Let's say you forg
|
|||
|
||||
In the hands of a competent programmer, this tool is **amazing**. It's a must-try kind of program that has completely changed my programming process. I'm not afraid of asking for help! You just have to be smart about using what you find.
|
||||
|
||||
The PySimpleGUI window that the results are shown in is an 'input' field which means you can copy and paste the results right into your code.
|
||||
The PySimpleGUI window that the results are shown in is an 'input' field which means you can copy and paste the results right into your code.
|
||||
|
|
Loading…
Reference in New Issue