Python GUI mit KIVY – Weitere Ansichten (Views)

Der Benutzer hat also unsere App betreten. Dann sollten wir ihm auch was bieten!
Mit mehreren Views zu arbeiten, ist mit Kivy kinderleicht. In dem Beitrag zeige ich dir, was der Screenmanager ist, wie er funktioniert und wie einfach du zwischen den Views hin und her wechseln kannst.

Hier hast du einen Überblick über die bisherigen Teile der Serie:

Unsicher mit Git?
Lade jetzt dein Git CheatSheet herunter!

Kivy Serie

Ziel

In dem Artikel wollen wir der Kivy App einen neuen View hinzufügen.
Am Ende soll der Benutzer sich mit seinem Namen anmelden und zwei Sekunden später automatisch auf die neue Ansicht geleitet werden.

Die neue Ansicht unserer Kivy GUI App ist in zwei Bereiche unterteilt.
Oben ist ein scrollbarer Teil, in dem später die Aktienwerte dargestellt werden.
Darunter gibt es ein Eingabefeld für die Eingabe der Ticker Symbole.

Kivy Mobile App - Neuer View
Kivy Mobile App – Neuer View

WelcomeView auslagern

Aktuell passiert noch alles in der build-Funktion unserer Kivy App.
Um mit mehreren Views zu arbeiten, ist das natürlich eher schlecht.
Daher ist der erste Schritt, dass wir für den Willkommen-Bildschirm eine eigene View Klasse anlegen.

View Klassen sind einfach nur Klassen, die von einem Layout ableiten.
Mussten wir also vorher noch sagen:

self.window = GridLayout()

Reicht es jetzt die Klasse davon ableiten zu lassen:

class WelcomeView(GridLayout):

Alles Andere wandert jetzt in die __init__() Funktion der Klasse.
Also alle Konfigurationen, Größen, Widgets….
Copy & Paste in die __init__() Funktion der neuen Klasse.

Als erste Zeile fügen wir noch einen Aufruf an den übergeordneten __init__() ein, damit das Layout auch ordentlich bereit gestellt wird.
Der Welcome View sollte damit so aussehen:

