Flet: Stack

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:

Figura 1: distâncias em Stack

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)
Figura 2: resultado do código com Stack. Apenas 3 frames são mostrados.

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)
Figura 3: sobreposição de controles com Stack.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *