Python GUI

How To Build A TODO TUI Application With Textual

building a tui with textual in pyscripter

Did you know it’s possible to build a rich UI that runs completely in the terminal? Even some experienced Python developers avoid using the terminal in favor of Graphical User Interfaces (GUIs). But, today, many developer tools use a Terminal User Interface (TUI) since they often spend a lot of time working in the terminal. Not only are there programs and tools, but there are also several games that run entirely in the terminal.

So, in this article, we will first develop a good understanding of TUIs and then move on to creating an interesting TUI using PyScripter to manage to-do lists.

What is a TUI?

How To Build A TODO TUI Application With Textual - an image of a laptop showing some Python code

A TUI, short for Text User Interface or Terminal User Interface, uses the terminal’s advanced features as the basis for a kind of GUI, generally occupying the full area of the terminal. It uses escape codes or proprietary console commands (the latter on Windows, the former on most other things) to take control of the entire console window and display a user interface. TUIs Usually handle input via the keyboard, but some modern systems also use mouse input.

Thus, a TUI allows users to interact with a program via the terminal. The terminal does not interact via commands, although many TUI programs also accept commands.

Why is Textual Popular For Making TUIs?

Textual is a Python framework for creating interactive applications that run in your terminal. It mainly adds interactivity to Rich with a Python API inspired by modern web development.

On modern terminal software, Textual apps offer more than 16 million colors, mouse support, and smooth, flicker-free animation. Furthermore, a powerful layout engine and reusable components make it possible to build apps that rival the desktop and web experience.

Currently, Textual runs on Linux, macOS, and Windows. This framework requires Python 3.7 or above.

How to Build a ToDo List TUI in Python?

How To Build A TODO TUI Application With Textual- an image of a laptop on someone's knee with a code editor open on the screen

Let us now move to the main part of this tutorial and start building a to-do list in Python. But first there are some requirements that you need to install.

What Are the Requirements For This TUI Tutorial?

For this tutorial you will need Python 3.9+ installed on your computer. You will also need to install an IDE a feature-packed IDE like PyScripter.

Then, you can install Textual via PyPI.

If you intend to simply run Textual apps, then install textual and textual_inputs using the following command:

However, if you plan to develop Textual apps, you should install textual[dev]. This is because the [dev] part installs a few extra dependencies for development.

Moreover, to make our to-do list more appealing will be using Rich. The Rich API will help us add color and style to our terminal output. In addition, Rich can also render attractive tables, progress bars, markdown, syntax highlighted source code, tracebacks, and other features right out of the box.

After installing Textual, you can install Rich using the following PyPI command:

How to Create a Basic TUI in Textual?

Let’s start this tutorial by creating a simple TUI in Textual, and then we will build upon this to create a TUI that serves our purpose.

How To Build A TODO TUI Application With Textual - example screenshot of TUI use

The following code builds a TUI with a text box Text that takes in some text from the user and displays it in the Output panel when the enter key is pressed. It has a simple Header and Footer where the Footer has a button q that can be clicked using the mouse to exit the program.

Running this code will give you the following output in the terminal:

How To Build A TODO TUI Application With Textual - screen 1

If we press enter, our text will appear on the output panel:

How To Build A TODO TUI Application With Textual- screen 2

If you cannot follow the program above, do not fear as we walk you through it step by step as we build a more complex To-do list over this code.

How To Create An Instance of Our to-do List?

We will start by importing several libraries and functions to create our TUI:

Above, we created a global variable formatted that helps us keep track of tasks in our to-do list by storing all our tasks in a string format.

Next, we define a class named ToDoForm that inherits from App imported from the This will serve as the primary class to help us run our TUI to-do list. We also define a constructor that calls the parent class’s constructor, which will help us instantiate our TUI to-do list.

How To Build A TODO TUI Application With Textual - example code of

We can now move on and start creating the user interface for our TUI.

How Do We Create a User Interface For Our TUI?

To create a user interface, we define an async function on_mount() that will format our TUI user interface. We define the function as a class method called when we instantiate our ToDoForm object.

We start by first placing a Header and Footer on our TUI. This is done by using self.view.dock(), adding an instance of either a Header or Footer as a parameter and specifying its placement in the optional edge argument. Here we define the Header to be at the top and the Footer to be at the bottom.

