Flet python page.update doesn't update my form gui

434 Views Asked by At

In my code, I'm trying to update the textfield value after retrieving image data with tesseract. The problem is that the value updates, but it doesn't do so in the GUI itself.

from flet import *
from vvisiteur import Visiteur
import pytesseract
from PIL import Image as img

class AppForm(UserControl):
    def __init__(self, page : Page):
        super().__init__()
        self.page = page
        self.name = self.app_form_input_field('Name', True)
        self.id_number = self.app_form_input_field('id Number', 3)
        self.phone = self.app_form_input_field('phone', 1)
        self.autre = self.app_form_input_field('Field Tree *', 1)

    def app_form_input_field(self, name:str, expand:int):
        return Container(
            expand=expand,
            height=45,
            bgcolor='#ebebeb',
            border_radius=6,
            padding=8,
            content = TextField(
                        label=name,
                        border_color="transparent",
                        height=20,
                        text_size=13,
                        content_padding=0,
                        cursor_color="black",
                        cursor_width=1,
                        cursor_height=18,
                        color="black",
                    ),
        )
    
    def pickFile(self, e:FilePickerResultEvent):
        image_loc = e.files[0].path
        img_pro=img.open(image_loc)
        text = pytesseract.image_to_string(img_pro, lang='fra')
        sections= {}
        lines = text.split("\n")
        sections['name'] = lines[18] + ' ' + lines[4]
        sections['id number'] = lines[24].split(" ")[0]
        temp =  lines[13].split()
        sections['phone'] = ' '.join(temp[1:])
        print(sections)
        self.id_number.content.value = sections["id number"]
        self.name.content.value = sections["name"]
        self.phone.content.value = sections["phone"]
        self.page.snack_bar = SnackBar(
            Text("sucess get from image", size=30),
            bgcolor="green"
        )
        self.page.snack_bar.open=True
        self.page.update()
    

    def return_vit(self):
        visiteur = Visiteur(self.name.content.value ,self.phone.content.value, self.id_number.content.value)
        return visiteur.to_dict()
        
    def build(self):
        file_picker = FilePicker(on_result=self.pickFile)
        self.page.overlay.append(file_picker)
        return Container(
            expand=True,
            height=220,
            bgcolor="white10",
            border=border.all(1, "#ebebeb"),
            border_radius=8,
            padding= 15,
            content=Column(
                expand=True,
                controls = [
                    Row(controls= [self.name]),
                    Row(controls= [
                        self.id_number,
                        self.phone,
                        self.autre,
                        ]
                    ),
                    ElevatedButton("Process",
                           bgcolor="blue",
                           color='white',
                           on_click=lambda _ :file_picker.pick_files()),
                ]
            )
        )

I'm trying to automatically fill a form with Texfields by retrieving information from an image and changing textfield.value directly in the code. it doesn't work when i use a class for my form but It works when I code directly in the main like this

import pytesseract
from PIL import Image as img
from flet import *
import flet
import os

def main(page: Page):
    image_loc= TextField(label="yout image name")
    id_number= TextField(label="id number")
    name_txt= TextField(label="your name")
    phone= TextField(label="phone number")
    healthy_service = TextField(label="healthy service")
    image_preview = Image(src=False, width= 150, height=120)

    def pickFile(e:FilePickerResultEvent):
        image_loc.value = e.files[0].path
        print(image_loc.value)
        img_pro=img.open(image_loc.value)
        text = pytesseract.image_to_string(img_pro, lang='fra')
        sections= {}
        lines = text.split("\n")
        sections['name'] = lines[18] + ' ' + lines[4]
        sections['id number'] = lines[24].split(" ")[0]
        temp =  lines[13].split()
        sections['phone'] = ' '.join(temp[1:])
        print(sections)
        id_number.value = sections["id number"]
        name_txt.value = sections["name"]
        phone.value = sections["phone"]
        page.snack_bar = SnackBar(
            Text("sucess get from image", size=30),
            bgcolor="green"
        )
        page.snack_bar.open=True
        page.update()

    file_picker = FilePicker(on_result=pickFile)

    page.overlay.append(file_picker)
    page.add(
        Column([
            image_loc,
            ElevatedButton("Process",
                           bgcolor="blue",
                           color='white',
                           on_click=lambda _ :file_picker.pick_files()),
            Text('you result in image', weight="bold"),
            image_preview,
            id_number,
            name_txt,
            phone,
            healthy_service,
        ])
    )

