Quick Introduction

The Counter app is one of the first apps one can build when learning to build GUI applications with the famous Flutter. In this article, we will rebuild it from scratch. Not in Dart, but with Python.

To achieve this, we will use a Python framework named Flet. If you've already heard of it, keep reading. If you haven't heard of it, let me briefly describe it: It is an open-source framework that aims to allow programmers to build Flutter applications with their favorite programming language easily.

At the time of writing, it is only available in Python, but they have planned to spread to other languages such as Go and C# in the upcoming years. Give their Roadmap a quick look.

Toward the end of this article, I will conclude by giving my opinion on this Python framework.

To look at the Flutter example we will be cloning, see this article.

App's Structure

The application is made up of three (3) main parts:

  • The app bar at the top
  • Some text containing the counter value in the middle
  • A floating action button at the right bottom

That will be all. Before we build the app, let's ensure you have Flet installed.

Installing Flet — "Hello, World!"

Flet is available as a Python package, meaning its installation is similar to other packages. Make sure you have Python installed, then run this command from your terminal to grab the latest version (v0.4.0 at the time of writing):

pip install flet

It is recommended to do this in a Virtual Environment.

After the installation, create a new file and name it as you wish (for example, my-editor), and run this basic "Hello, World!" code using your favorite IDE to ensure you are good to go.

import flet as ft

def main(page: ft.Page):
    page.add(ft.Text(value="Hello, world!"))
    
ft.app(target=main)
None
Hello World — Dark Mode
None
Hello World — light mode

Throughout this article, I will be importing Flet with the alias ft, just like Numpy is commonly aliased np or Pandas pd. All right! Let's dive right in.

The execution of that code block opens a native window containing the rendered output. If you wish, you could tell Flet to render that output in your browser just by modifying the last line of code to:

ft.app(target=main, view=ft.WEB_BROWSER)  # a port could also be specified

Step 1: Page/UI Configuration

Let's add some settings/configurations to our page/UI.

import flet as ft

def main(page: ft.Page):
    # the title of the app
    page.title = "Flet Counter App"

    # a light/bright theme
    page.theme_mode = "light"

    # use material 2 design theme | this is just to better mimic the Flutter example
    page.theme = ft.Theme(use_material3=False)

    # center the pages' content
    page.horizontal_alignment = "center"
    page.vertical_alignment = "center"

    page.add(ft.Text(value="Hello, world!"))
    
ft.app(target=main)

I added explanatory comments to ease your understanding.

Step 2: The AppBar at the Top

Now, let's add an application bar. The Flet page has an appbar property that only takes a AppBar class.

Add the code block before the page.add():

    # the app's appbar
    page.appbar = ft.AppBar(
        title=ft.Text("Flet Demo Home Page", color=ft.colors.WHITE),  # a title of white color
        bgcolor=ft.colors.BLUE,  # a blue background color
        center_title=True  # center the title || without this, the title will be on the left
    )

    page.add(ft.Text(value="Hello, world!"))
    
ft.app(target=main)

Run your code, and you will see something similar to the image below:

None
Hello World with AppBar

Step 3: The Counter Text in the Middle

We will now modify the text ("Hello, World") in the middle of the application. We will add static text (a description) on the top and dynamic text (the counter value) below it.

  # the app's appbar
  page.appbar = ft.AppBar(
      # ....
  )

  # text that contains the counter number to be incremented
  counter_text = ft.Text("0", style=ft.TextThemeStyle.DISPLAY_MEDIUM)

  # adding our widgets/controls to the page/UI
  page.add(
      ft.Text("You have pushed the button this many times:"),
      counter_text
  )

ft.app(target=main)

Run your app, and you will see the two texts we are just from adding:

None
Appbar and Counter value

Step 4: The Floating Action Button at the Bottom

Now we will add the floating action button (FAB) at the bottom right corner of the screen. Our FAB should have a blue background, be round/circular, and have a white plus (+) icon. You can make use of this app to choose your icons.

The FAB will also have a tooltip, the text shown when the icon is hovered over.

The Flet page has a floating_action_button property that only takes a FloatingActionButton class.

    # the page's FAB
    page.floating_action_button = ft.FloatingActionButton(
        content=ft.Icon(ft.icons.ADD, color=ft.colors.WHITE),
        shape=ft.CircleBorder(),  # gives the button a round/circle shape
        on_click=increment_counter,  # the callback to be executed when this button is clicked
        tooltip="Increment",  # the text to be shown when this button is hovered
        bgcolor=ft.colors.BLUE  # a blue background color
    )

    page.add(
        # ...
    )

ft.app(target=main)

In the code above, I defined a property of the FAB named on_click to be equal to increment_counter, which is the function/callback which will be called every time this button is clicked. Before running the code, we must create this callback, or Python will break and tell us it didn't find something named increment_counter.

This callback/function will modify the increment by one from that 0 in the middle. Here is its definition:

def increment_counter(e):
    """Increment the value of the counter_text object by 1, and update the UI to reflect these changes."""
    counter_text.value = str(int(counter_text.value) + 1)
    page.update()

Add it in the main function, but below or above the page settings we made earlier.

Run the code, and you will see the following output:

None
Final result

Press on the FAB, and you will see the counter value being modified. Here is the complete code. I deployed an online version of this for you here. Try it out and let me know what you think. You could eventually package this app as a standalone executable file or deploy it on the web. That's the cross-platform nature of Flet.

Do you think what we've built resembles the Flutter example? I am sure it does!

Conclusion

See this application as a proof of concept: Python only can be used to build Flutter UIs. All thanks to the Flet Python framework. As you've seen, it is pretty easy and simple to use. I have tried several Python GUI frameworks, and personally, Flet is the easiest of all.

If you face any issues, let me know so I can help you out.

By the way, I started a Youtube channel, please subscribe:

Thanks for reading.