An Introduction to Python Gooey

Fullstackdad
4 min readNov 25, 2022

--

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" and default must by True.
  • To create a checkbox that is unchecked by default, action must be "store_true" and default must by False.

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!

--

--

Fullstackdad
Fullstackdad

Written by Fullstackdad

I’m a DIY full stack hobby developer dad, posting various DIY tech projects here for future reference and in case it can help others. Views are my own.

No responses yet