flet.app(target=main)

A Minimum code with class it not work

import pytesseract
from PIL import Image as img
from flet import *
import flet
import os


class form(UserControl):
    def __init__(self, page : Page):
        super().__init__()
        self.page = page
        self.image_loc= TextField(label="yout image name")
        self.id_number= TextField(label="id number")
        self.name_txt= TextField(label="your name")
        self.phone= TextField(label="phone number")
        self.healthy_service = TextField(label="healthy service")
        self.image_preview = Image(src=False, width= 150, height=120)

    def pickFile(self, e:FilePickerResultEvent):
        image_loc = e.files[0].path
        img_pro=img.open(image_loc)
        text = pytesseract.image_to_string(img_pro, lang='fra')
        sections= {}
        lines = text.split("\n")
        sections['name'] = lines[18] + ' ' + lines[4]
        sections['id number'] = lines[24].split(" ")[0]
        temp =  lines[13].split()
        sections['phone'] = ' '.join(temp[1:])
        print(sections)
        self.id_number.value = sections["id number"]
        self.name_txt.value = sections["name"]
        self.phone.value = sections["phone"]
        self.page.snack_bar = SnackBar(
            Text("sucess get from image", size=30),
            bgcolor="green"
        )
        self.page.snack_bar.open=True
        self.page.update()

    def build(self):
        file_picker = FilePicker(on_result=self.pickFile)
        self.page.overlay.append(file_picker)
        return(
            Container(
                content = Column([
                ElevatedButton("Process",
                           bgcolor="blue",
                           color='white',
                           on_click=lambda _ :file_picker.pick_files()),
                Text('you result in image', weight="bold"),
                self.image_preview,
                self.id_number,
                self.name_txt,
                self.phone,
                self.healthy_service,
            ])
        )
    )

def main(page: Page):
    myform = form(page)
    page.add(myform)
    page.update()

flet.app(target=main)
1

There are 1 best solutions below

1
On BEST ANSWER

You have to use self.update() to update elements in UserControl

You can see it even in examples for UserControl


You still need self.page.update() to update self.page.snack_bar.


Minimal working code:

I keep only one TextField and display path instead of text from pytesseract.
This way everyone can test it.

import flet as ft   # PEP8: `import *` is not preferred

class Form(ft.UserControl):  # PEP8: `UpperCasenames` for classes

    def __init__(self, page : ft.Page):
        super().__init__()
        self.page = page   # to add `SnackBar`
        self.name_txt = ft.TextField(label="your name")

    def pickFile(self, e:ft.FilePickerResultEvent):
        if e.files:
            sections = {}
            sections['name'] = e.files[0].path
            print(sections)
            
            self.name_txt.value = sections["name"]
            self.update()       # to update elements in `UserControl`

            self.page.snack_bar = ft.SnackBar(
                ft.Text("sucess get from image", size=30),
                bgcolor="green"
            )
            self.page.snack_bar.open = True
            self.page.update()  # to update `self.page.snack_bar`
        else:
            self.page.snack_bar = ft.SnackBar(
                ft.Text("You didn't select image", size=30),
                bgcolor="red"
            )
            self.page.snack_bar.open = True
            self.page.update()  # to update `self.page.snack_bar`
 
    def build(self):
        file_picker = ft.FilePicker(on_result=self.pickFile)
        self.page.overlay.append(file_picker)
        
        return(
            ft.Container(
                content = ft.Column([
                ft.ElevatedButton("Process",
                           bgcolor="blue",
                           color='white',
                           on_click=file_picker.pick_files),  # no need `lambda`
                ft.Text('you result in image', weight="bold"),
                self.name_txt,
            ])
        )
    )

def main(page: ft.Page):
    myform = Form(page)
    page.add(myform)
    #page.update()   # doesn't need it

ft.app(target=main)

PEP 8 -- Style Guide for Python Code