Page behavior in flet works when used directly in `main`, but not in a UserControl?

20 views Asked by At

This code produces a (currently non-functional) login page that looks more or less the way I would like it to look (see image #1).

import flet as ft

def main(page : ft.Page):
    page.title = 'Login Page'
    page.vertical_alignment = 'center'
    page.horizontal_alignment = 'center'


    page.add(
        ft.Row(controls=[ft.Image(src=f'/images/splash_image_1.png', fit=ft.ImageFit.FIT_HEIGHT)],
               alignment=ft.MainAxisAlignment.CENTER,
               spacing=10,
               height=200),
        ft.Column(
            [ft.TextField(hint_text='First Name', expand=False),
             ft.TextField(hint_text = 'Last Name', expand=False),
             ft.TextField(hint_text = 'Email', expand=False)],
             alignment=ft.MainAxisAlignment.SPACE_AROUND,
             horizontal_alignment=ft.CrossAxisAlignment.CENTER,
             scroll = ft.ScrollMode.ADAPTIVE
        ),
        ft.Row([
            ft.ElevatedButton('Close'),
            ft.ElevatedButton('Login'),
        ],
        expand=True,
        alignment=ft.MainAxisAlignment.CENTER,
        vertical_alignment=ft.MainAxisAlignment.END,
        spacing = 100),
    )
    page.window_width = 640
    # print(f"Height: {page.window_height}\nWidth: {page.window_width}")
    
    page.update()

ft.app(target=main, assets_dir='assets')

Correct display shown here

I was trying to save this the way it currently is so I can work on other parts of the application, and I tried to do it like this (saved in a file called startup.py, which is in the root project directory):

import flet as ft

class LoginScreen(ft.UserControl):
    def __init__(self):
        super().__init__()
        
    def build(self):
        return ft.Column([
            ft.Row(controls=[ft.Image(src='/images/splash_image_1.png', fit=ft.ImageFit.FIT_HEIGHT)],
                   alignment=ft.MainAxisAlignment.CENTER,
                   spacing=10,
                   height=200),
            ft.Column([
                ft.TextField(hint_text='First Name', expand=False),
                ft.TextField(hint_text='Last Name', expand=False),
                ft.TextField(hint_text='Email', expand=False)],
                alignment=ft.MainAxisAlignment.SPACE_AROUND,
                horizontal_alignment=ft.CrossAxisAlignment.CENTER,
                scroll=ft.ScrollMode.ADAPTIVE
            ),
            ft.Row([
                ft.ElevatedButton('Close'),
                ft.ElevatedButton('Login')],
                expand=True,
                alignment=ft.MainAxisAlignment.CENTER,
                vertical_alignment=ft.MainAxisAlignment.END,
                spacing=100),
        ])

But when I try to do this:

import flet as ft
from startup import LoginScreen

def main(page : ft.Page):
    page.title = 'Login Page'
    page.vertical_alignment = 'center'
    page.horizontal_alignment = 'center'

    page.add(LoginScreen())
    page.update()


ft.app(target=main,assets_dir='assets')

It looks different

The TextFields are grayed out and not editable, and the image doesn't display. I'm also not sure how to set the page width depending on the control being displayed.

So how can I get the same behavior that I get from adding the controls directly to the page, while also making this particular page portable? I'm trying to save the current state of the page, and will later add functionality to route the user elsewhere when the Login button is pressed.

I'm very new to flet/Flutter, and I assume there's a massive part of the story that I'm missing here.

I tried to save the current page as a single ft.UserControl, and I was expecting to just be able to add it to the page.

This apparently does not work, and I'm not sure how else to save pages so that the user can navigate them.

0

There are 0 answers