Cli2Gui is a Python package that allows you to transform command-line interface (CLI) applications
into graphical user interfaces (GUIs). It supports popular parsers like argparse, and different
GUI libraries, like freesimplegui. In this tutorial, we will walk through how to integrate
Cli2Gui into your Python project.
For the examples below, install the Cli2Gui package by running:
pip install cli2gui[fsg]Note: If you need the functionality provided by these libraries, use the following extras:
- psg: For PySimpleGUI support, adding easy-to-build, functional GUIs.
- fsg: For FreeSimpleGUI, a lightweight, streamlined GUI option.
- web: To run your app in a web browser via PySimpleGUIWeb.
- qt: For PySimpleGUIQt, creating polished, native desktop GUIs.
- pandoc: To pretty print markdown files and similar
The primary way to use Cli2Gui is through a decorator that you add to your main function. The
decorator transforms your CLI into a GUI when necessary.
Here's a simple example of how to integrate Cli2Gui into a basic program:
import argparse
def run(args):
print(args.arg)
def main():
parser = argparse.ArgumentParser(description="Example parser")
parser.add_argument("arg", type=str, help="Positional argument")
args = parser.parse_args()
run(args)
if __name__ == "__main__":
main()In this basic example, we have a CLI app that takes a positional argument. Next, we will enhance
it with Cli2Gui to provide a GUI option.
We'll now decorate the main function with Cli2Gui:
from cli2gui import Cli2Gui
# Define the function that will handle the program's logic
def run(args):
print(args.arg)
# Use Cli2Gui as a decorator to convert CLI into a GUI, using freesimplegui
@Cli2Gui(run_function=run, gui="freesimplegui")
def main():
parser = argparse.ArgumentParser(description="Example parser with GUI support")
parser.add_argument("arg", type=str, help="Positional argument")
args = parser.parse_args()
run(args)
if __name__ == "__main__":
main()The Cli2Gui decorator wraps around the main function and adds support for both CLI and GUI.
You can now run this program in two ways:
- CLI Mode:
python3 main.py - GUI Mode: run
python3 main.py --cli2guiand the GUI will appear, allowing you to enter the arguments interactively.
Let’s expand on the previous example with a more complex argument structure, including mutually exclusive groups, optional arguments, and file inputs. We will also demonstrate how to add a menu to the GUI.
from cli2gui import Cli2Gui
import argparse
from pathlib import Path
# Define the function that will handle the program's logic
def handle(args):
print(args)
# Define the CLI function with advanced arguments
@Cli2Gui(
run_function=handle,
gui="freesimplegui",
menu={
"File": "path/to/file.md",
"Another File": "path/to/another_file.md",
}
)
def cli():
parser = argparse.ArgumentParser(description="Advanced CLI with GUI support")
# Positional arguments
parser.add_argument("positional", help="Positional argument")
parser.add_argument("positional_file", type=argparse.FileType("r"), help="Positional file input")
# Optional arguments
parser.add_argument("--optional", help="Optional argument")
parser.add_argument("--store-true", action="store_true", help="Store true")
parser.add_argument("--store-false", action="store_false", help="Store false")
parser.add_argument("--store", help="Store value")
parser.add_argument("--count", action="count", help="Count occurrences")
parser.add_argument("--choices", choices=["choice1", "choice2"], help="Pick a choice")
parser.add_argument("--somefile", type=argparse.FileType("r"), help="Optional file input")
# Mutually exclusive group
group = parser.add_argument_group("Image options")
mxg = group.add_mutually_exclusive_group()
mxg.add_argument("--mxg-true", action="store_true", help="Mutually exclusive store true")
mxg.add_argument("--mxg-false", action="store_false", help="Mutually exclusive store false")
mxg.add_argument("--mxg", help="Mutually exclusive store")
mxg.add_argument("--mxg-count", action="count", help="Mutually exclusive count")
mxg.add_argument("--mxg-choices", choices=["choice1", "choice2"], help="Mutually exclusive choice")
args = parser.parse_args()
handle(args)
if __name__ == "__main__":
cli()In this example:
- run_function: The function to be executed when the user clicks the "Run" button in the GUI. This is the
handle()function - gui: Specify the GUI framework to use. Supported options are:
"dearpygui","pysimplegui","pysimpleguiqt","pysimpleguiweb","freesimplegui". Defaults to"dearpygui". In the example, this is"freesimplegui". - menu: Add a custom menu to the GUI. Example:
{"File": "/path/to/file.md"}.
You can customize various aspects of the GUI, including the theme, icon, and program name. Here’s how you can apply some customization options:
@Cli2Gui(
run_function=handle,
gui="freesimplegui",
theme="one-light.yaml",
darkTheme="one-dark.yaml",
image="path/to/icon.png",
program_name="My Custom Program",
program_description="This is a custom description"
)
def cli():
# Argument parsing logic here
passIn this example:
- run_function: The function to be executed when the user clicks the "Run" button in the GUI. This is the
handle()function - gui: Specify the GUI framework to use. Supported options are:
"dearpygui","pysimplegui","pysimpleguiqt","pysimpleguiweb","freesimplegui". Defaults to"dearpygui". In the example, this is"freesimplegui". - theme: Set a base24 theme or provide a base24 scheme file (e.g.,
"one-light.yaml"). - darkTheme: Specify a dark theme variant using a base24 scheme or file (e.g.,
"one-dark.yaml"). - image: Define the program icon. Supported formats are those compatible with the Python Imaging Library (PIL).
- program_name: Override the default program name with a custom name.
- program_description: Provide a custom description for the program.
- menu: Add a custom menu to the GUI. Example:
{"File": "/path/to/file.md"}.