9 marca 2018

Tutorial – Aplikacja okienkowa python – kivy – ustawiamy widgety

Witam, jakiś czas temu wrzuciłem na blog informację o tym, jak zrobić pierwszą aplikację okienkową w pythonie, przy pomocy kivy. Teraz postaram się opisać w jaki sposób przy pomocy layoutów GridLayout oraz BoxLayout ustawić odpowiednio widgety. No więc wykonamy prosty ekran logowania w Kivy. Do dzieła!

Pierwszą rzecz którą powinniśmy zrobić, to załadować standardowo bibliotekę kivy. Poniżej możemy zadeklarować jaką minimalną wersję biblioteki wymaga nasz program (nie jest to konieczne, lecz warto o tym pamiętać).

import kivy
kivy.require('1.0.7')

W dalszych liniach kodu będziemy importować konkretne „składniki” z biblioteki kivy.
Do wykonania aplikacji okienkowej potrzebujemy:

  • kivy.app do działania samego programu
  • kivy.uix.label w celu wyświetlenia tekstu na ekranie
  • kivy.uix.gridlayout aby ustawić główny layout programu
  • kivy.config aby ustawić standardowe elementy programu, np. rozdzielczość, fullscreen itd.
  • kivy.lang przydatne, aby zaimportować plik kv w którym ustawia się widok naszej aplikacji oraz akcje użytkownika

Teraz rzut okiem na kod programu:

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.config import Config
from kivy.lang import Builder

Ustawmy teraz standardową konfiguracje programu:

Config.set('graphics', 'resizable', '0')
Config.set('graphics', 'width', '500')
Config.set('graphics', 'height', '300')
Config.set('graphics', 'fullscreen', '0')

Pierwsza linia ustawień oznacza, ze naszego programu nie da się skalować. Następne dwie ustawiają standardowe okno programu na rozdzielczość 500×300. Ostatnia odpowiada za wyświetlenie programu w oknie.

Możemy teraz podać ścieżkę do pliku kv. Nie musimy tego jednocześnie robić.

Plik kv zostanie automatycznie załadowany, jeśli jego nazwa będzie odpowiadała głównej klasie programu.
Jeśli nazwa pliku kv będzie inna, możemy go załadować przy pomocy poniższej linii kodu:

Builder.load_file('myapp.kv')

Pamiętaj! Jeśli plik kv zostanie załadowany automatycznie, a dodatkowo umieścisz powyższą linię kodu, zostanie on załadowany dwukrotnie.

 

Tworzymy teraz główną klasę programu, niech będzie to klasa o nazwie MyApp()

class MyApp(App):
    def build(self):
        return LoginScreen()

MyApp().run()

Do klasy MyApp przekazujemy w parametrze klasę App, dla tego musieliśmy ją zaimportować (patrz: ładowanie klas kivy).
Klasa MyApp posiada wewnątrz funkcję build (tego od nas wymaga Kivy), zwraca nam klasę LoginScreen() (tą stworzymy za chwilę)

Na samym końcu uruchamiamy nasz program pisząc MyApp().run()

Co kryje się w klasie LoginScreen ?

W klasie Login Screen zdefiniujemy funkcję click() i na razie nic poza tym.

Przejdźmy teraz do pliku myapp.kv

Na początku pliku myapp.kv wpiszmy jakiej klasy będzie się tyczyła struktura którą aktualnie wykonujemy, czyli zaczynamy od:

<LoginScreen>:

typ layoutu jaki przekazaliśmy to GridLayout, więc możemy zadeklarować ilość wierszy i kolumn:

cols: 1
rows: 2

Następnie ustalimy kolor tła całego programu na szary:

canvas.before:
        Color:
            rgba: 0.54, 0.54, 0.54, 1
        Rectangle:
            pos: self.pos
            size: self.size

Po ustawieniu koloru, „wstawiamy” widget Grid Layout (tak, layout jest tutaj również widgetem) oraz poniżej Box Layout. W BoxLayout wrzucamy jedynie Button z odpowiednimi parametrami.
W GridLayout ustawiamy cols i rows równe 2, czyli robimy dwie kolumny, oraz dwa wiersze. W pierwszym oknie wrzucamy Label Login, w drugim BoxLayout z TextInput. W wierszu drugim wrzucamy znów Label Password, a obok BoxLayout z TextInput. Całość będzie o wiele bardziej czytelna po spojrzeniu na poniższe screeny oraz kod:

GridLayout:
        cols: 2
        rows: 2

        Label:
            text: 'Login'
        BoxLayout:
            TextInput:
                id: username
                multiline: False
                text: 'radian'
                size_hint_y: 0.4
                pos_hint: {'center_y': .5}

        Label:
            text: 'Password'
        BoxLayout:
            TextInput:
                id: password
                password: True
                size_hint_y: 0.4
                pos_hint: {'center_y': .5}

    BoxLayout:
        Button:
            size_hint_y: 0.3
            pos_hint: {'bottom': 1}
            text: 'Zaloguj się'
            on_press:root.click(username.text,password.text)

 

Po powyżej wykonanych czynnościach, zobaczymy nasz LoginScreen, lecz przycisk Zaloguj odwołuje się do klasy click przekazując jej parametry z TextInput, należy to obsłużyć. Wracamy więc do naszego pliku głównego aplikacji py.

W klasie LoginScreen tworzymy metodę click, odbieramy parametry i dopisujemy obsługę:

def click(self,username,password):
    self.clear_widgets()

    self.success = Label(text='udane logowanie')
    self.failed = Label(text='nie udane logowanie')

    if username == 'radian' and password == 'haslo':
        self.add_widget(self.success)
    else:
        self.add_widget(self.failed)

Powyżej odbieramy parametry przekazane do funkcji, ustawiamy dwa nowe label, dla sukcesu oraz dla błędnych danych. Tworzymy prosty warunek if i wyświetlamy odpowiedni label. Pamiętaj! Wcześniej usuwamy wszystkie widgety za pomocą clear_widgets().

Cały program możemy ściągnąć z poniższego linka do GitHub:

https://github.com/govr/LoginScreen