Saudações! Hoje falaremos novamente sobre a biblioteca
KivyMD - um conjunto de widgets para desenvolvimento de plataforma cruzada em Python no estilo de Design de materiais. Neste artigo, não analisarei os widgets do KivyMD, como em um
artigo recente , mas sim sobre o posicionamento de widgets. Algo como um tutorial sobre o desenvolvimento de aplicativos móveis em Python para iniciantes não estará aqui. Portanto, se você ouvir pela primeira vez sobre a estrutura do Kivy, é improvável que esteja interessado em tudo isso. Bem, nós dirigimos sob o corte!
Outro dia, baixei o aplicativo de demonstração Flutter UIKit do Google Play:
E agora vamos tentar repetir uma tela a partir desta aplicação. Vejamos os resultados imediatamente: Flutter à esquerda, Kivy e KivyMD à direita.
Alguns elementos da interface do usuário são diferentes, não devido a alguns recursos técnicos, pelos quais era impossível obter um resultado idêntico, mas eu apenas pensei que seria mais orgânico (por exemplo, a Barra de Ferramentas preta, na minha opinião, não parece nada).
Então! O que é surpreendente ao olhar para a tela que vamos tocar? Layout frontal de fundo transparente. No Kivy, essa opção é fornecida pelo FloatLayout, que permite colocar widgets e controles um acima do outro, da seguinte maneira:
Esquematicamente, nossa tela ficará assim:
O layout desta tela é bastante simples:
Por que estou falando do FloatLayout se nossa tela é herdada da Screen?
<ProductScreen@Screen>: ...
Só porque Tela -> RelativeLayout -> FloatLayout.
Todos os widgets no FloatLayout são posicionados no canto inferior esquerdo, ou seja, na tela eles recebem a posição automaticamente (0, 0). Na marcação, não é difícil rastrear a ordem de adicionar elementos à tela de cima para baixo:
Se alguém prestou atenção, indicamos a posição para apenas um widget:
MDToolbar: ... pos_hint: {"top": 1}
Além das coordenadas específicas (x, y), cada widget no Kivy pode receber uma dica de posição:
pos_hint: {"top": 1}
Então, a imagem de fundo inferior ...
BoxLayout: size_hint_y: None height: root.height - toolbar.height FitImage: source: "smokestackheather.jpeg"
... graças ao widget FitImage (biblioteca KivyMD), ele é estendido automaticamente para todo o espaço alocado, mantendo as proporções da imagem:
Por padrão, cada widget e layout no Kivy recebe 100% do espaço, a menos que seja especificado de outra forma. Por exemplo, se você deseja adicionar um botão à tela, obviamente fará o seguinte:
from kivy.app import App from kivy.lang import Builder KV = """ Button: text: "Button" """ class MyApp(App): def build(self): return Builder.load_string(KV) MyApp().run()
E obtenha o resultado:
O botão ocupou 100% do espaço. Para colocar um botão no centro da tela, primeiro é necessário fornecer o tamanho necessário e, em segundo lugar, indicar onde será localizado:
from kivy.app import App from kivy.lang import Builder KV = """ Button: text: "Button" size_hint: None, None size: 100, 50 pos_hint: {"center_y": .5, "center_x": .5} """ class MyApp(App): def build(self): return Builder.load_string(KV) MyApp().run()
Agora a imagem mudou:
Você também pode especificar a propriedade
size_hint , de 0 a 1 (equivalente a 0-100%), ou seja, a dica de tamanho:
from kivy.app import App from kivy.lang import Builder KV = """ BoxLayout: Button: text: "Button" size_hint_y: .2 Button: text: "Button" size_hint_y: .1 Button: text: "Button" """ class MyApp(App): def build(self): return Builder.load_string(KV) MyApp().run()
Ou a mesma coisa, mas a dica de largura (
size_hint_x ):
from kivy.app import App from kivy.lang import Builder KV = """ BoxLayout: Button: text: "Button" size_hint_x: .2 Button: text: "Button" size_hint_x: .1 Button: text: "Button" """ class MyApp(App): def build(self): return Builder.load_string(KV) MyApp().run()
O MDToolbar tem uma altura de 56dp, não pode ocupar todo o espaço e, se você não informar que o local está no topo, ele ficará automaticamente na parte inferior da tela:
A lista de cartões, OrderProductLayout (falaremos sobre isso a seguir), é um ScrollView com elementos MDCard e ocupa toda a altura da tela, mas graças ao preenchimento (valores de indentação em pontos baixos) parece estar localizado um pouco acima do centro da tela. Bem, por padrão, o MDBottomAppBar lança âncora na borda inferior da tela. Portanto, apenas o MDToolbar indicamos onde está o seu lugar.
Agora vamos ver o que é o widget OrderProductLayout:
Como você pode ver, essas são quatro placas incorporadas no ScrillView. Diferentemente da tela pai, herdada do FloatLayout, aqui todos os widgets são lidos de cima para baixo.
Isso é muito conveniente, pois existe uma hierarquia clara de widgets, uma estrutura em árvore e, à primeira vista, fica claro qual widget / controle pertence a qual layout. No Kivy, o layout usado mais comum é o BoxLayout - uma caixa que permite colocar widgets dentro de si vertical ou horizontalmente (por padrão - o último):
Isso pode ser visto com mais clareza no diagrama a seguir, onde a orientação horizontal BoxLayout é usada:
Proibimos o BoxLayout de usar 100% do espaço -
size_hint_y: None e disse - sua altura será exatamente a mesma que a altura do elemento mais alto aninhado em você -
height: self.minimum_height .
Lista de Imagens:
Se quiséssemos usar a rolagem vertical da lista, precisaríamos alterar o GridLayout da seguinte maneira:
ScrollView: GridLayout: size_hint_y: None height: self.minimum_height cols: 1
Substitua linhas (colunas) por colunas (colunas) e indique no
mínimo não a largura, mas a altura:
from kivy.app import App from kivy.lang import Builder from kivy.metrics import dp from kivy.uix.button import Button KV = """ ScrollView: GridLayout: id: box size_hint_y: None height: self.minimum_height spacing: "5dp" cols: 1 """ class MyApp(App): def build(self): return Builder.load_string(KV) def on_start(self): for i in range(20): self.root.ids.box.add_widget( Button( text=f"Label {i}", size_hint_y=None, height=dp(40), ) ) MyApp().run()
Os seguintes cartões são a escolha da cor e tamanho (eles são quase idênticos):
Um recurso distintivo da linguagem de marcação da Kv Language não é apenas a estrutura clara dos widgets, mas também o fato de que essa linguagem suporta alguns recursos da linguagem Python. A saber: chamar métodos, criar / alterar variáveis, operações lógicas, E / S e matemáticas ...
Calculando o
valor declarado no
Label ...
Label: value: 0 text: str(self.value)
... acontece diretamente na própria marcação:
MDIconButton: on_release: label_value.value -= 1 if label_value.value > 0 else 0
E eu nunca vou acreditar que isso (código Flutter) ...
... mais lógico e legível que o código da linguagem Kv:
Ontem me perguntaram como o Kivy está indo com o ambiente de desenvolvimento. Existem autocomplits, hotloads e outras comodidades? Com o preenchimento automático, tudo fica bem se você usar o PyCharm:
Quanto ao hotload ... Python é uma linguagem interpretada. O Kivy usa Python. Portanto, para ver o resultado, você não precisa compilar o código, executá-lo - consulte / teste. Como eu disse, o Kivy não usa APIs nativas para renderizar a interface do usuário; portanto, você pode emular vários modelos de dispositivos e plataformas usando o módulo de
tela . É suficiente executar seu projeto com os parâmetros necessários para que a janela do aplicativo testado seja aberta no computador como se estivesse sendo executado em um dispositivo real. Parece estranho, mas como o Kivy abstrai da plataforma na renderização da interface do usuário, isso elimina a necessidade de emuladores pesados e lentos para testes. Isso se aplica apenas à interface do usuário. Por exemplo, o aplicativo de teste descrito neste artigo foi testado com as opções de
tela -m: droid2, portrait, scale = .75 .
À esquerda - executando em um dispositivo móvel, à direita - em um computador:
Lista completa de parâmetros do módulo de tela: Bem, e finalmente, o resultado final é o lançamento em um dispositivo móvel ...
A única coisa que incomoda é a velocidade de lançamento. No mesmo Flutter, ela é simplesmente fenomenal!
Espero ter sido útil para alguém, até breve!