Objeto Stack
Em alguns casos queremos colocar controles em cima de outros. No Flet é possível sobrepor vários filhos do controle Stack. Podemos, por exemplo, colocar um texto sobre uma imagem ou um container móvel, como fizemos no exemplo 3.
Propriedades de Stack
O controle Stack possui apenas 2 propriedades:
clip_behavior
Como será cortado (clipped) o conteúdo do objeto.
Os valores possíveis estão armazenados em no enum ClipBehavior com os valores:
- NONE
- ANTI_ALIAS
- ANTI_ALIAS_WITH_SAVE_LAYER
- HARD_EDGE (default)
controls
Uma lista contendo os controles a serem exibidos dentro de Stack, em ordem de exibição, sendo o último controle exibido por cima dos demais.
Controles dentro de Stack
Diversos controles, ao serem colocados dentro de um Stack passam a admitir propriedades de posição. São elas:
left: distância entre a borda esquerda do controle filho até a borda esquerda do Stack.
right: distância entre a borda direita do controle filho até a borda direita do Stack.
bottom: distância entre a borda inferior do controle filho até a borda inferior do Stack.
top: distância entre a borda superior do controle filho até a borda superior do Stack.
Exemplo de uso do Stack
O exemplo de código a seguir insere 3 controles dentro de um Stack, 1 imagem e 2 linhas. Nessa posição eles admitem as propriedades listadas acima, em particular top e left que são usadas para mover a linha de texto.
1 import flet as ft 2 import time 3 4 def main(page: ft.Page): 5 def voltar(e): 6 texto.size = 50 7 linha_texto.top=500 8 linha_texto.left=0 9 page.update() 10 11 def partir(e): 12 while linha_texto.top > 0: 13 time.sleep(.1) 14 texto.size -= 1 15 linha_texto.top-=10 16 linha_texto.left+=10 17 page.update() 18 19 imagem = ft.Image(src=f"https://phylos.net/wp-content/uploads/2020/02/deepfield.jpg", 20 width=950, height=556, fit=ft.ImageFit.NONE) 21 22 texto = ft.Text("Em uma galáxia muito muito distante...", 23 color="yellow", size=50, weight="bold", opacity=0.3) 24 25 linha_texto = ft.Row([texto], left = 0, top=500) 26 27 bt_partir = ft.ElevatedButton("Partir!", bgcolor="blue", color="white", 28 width=120, height= 35, on_click=partir) 29 30 bt_voltar = ft.ElevatedButton("Voltar", bgcolor="blue", color="white", 31 width=120, height= 35, on_click=voltar) 32 33 linha_botoes = ft.Row([bt_partir,bt_voltar], left = 10, top=10) 34 35 page.add(ft.Stack([imagem, linha_texto,linha_botoes], width=950, height=556)) 36 37 ft.app(target=main)
Um clique no botão Voltar retorna as propriedades do texto e da linha que o contém para seus valores iniciais. Observe que, se o botão Partir! for acionado antes que o loop na linha 12 tenha terminado a velocidade de subida do texto aumentará pois os incrementos serão aumentados (loops dentro de loops).
Exemplo: sobreposição de controles
Mais um exemplo ajudará a mostrar que, dentro de um Stack, controles desenhados estão dispostos em camadas. Se dois controles são posicionados no mesmo lugar o último deles, na camada superior, ficará visível, cobrindo o controle por baixo.
1 import flet as ft 2 3 class Ct(ft.Container): 4 def __init__(self, cor, acima, direita, abaixo, esquerda): 5 super().__init__() 6 self.width=20 7 self.height=20 8 self.border_radius=5 9 self.bgcolor=cor 10 self.top=acima 11 self.right=direita 12 self.bottom=abaixo 13 self.left=esquerda 14 15 def main(page: ft.Page): 16 page.horizontal_alignment = ft.CrossAxisAlignment.CENTER 17 page.vertical_alignment = ft.MainAxisAlignment.CENTER 18 19 def mover(e): 20 e.control.data = (e.control.data % 5) + 1 21 i = e.control.data 22 st.controls.pop() 23 if i==1: ct5=Ct("purple", 0, 60,60,0) 24 elif i==2: ct5=Ct("purple", 0,0,60,60) 25 elif i==3: ct5=Ct("purple", 60,0,0,60) 26 elif i==4: ct5=Ct("purple", 60,60,0,0) 27 else: ct5=Ct("purple", 30,30,30,30) 28 st.controls.append(ct5) 29 st.update() 30 31 ct1 = Ct("red", 0, 60,60,0) 32 ct2 = Ct("yellow", 0,0,60,60) 33 ct3 = Ct("blue", 60,0,0,60) 34 ct4 = Ct("green", 60,60,0,0) 35 ct5 = Ct("purple", 30,30,30,30) 36 ct5.data=0 37 bt_mover = ft.ElevatedButton("Mover", bgcolor="blue", color="white", 38 width=120, height= 35, data = 0, on_click=mover) 39 40 st = ft.Stack([ct1, ct2, ct3,ct4, ct5]) 41 st.data = 0 42 43 page.add(ft.Container(st, border_radius=8, padding=5, 44 width=100, height=100, bgcolor="black"), bt_mover) 45 46 ft.app(target=main)
O exemplo também ajuda a ilustrar o uso de POO no Flet. Como muitos controles com propriedades semelhantes serão criados, a classe Ct foi criado na linha 3, herdando de um ft.Container. Objetos criados nas linhas 31 a 35 passam para o construtor apenas a cor e a posição do container.
A função mover(), acionada por bt_mover remove o último objeto no Stack na linha 22 e cria um novo container roxo por cima dos demais, circularmente. O container coberto não deixa de existir e reaparece na próxima operação.