Next, we define a text input that will help us append tasks to our TUI to-do list. We do this by creating an instance of the TextInput object and assigning it to a variable self.todo. We then specify its title, name, and placeholder.

Note: The title is what will be displayed on top of the TextInput text box.

The self.todo will receive inputs from the user, which we will later use to add items to our tasks in formatted.

Similarly, we create another TextInput instance named self.file that we will use to take file names as input and add their contents to our to-do list.

Finally, to output our to-do list, we instantiate a Static object, and within it, a Panel. We then assign it to a variable named self.output. This will serve as the output of our TUI. We then define the placement of our text input and output panel by using the self.view.dock() and specify its placement using edge. For our output panel, we also use another size argument that helps us define a custom size for our panel.

How To Build A TODO TUI Application With Textual - code example 4

But the question arises, how can we use these variables to add values to our to-do list?

How To Create Functions to Add Entries to Our to-do list?

To add entries to our to-do list, we create async functions that will use the inputs provided in the self.todo and self.file objects, and then add them to our to-do list.

First, we define an async function action_submit() that will use the self.todo text box.

The function simply uses the .value attribute of the TextInput object to retrieve the value in the self.todo text box. It then formats the input by removing a hyphen and then adds it to self.output list using the .update() method.

Finally, the function empties the text box by setting the value of self.todo.value to an empty string before writing the contents of the to-do list into a file named “ToDo.txt.

Next, we define a function action_read() that reads the file provided in the text box of self.file, and writes its contents into our to-do list.

Like the action_submit() function, we first read the contents provided in the self.file text box using the .value attribute. If a file has been provided, the function reads the file’s contents, parses and formats it, then appends the items in the file to our to-do list. If no file has been provided, the function simply prints an error.

How To Build A TODO TUI Application With Textual - another code example

How Can We Add Bindings to Our TUI?

Now that we’ve defined our functions, we can call them by pressing some keys on our keyboard. This is done through key bindings.

Textual allows us to create key bindings for our TUI easily. This can be done using the .bind() method, which takes three arguments. The first argument specifies the key that we will bind, the second argument specifies the action to bind to, and the final argument is optional and provides a short description of the action.

For our application, we will bind three keys:

  1. The “q” key binding will help us quit our TUI.
  2. The “enter” key binding will help us submit entires to our to-do list.
  3. Finally, pressing the “ctrl+r” key binding will allow us to read specific files that we specify in the self.file text box.

To create our key bindings, we create an async function on_load() that runs when we create an instance of our TUI:

How Do We Run The Code We Have Created?

Now all that’s left is to create an instance of our ToDoForm and run it. Here is what our final code looks like:

How To Build A TODO TUI Application With Textual- a screenshot of the todo list generator TUI

Let’s say you wanted to add some tasks to your to-do list. You can write it down in the ToDo text box:

How To Build A TODO TUI Application With Textual - a screenshot of the todo list generator TUI - 2

If you press enter, it will be added to your to-do list.

How To Build A TODO TUI Application With Textual - a screenshot of the todo list generator TUI - 3

This creates a file, “ToDo.txt” in the same directory.

Let us now create a text file named “tasks.txt” inside the application directory and define some tasks inside it. First, we will add three tasks to the file, with each task beginning with a hyphen:

How To Build A TODO TUI Application With Textual - example UI

With the code running, add the file’s name to the TUI, then press “ctrl+r” together. This adds the tasks to your to-do list:

How To Build A TODO TUI Application With Textual- screenshot of adding tasks

Let’s add more tasks to your to-do list:

How To Build A TODO TUI Application With Textual - adding the tasks

All this content has been appended to the text file, “ToDo.txt“:

How To Build A TODO TUI Application With Textual - GUI 5

Congratulations on reaching the end of this tutorial. You may have noticed that we have been using PyScripter throughout this project. This is because PyScripter is one of the best tools that you can have to organize your code and understand it better. So, if you are starting with Python, PyScripter should be part of your starter kit.

Why Should You Use PyScripter to Create TUIs?

How To Build A TODO TUI Application With Textual- the Embarcadero Python tools download page

