DEV Community

Cover image for Build Flutter Apps using Python ft. flet
Md. Mobin
Md. Mobin Subscriber

Posted on • Edited on

Build Flutter Apps using Python ft. flet

Building a MiCard App with Flet: Flutter-style UI in Python

Learn how to create beautiful, cross-platform apps using Python and Flet - a framework that brings Flutter's power to Python developers.


What is Flet?

Flet enables developers to easily build real-time web, mobile, and desktop apps in Python. No frontend experience required - if you know Python, you can build beautiful UIs!

Learn more about Flet →

Getting Started

Installation

pip install flet
Enter fullscreen mode Exit fullscreen mode

Hello World Application

Let's start with a simple example:

import flet
from flet import Page, Text

def main(page: Page):
    page.add(Text("Hello, world!"))

flet.app(target=main)
Enter fullscreen mode Exit fullscreen mode

Run the application:

python3 main.py
Enter fullscreen mode Exit fullscreen mode

Hello World Application

Understanding Flet's Architecture

Flet is built using a control-based architecture similar to Flutter. The Page is the parent control, and components like Text, Container, Column, and Row are child controls that you can compose together.

Flet Overview

Project: Building a MiCard App

We're going to recreate a Flutter MiCard app using Python and Flet. This will be a digital business card with profile information and social links.

Original Flutter version: GitHub Repository

Flutter MiCard

Step 1: Project Setup

Create a new file called micard.py and import the required modules:

import flet
import webbrowser
from flet import (
    Column,
    Container,
    Page,
    Text,
    UserControl,
    border_radius,
    colors,
    alignment,
    padding,
    CircleAvatar,
    Divider,
    ListTile, 
    Icon,
    icons, 
    Image,
)
Enter fullscreen mode Exit fullscreen mode

Step 2: Understanding UserControl

We'll use Flet's UserControl class to create an isolated, reusable component. Think of it as a custom widget - when it's added to a page, the build() method is automatically called.

Step 3: Building the Header

Let's create the MiCard class with a profile header:

class MICard(UserControl):
    # Profile links - customize these with your own
    urls = [
        "tel://+919667XXXXXX",
        "mailto://your.email@example.com",
        "https://twitter.com/your_handle",
        "https://github.com/your_username"
    ]

    def build(self):
        return Container(
            padding=padding.symmetric(horizontal=20, vertical=50),
            alignment=alignment.center,
            content=Column(
                alignment="center",
                horizontal_alignment="center",
                spacing=20,
                controls=[
                    CircleAvatar(
                        background_image_url="https://www.aceorganicchem.com/blog/wp-content/uploads/2020/02/bitmoji-300x300.jpeg",
                        bgcolor=colors.WHITE,
                        max_radius=100
                    ),
                    Text("MD MOBIN", size=40),
                    Text("Flutter Developer", size=30, color=colors.WHITE30),
                    Container(
                        width=1000,
                        padding=padding.symmetric(horizontal=20, vertical=10),
                        content=Divider(
                            color=colors.WHITE,
                            thickness=2,
                            height=50,
                        )
                    ),
                ]
            )
        )


def main(page: Page):
    page.title = "Mi Card"
    page.horizontal_alignment = "center"
    page.vertical_alignment = "center"
    page.scroll = "adaptive"
    page.bgcolor = colors.BLUE_ACCENT_700

    card = MICard()
    page.add(card)


flet.app(target=main)
Enter fullscreen mode Exit fullscreen mode

Output:

Output 1

Step 4: Adding Custom Fonts

You can use custom fonts from local files or URLs. Add this before page.add(card):

page.fonts = {
    "dancing_script": "https://github.com/google/fonts/raw/main/ofl/dancingscript/DancingScript%5Bwght%5D.ttf"
}
Enter fullscreen mode Exit fullscreen mode

Update the name Text control:

Text("MD MOBIN", font_family='dancing_script', size=40)
Enter fullscreen mode Exit fullscreen mode

Output:

Output 2

Step 5: Creating Contact Tiles

Let's add a reusable function for contact information tiles. Add this method to the MICard class:

def tile_widget(self, icon, title, index):
    return Container(
        width=1000,
        padding=padding.symmetric(horizontal=20, vertical=10),
        bgcolor=colors.WHITE,
        alignment=alignment.center,
        border_radius=border_radius.all(8),
        content=ListTile(
            leading=icon,
            title=Text(title, color=colors.BLACK),
        )
    )
Enter fullscreen mode Exit fullscreen mode

Add these tiles to your Column controls list (after the Divider):

self.tile_widget(
    icon=Icon(name=icons.CALL, color=colors.BLACK, size=50), 
    title="+91 9667******",
    index=0
),
self.tile_widget(
    icon=Icon(name=icons.EMAIL, color=colors.BLACK, size=50),
    title="test@flet.com",
    index=1
),
self.tile_widget(
    icon=Image(
        src="https://cdn-icons-png.flaticon.com/512/1384/1384033.png", 
        fit="contain"
    ),
    title="@SmkWinner",
    index=2
),
self.tile_widget(
    icon=Image(
        src="https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png",
        fit="contain"
    ), 
    title="DJSMK123",
    index=3
),
Enter fullscreen mode Exit fullscreen mode

Note: Since Twitter and GitHub icons aren't available in Flet's icon library, we're using images instead.

Output:

Output 3

Step 6: Making Links Clickable

Now let's make these tiles interactive! Add a click handler method to the MICard class:

def onClick(self, index):
    webbrowser.open_new_tab(self.urls[index])
Enter fullscreen mode Exit fullscreen mode

Update the tile_widget method's ListTile to handle clicks:

content=ListTile(
    leading=icon,
    title=Text(title, color=colors.BLACK),
    on_click=lambda e: self.onClick(index=index)
)
Enter fullscreen mode Exit fullscreen mode

The lambda function allows us to pass the index parameter to our click handler.

Step 7: Running as a Web App

To run your app in a web browser instead of a desktop window:

flet.app(target=main, view=flet.WEB_BROWSER)
Enter fullscreen mode Exit fullscreen mode

Complete Source Code

You can find the complete source code here: GitHub Repository

What's Next?

Now that you've built your first Flet app, try these next steps:

  • Build a To-Do App with Flet
  • Customize the MiCard with your own information and styling
  • Explore Flet's extensive control library
  • Deploy your app to the web

Key Takeaways

  • Flet brings Flutter's declarative UI to Python
  • UserControl lets you create reusable components
  • You can use custom fonts from URLs or local files
  • Lambda functions are great for event handlers with parameters
  • Flet apps can run as desktop, mobile, or web applications

Connect With Me

Happy coding! 🚀

Top comments (2)

Collapse
 
juniverse profile image
Universe

This is great!I'll look more into it.

Collapse
 
oknhahii profile image
Andrew

I hope Python flet can compete with React native