Skip to content
Advertisement

Update image on button click

Can someone explain to me how do I update a property of an element from a function called from another element, like in the example below?
In this example, I created a flet app which shows 4 elements. The two elements at the top are images and the ones at the bottom are buttons. Now, I’d like to click the buttons and change the images. How do I do that? I already tried to change it through the controls, but I was not able to do it.

import numpy as np
import base64
import flet
from flet import Image, Page, Row, TextButton
from io import BytesIO
from PIL import Image as image

arr = np.zeros((400, 400, 3), dtype=np.uint8)
pil_img = image.fromarray(arr)
buff = BytesIO()
pil_img.save(buff, format="JPEG")
image_string = base64.b64encode(buff.getvalue()).decode("utf-8")

def main(page: Page):
    page.title = "My Page"
    page.theme_mode = "light"
    page.padding = 50

    page.update()

    def update_load_button(value):
        img = np.random.randint(0, 255, (400, 400, 3), np.uint8)
        pil_img = image.fromarray(img)
        buff = BytesIO()
        pil_img.save(buff, format="JPEG")
        new_image_string = base64.b64encode(buff.getvalue()).decode("utf-8")
        ## CHANGE IMAGE HERE ##
        page.update()

    def update_predict_button(v):
        pass

    page.add(
        Row(controls=[
            Image(src_base64=image_string),
            Image(src_base64=image_string)
        ], alignment='center'),
        Row(controls=[
            TextButton("Load_image", on_click=update_load_button),
            TextButton("Predict", on_click=update_predict_button)
        ], alignment='center')
    )
    page.update()

Advertisement

Answer

You need to update the value only of the Image.

Click on Load image to change the 2. image’s color:

import numpy as np
import base64
import flet
from flet import Image, Page, Row, TextButton
from io import BytesIO
from PIL import Image as image

arr = np.zeros((400, 400, 3), dtype=np.uint8)
pil_img = image.fromarray(arr)
buff = BytesIO()
pil_img.save(buff, format="JPEG")

def main(page: Page):
    image_string = base64.b64encode(buff.getvalue()).decode("utf-8")
    page.title = "My Page"
    page.theme_mode = "light"
    page.padding = 50
    img_1 = Image(src_base64=image_string)
    img_2 = Image(src_base64=image_string)

    # page.update()   # not needed!

    def update_load_button(value):
        img = np.random.randint(0, 255, (400, 400, 3), np.uint8)
        pil_img = image.fromarray(img)
        buff = BytesIO()
        pil_img.save(buff, format="JPEG")
        
        new_image_string = base64.b64encode(buff.getvalue()).decode("utf-8")
        img_2.src_base64 = new_image_string  # img_2's value updated
        ## CHANGE IMAGE HERE ##
        img_2.update()  # only img_2 widget will be updated

    def update_predict_button(v):
        pass

    page.add(
        Row(controls=[
            img_1,
            img_2
        ], alignment='center'),
        Row(controls=[
            TextButton("Load_image", on_click=update_load_button),
            TextButton("Predict", on_click=update_predict_button)
        ], alignment='center')
    )
    # page.update() # not needed, every widget can be stateless (only Image not)
    
flet.app(target=main)
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement