Flet框架中类实现表单时page.update无法更新GUI问题求助
问题描述
我尝试用Tesseract识别图片数据后更新Flet表单的TextField值,但遇到了问题:代码里已经更新了TextField的value属性,GUI界面却没同步更新。直接在main函数里写代码时功能正常,但把表单封装成UserControl类后就出现了这个GUI不更新的问题。
下面是相关代码示例:
封装为类的问题代码
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()), ] ) )
直接在main中编写的正常代码
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)
最简类实现的问题代码
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)
解决方案
问题出在Flet的UserControl更新机制上:当你在UserControl内部修改控件属性后,仅调用self.page.update()不足以触发UserControl内部控件的UI同步,必须额外调用self.update()来通知Flet更新当前UserControl的视图。
下面是修改后的代码:
修改后的封装类代码
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() # 新增:更新当前UserControl self.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()), ] ) )
修改后的最简类实现代码
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() # 新增:更新当前UserControl self.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)
原理说明
Flet中,UserControl是独立的组件单元,它有自己的视图状态。当你修改UserControl内部控件的属性时,需要调用self.update()来告知Flet重新渲染这个UserControl的内容。而直接在main中操作的控件属于页面直接管理,调用page.update()就能同步所有页面控件的状态。
内容的提问来源于stack exchange,提问作者Ogefrec Ockey
相关产品推荐
相关产品推荐