Embarcadero sponsors PyScripter, a popular, free, and open-source Python IDE. This IDE has all the features you’d expect from a modern Python IDE while remaining lightweight and fast. PyScripter is natively compiled for Windows, allowing it to use as little memory as possible while providing maximum performance. It also has full Python debugging capabilities, both locally and remotely. Another noteworthy feature of this IDE is its integration with Python tools like PyLint, TabNanny, Profile, etc. It can also run or debug files directly from memory.

PyScripter includes all the features you’d expect from a professional IDE, such as brace highlighting, code folding, code completion, and syntax checking as you type. It also has features you’d expect to find in a legitimate native app, such as the ability to drag and drop files into the PyScripter IDE. These features work in tandem to save time and make the development process simple and enjoyable.

PyScripter includes a Python interpreter with call indications and code completion. This program lets you run scripts without saving them and keeps a record of your command history. This IDE also includes a remote Python debugger for debugging Python code. As a result, variables, the watch window, and the call stack are visible. Additional debugging tools built into PyScripter include conditional breakpoints and thread debugging. Furthermore, PyScripter has debugger indications to help you debug your files without saving them, as well as the ability to destroy them.

Thus, PyScripter is a fantastic IDE seeking to create a Python IDE that can compete with other languages’ traditional Windows-based IDEs. It is lightweight, versatile, and extendable with a lot of features.

Furthermore, since it was built from the ground up for Windows, it is substantially faster and more responsive than cumbersome text editors, making it perfect for making TUIs.

Are You Ready to Build Your Own TUI?

How To Build A TODO TUI Application With Textual- an image of a person about to download the free PyScripter tool

In this tutorial, you have learned several useful things about Python!

Textual is a TUI framework for Python inspired by modern web development. It has a very active repository on GitHub. This awesome framework is built on Rich and is currently a work in progress, but usable by programmers who don’t mind some API instability between updates.

You can conveniently build complex and simple TUIs with Textual in PyScripter. This IDE will make the entire process very seamless and enjoyable for you.

Now that you know PyScripter’s countless features and how Textual works, go ahead and create your own TUIs in everyone’s favorite IDE!

What Are the FAQs On This Topic?

How To Build A TODO TUI Application With Textual- another person on the PyScripter download page

What are some use cases of TUIs?

TUIs can be used to make programs like stopwatches, calculators, code and other file viewers, basic games, and to-do lists (as shown in this article).

There are several other possibilities. The only limit is your imagination!

Which other TUI libraries are available in Python?

Pytermgui, picotui, and pyTermTk are other frameworks and libraries that can be used to create interactive and attractive TUIs in Python.

What is the difference between CLI, GUI, and TUI?

GUI means Graphical User interface. You must have heard this word most commonly. It is the GUI that has enabled the common user to use computers. A GUI application is an application that can be run with a mouse, touchpad, or touchscreen.

The CLI is a command line program that accepts text input to perform a certain task. Any application you can use via commands in the terminal falls into this category.

TUI, i.e., Terminal User Interface, falls between GUI and CLI. It can also be called a kind of text-based GUI. Before the arrival of the GUI, everything used to run on the command line; then, the terminal user interface provided a kind of GUI on the command line. TUI programs can be run via a mouse or keyboard.

What is Python4Delphi?

In short, P4D offers a selection of real-world apps that can be modified to your individual needs and used in Python GUI.

Consider integrating Delphi’s GUI and desktop app development power with Python in your applications to give world-class solutions to your clients’ needs. Python4Delphi is the answer to your problems.

Python for Delphi (P4D) is a free Delphi and Lazarus component library that wraps the Python DLL. They make it simple to run Python scripts while allowing for new Python modules and types. The best feature of P4D is that it simplifies the use of Python as a scripting language. It also includes numerous customizable demos and tutorials that are ready to use in the development of real-world apps.

Related posts
Python GUI

Is Python a Scripting Language or a Programming Language?

Python GUI

Recommended Read: Mixing Python and Delphi Made Easy

Learn PythonPython GUI

How To Create A FastAPI Server And Python GUI Client App To Manage Employees

Python GUI

Python Programming Jobs That Have High Paying Salary