An Introduction to Python Gooey
This is a demonstration of how to add a simple graphical user interface (GUI) to your python application using the Gooey library.
I use python for ad hoc automation and data analysis projects, and Gooey is a very easy way to enhance my applications with a GUI to accept user inputs and print feedback to users who may not be familiar with a command line interface.
This demo is written using python 3.10 on Windows; however, other python versions should work just as well. The commands may be slightly different on other operating systems.
1. Set up a project and install Gooey
While optional, I use virtual environments for all of my projects in order to control libraries available to each project. Create a project folder and click in the address bar to open a command prompt at the same location.
Create a virtual environment: python -m venv venv
Activate the virtual environment: venv\Scripts\activate
Install Gooey: pip install gooey
2. Hello World Gooey
It only takes a few lines of code to create a GUI.
# app.py
from gooey import Gooey, GooeyParser
@Gooey()
def main():
parser = GooeyParser()
args = parser.parse_args()
if __name__ == "__main__":
main()
And here’s the result when running app.py:
3. Collecting user input
Gooey collects user input in the form of arguments. Here is a form with four example fields.
# app.py
from gooey import Gooey, GooeyParser
def do_stuff(args=None):
print(f"The file you chose is {args.file_path}")
print(f"The folder you chose is {args.directory_path}")
print(f"The first checkbox value is {args.checkbox_1}")
print(f"The second checkbox value is {args.checkbox_2}")
if args.checkbox_1:
print(f"The first checkbox is unchecked")
else:
print(f"The first checkbox is checked")
if args.checkbox_2:
print(f"The second checkbox is checked")
else:
print(f"The second checkbox is unchecked")
print("All done!")
@Gooey(
program_name="Gooey Demo",
program_description="Demonstrate Gooey features",
default_size=(600, 500),
)
def main():
parser = GooeyParser()
gp = parser.add_argument_group("Group 1")
gp.add_argument(
"-a",
"--file_path",
metavar="File Chooser",
help="Choose a .txt file",
widget="FileChooser",
gooey_options=dict(wildcard="Text (.txt) | *.txt"),
)
gp.add_argument(
"-b",
"--directory_path",
metavar="Directory Chooser",
help="Choose a folder",
widget="DirChooser",
)
gp = parser.add_argument_group("Group 2")
gp.add_argument(
"-c",
"--checkbox_1",
metavar="Checkbox 1",
help="Checkbox that is checked by default",
widget="CheckBox",
action="store_false",
default=True,
)
gp.add_argument(
"-d",
"--checkbox_2",
metavar="Checkbox 2",
help="Checkbox that is unchecked by default",
widget="CheckBox",
action="store_true",
default=False,
)
args = parser.parse_args()
do_stuff(args)
if __name__ == "__main__":
main()
After clicking start, the following window stays open while the script is running. I did not select a file or folder path (returned None as path) or check/uncheck any checkboxes.
I just love how simple it is to create a functionable GUI with this library!
4. Things that are not intuitive
There are a few basic things that took me awhile to figure out with Gooey — hence the motivation for this post. I can’t explain these in depth as I’m not a python pro, but here are a few things I’ve learned.
Gooey is a decorator and needs to be placed inside a function, ideally the main function. It won’t work outside of a function.
Controls can be grouped using the parser.add_argument_group()
function. At least one group is required for Gooey to work, and multiple groups can be used to organized controls.
Arguments can be fussy. Each argument needs a unique identifier (prefixed with a single dash) and a name (prefixed with two dashes). These must have the correct prefix and they must be unique — otherwise these words are meaningless. Example:
gp.add_argument(
"-a",
"--file_path",
metavar="File Chooser",
help="Choose a .txt file",
widget="FileChooser",
gooey_options=dict(wildcard="Text (.txt) | *.txt"),
)
Checkboxes can be unresponsive unless they are carefully configured. The default and action must be opposite of each other, or they will not register actions or non-actions appropriately. For more details, see this issue.
- To create a checkbox that is checked by default,
action
must be"store_false"
anddefault
must byTrue
. - To create a checkbox that is unchecked by default,
action
must be"store_true"
anddefault
must byFalse
.
Take this into consideration when you are coding your app (flip the values returned from store_false
arguments, etc.). Example of checkbox that is checked by default:
gp.add_argument(
"-c",
"--checkbox_1",
metavar="Checkbox 1",
help="Checkbox that is checked by default",
widget="CheckBox",
action="store_false",
default=True,
)
Print statements do not appear on the display window when python’s standard out buffer is full. There’s an easy fix — use sys.stdout.flush()
after any print statements to force them to be printed to the Gooey window.
import sys
print("Progress update..")
sys.stdout.flush()
5. In summary
Gooey is easy to learn and easy to use for adding a simple GUI to python applications. I look forward to reading your tips and experience in the comments below. Happy coding!