class WelcomeView(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.cols = 1
        self.size_hint = (0.6, 0.7)
        self.pos_hint = {
            'center_x': 0.5,
            'center_y': 0.5
        }

        self.add_widget(Image(source='logo_weiß.png'))
        self.greeting = Label(text='Wie heißt du?',
                              font_size=18,
                              color='#33cccc')
        self.add_widget(self.greeting)
        self.user = TextInput(multiline=False,
                              padding_y=(20, 20),
                              size_hint=(1, 0.5)
                              )
        self.add_widget(self.user)
        self.entrance_button = Button(text='Eintreten',
                                      size_hint=(1, 0.5),
                                      bold=True,
                                      background_color='#33cccc',
                                      background_normal='')
        self.entrance_button.bind(on_press=self.entrance_button_behaviour)
        self.add_widget(self.entrance_button)

    def entrance_button_behaviour(self, *args):
        self.greeting.text = f'Herzlich Willkommen {self.user.text}.'

Die Funktion für den entrance_button muss natürlich auch mit in die Klasse.

Kivy Screenmanager anlegen

Alles klar. Der Willkommen-Bildschirm hat jetzt seinen eigenen View bekommen.
Damit kannst du ihn aus der build-Funktion der App löschen.
Aber was dann?
Irgendwas muss ja weiter in der build Funktion passieren. Sonst wird nichts dargestellt.

Genau dafür gibt es den ScreenManager.
Er kümmert sich darum, die verschiedenen Ansichten darzustellen.

In der build-Funktion erzeugst du also zuerst einen neuen ScreenManager.
Und genau der wird dann auch im return wieder zurückgegeben:

# from kivy.uix.screenmanager import ScreenManager

class MyApp(App):
    def build(self):
        # ScreenManager übernimmt die Arbeit welcher View angezeigt werden soll
        self.screen_manager = ScreenManager()

        # ScreenManager zurückgeben, um die Views verfügbar zu machen
        return self.screen_manager

Fertig ist der ScreenManager!
Natürlich ist der noch leer, hat keine Ahnung von den Screens und hilft uns demnach mal so überhaupt nicht.
Dann sorgen wir doch mal dafür, dass WelcomeView und Screenmanager in Kontakt treten!

WelcomeView zum Kivy Screenmanager zufügen

Der ScreenManager benötigt zwei Dinge.
Zum einen den Namen, unter dem der View zu finden ist, zum anderen eine Instanz von dem View, die er aufrufen kann.

Die Instanz können wir direkt als Variable in unserer App ablegen:

self.welcome_view = WelcomeView()

Den Namen für den View können wir nicht einfach so angeben.
Für den ScreenManager muss auch klar sein, welcher View und welcher Name zusammen gehören.
Deswegen wird beides zusammen in einen Screen verpackt.
Immerhin ist es ja ein ScreenManager und kein ViewManager 😉

Wir legen also zuerst einen Screen an und übergeben dabei direkt den Namen.
Im Anschluss wird noch das Widget – also unser View – angehängt.
Genau so, wie wir vorher schon Widgets angehängt haben. Über eine add_widget Funktion:

# from kivy.uix.screenmanager import Screen

screen = Screen(name='welcomeView')
screen.add_widget(self.welcome_view)

Als letzter Schritt muss der Screen an den ScreenManager übergeben werden.
Auch das funktioniert wieder über die bekannte Funktion add_widget.

self.screen_manager.ad_widget(screen)

Fertig.
Damit haben wir den Willkommensbildschirm erfolgreich aus der build Funktion ausgelagert.
Der WelcomeView ist der erste Screen im ScreenManager.
Daher wird er als Standard zuerst aufgerufen und angezeigt. Wir müssen also nichts weiter dafür tun.

Der ScreenManager soll natürlich auch einen Sinn haben.
Also geht’s an den nächsten View: Die Darstellung der Aktien im StockView.

StockView anlegen

Der StockView soll zwei Aufgaben erfüllen:

  • Zufügen von Aktien Ticker Symbolen
  • Darstellen der Aktien und ihrer Daten

Dafür wollen wir den Bildschirm in zwei Bereiche unterteilen.
Oben gibt es eine lange, scrollbare Liste mit all den Aktiendaten, die wir schon zugefügt haben.
Unten am Bildschirm fügen wir eine Zeile an, mit einem Eingabefeld und einem Zufügen Button.
In etwa so soll das aussehen:


'''
Ticker      Name        Preis       Löschen
Ticker      Name        Preis       Löschen
------------------------------------------
Label   Tickereingabe               Zufügen
'''

Aber zuerst brauchen wir eine Klasse für unseren View.
Der View soll mehrere Zeilen (zwei) haben, also bietet sich auch hier wieder ein GridLayout an.

Wie schon beim WelcomeView wollen wir auch hier nicht die volle Bildschirmgröße verwenden.
Ein wenig Abstand vom Rand sieht immer ganz gut aus.
Das machen wir also gleich mit. Zusammen mit dem nötigen zentrieren:

class StockView(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.cols = 1
        self.size_hint = (0.9, 0.9)
        self.pos_hint = {
            'center_x': 0.5,
            'center_y': 0.5
        }

Sehr schön. Damit haben wir einen View mit einer Spalte, 90 % Bildschirmbreite und -höhe und zentriert ist das Bild auch.

Dann kümmern wir uns direkt um den oberen Teil:
Der soll ja scrollbar sein. Sonst verschwinden zugefügte Aktien irgendwann. Das wäre nicht so schick.

Der ScrollView

Dafür gibt Kivy uns eine Klasse ScrollView.
Der ScrollView kann allerdings nur ein Widget entgegennehmen. Wir brauchen aber mehrere.
Deswegen müssen wir in diesen ScrollView jetzt erstmal ein GridLayout packen.
Warum ein GridLayout?
Einfach. Die Aktienliste besteht aus mehreren Zeilen (den Aktien) und aus vier Spalten (den verschiedenen Daten).

Eins müssen wir noch beachten:
Der ScrollView darf natürlich nicht die volle Bildschirmhöhe einnehmen.
Immerhin soll ja noch Platz für die Eingabezeile unten am Bildschirm bleiben.
Also setzen wir die Größe direkt auf 90 %.

Kurz zusammen gefasst:

  • ScrollView mit 90 % Breite erzeugen
  • GridLayout mit vier Spalten konfigurieren
  • GridLayout zum ScrollView zufügen
  • ScrollView zum StockView (unserem Bildschirm) zufügen.
# from kivy.uix.scrollview import ScrollView

self.stock_view = ScrollView(size_hint=(1, 0.9))
self.stock_list = GridLayout(cols=4)
self.stock_view.add_widget(self.stock_list)
self.add_widget(self.stock_view)

Hmm… vier Punkte in unseren To-dos und vier Zeilen Code um sie abzuarbeiten…
Python ist schon ne coole Sprache 😉

Als Nächstes kümmern wir uns um die Eingabe neuer Aktien.
Dafür brauchen wir eine Zeile und drei Spalten.
Klingt schon wieder nach einem GridLayout, oder?

Genau das benutzen wir auch dafür.
Der ScrollView hat schon 90 % der Bildschirmhöhe bekommen. Also bleiben noch 10 % für das Eingabefeld übrig.

self.stock_add = GridLayout(cols=3, size_hint=(1, 0.1))
self.add_widget(self.stock_add)

So schnell ist das Layout zugefügt. Drei Spalten, 10 % Höhe, volle Breite.

Dann müssen nur noch die Inhalte rein:
Ein Label, damit wir später auch wissen, wofür das Eingabefeld ist.
Ein Eingabefeld natürlich. Auch wieder als einzelne Eingabezeile.
Und abschließend noch ein Button zum Hinzufügen.

Hier kannst du nochmal nachlesen, wie das mit den Größen und dem Styling funktioniert.

self.ticker_text = Label(text='Symbol/Ticker:',
                         size_hint=(0.2, 0.5))
self.stock_add.add_widget(self.ticker_text)

self.ticker_input = TextInput(multiline=False,
                              padding_y=(10, 10),
                              size_hint=(0.6, 0.5))
self.stock_add.add_widget(self.ticker_input)

self.ticker_add = Button(text='Zufügen',
                         size_hint=(0.2, 0.5),
                         bold=True,
                         background_color='#33cccc',
                         background_normal='')
self.ticker_add.bind(on_press=self.add_ticker_symbol)
self.stock_add.add_widget(self.ticker_add)

Wie schon beim letzten Mal setzen wir direkt wieder eine Funktion an den Button.
Sonst vergessen wir es nur und wundern uns dann, dass es nicht funktioniert.

Die Funktion selbst ist eher überschaubar.
Wir wollen aktuell ja nur wissen, ob alles geklappt hat.
Eine einfache Ausgabe auf der Konsole reicht dafür vollkommen aus:

def add_ticker_symbol(self, *args):
    print('Test für das zufügen von Aktien')

Die Funktion ist natürlich Teil der Klasse.

Fertig ist unser StockView!
War gar nicht mal so schwer, oder?

Jetzt wollen wir die Aktien Ansicht natürlich noch aufrufen. Sonst wär ja alles umsonst gewesen.
Dafür müssen wir ihn wieder dem ScreenManager bekannt machen.

StockView zum Kivy ScreenManager zufügen

Wie schon beim WelcomeView genügen ein paar wenige Zeilen:

self.stock_view = StockView()
screen = Screen(name='stockView')
screen.add_widget(self.stock_view)
self.screen_manager.add_widget(screen)

Wir erzeugen eine Insatanz der View Klasse – in dem Fall vom StockView.
Dann wird ein Screen erzeugt und ein Name vergeben.
Und im Anschluss wird die Instanz an den Screen gehängt und der Screen an den ScreenManager.
Fertig.

Der Code wird nach unserem WelcomeView und vor dem return in die build Funktion der App eingebaut.

StockView anzeigen

Wir haben jetzt einen StockView und wir haben ihn dem ScreenManager bekannt gemacht.
Was fehlt dann noch?
Na klar. Wir müssen dem ScreenManager auch mitteilen, wann er den StockView aufrufen soll!

In unserem WelcomeView gibt es schon die Funktion entrance_button_behaviour.
Aktuell wird hier nur ein Text ausgegeben.
Unser Ziel ist es, nach der Textausgabe auf den StockView weiterzuleiten.

Ein Umschalten zwischen den Views geht ganz einfach über den vergebenen Namen:

app.screen_manager.current = 'stockView'

Über app erhalten wir Zugriff auf die gesamte App.
Das ist die Variable, die wir in der if __name__ == ‘__main__’ definiert haben.

An die App haben wir den ScreenManager gehängt.
Das ist in der build Funktion unserer App passiert.

Und mit current können wir jetzt einfach zwischen den Views hin und her wechseln.

Am einfachsten wäre es also, die Zeile direkt in unsere entrance_button_behaviour Funktion zu legen.
Dann haben wir allerdings ein Problem…
Der View wechselt SOFORT.

Und wir wollen unserem Benutzer doch die Chance geben, unsere Nachricht lesen zu können, richtig?
Also müssen wir irgendwie verzögern.
Das könnten wir natürlich irgendwie hacky über ein sleep lösen…
Aber Kivy gibt uns dafür direkt ein Werkzeug mit an die Hand: Clock

Mit Clock können wir Aktionen einplanen.
Dafür brauchen wir – wie bei Buttons – eine Funktions-Referenz und eine Zeit, nach der etwas ausgeführt werden soll.
Dafür bietet Clock die Funktion schedule_once an.

Zuerst brauchen wir also eine eigene Funktion für den View-Wechsel:

def switch_to_next_view(self, *args):
    app.screen_manager.current = 'stockView'

Die Funktion wird aus unserem WelcomeView aufgerufen. Ist also auch Bestandteil der WelcomeView Klasse.

Dann können wir die entrance_button_behaviour Funktion anpassen:

# from kivy.clock import Clock

def entrance_button_behaviour(self, *args):
    self.greeting.text = f'Herzlich Willkommen {self.user.text}.'
    Clock.schedule_once(self.switch_to_next_view, 2)

Es muss lediglich eine Zeile zugefügt werden.
Über die Clock rufen wir die Funktion schedule_once auf und übergeben zuerst die Funktions-Referenz.
Der zweite Parameter ist die Zeit, nach der die Aktion ausgeführt werden soll.
Angegeben in Sekunden.

Bei Klick auf den Button soll also weiter unser Text angezeigt und nach zwei Sekunden auf den StockView gewechselt werden.

Das war’s!

Zusammenfassung

In dem Artikel hast du gesehen, wie du eine App mit mehreren Views bauen kannst.
Mit dem ScreenManager haben wir Views verwaltet und aufgerufen.
Und über Clock haben wir die Ausführung für später eingeplant.

Wenn du sehen willst, wie es weiter geht, verpasse auf keinen Fall den nächsten Artikel der Serie!
Trag dich am besten direkt in den Newsletter ein und werde informiert, wenn ein neuer Artikel online geht!

Wie kannst du am schnellsten Summen... x
Wie kannst du am schnellsten Summen bilden? Python Built-Ins | #Shorts

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht.

Scroll to Top
ANFORDERN
Anfordern
Bereit zum Ausdrucken | Mit Erklärungen
IMMER ZUR HAND
ANFORDERN
Anfordern
Bereit zum Ausdrucken | Mit Erklärungen
IMMER ZUR HAND
Trag dich schnell ein und bekomme Zugang zum Download!
Gib mir den Download!