In der App soll der Benutzer Aktien beobachten können. Dafür kann er nach und nach über die Ticker Symbole Aktien zu einer Liste hinzufügen. Werden es zu viele, würde die Liste aber einfach aus dem Bildschirm wandern!
Nicht gerade benutzerfreundlich.
Um das zu vermeiden, werden wir mit dem ScrollView eine scrollbare Liste mit Aktiendaten in unseren View einbauen.
Damit bleiben die Aktien immer im Blick und können einfach durch gescrollt werden!
Kivy Serie
- Erste Schritte mit Fenstern
- Den Benutzer Willkommen heißen
- Die Verpackung zählt!
- Weitere Ansichten (Views)
- Scrollbare Liste mit Aktiendaten
- Aktiendaten API anbinden (yfinance)
- Fehler “Instruction outside the main Kivy thread”
- Element aus dem Layout entfernen
- Aktien in der Watchlist speichern
Ziel ist es also, eine scrollbare Liste mit Aktiendaten zu generiere.
Im letzten Artikel haben wir dafür bereits einen View angelegt.
In dem View gibt es bereits zwei Bereiche.
Einmal am unteren Bildschirmrand die Zeile für die Ticker Symbol Eingabe.
Und einmal einen leeren Bereich, in den wir jetzt unsere scrollbare Liste mit Aktiendaten einfügen wollen.
Dummy Daten vorbereiten
Es ist immer wichtig, zu sehen, woran man arbeitet.
Aktuell haben wir alle Komponenten in unserer App.
Eine ScrollView mit einem GridLayout, dass auch schon die richtige Anzahl an Spalten für unsere Aktiendaten enthält.
Aber ohne Daten in den Komponenten zu haben, sehen wir nicht wirklich, was sich darin abspielt.
Geschweige denn, was wir da eigentlich konfigurieren.
Direkt eine API anbinden ist aber auch zu viel des Guten.
Mal abgesehen von der Menge an Anfragen und dem Zeitverlust durch die Anfragen während der Entwicklung.
Was machen wir faulen Entwickler? Wir finden den einfachen Weg und benutzen Mock-Objekte (Dummy Daten).
Damit können wir bequem die Komponenten füllen und sehen sofort, was sich darin abspielt.
Wir können Funktionalitäten und Styling anpassen, ohne von Internet abhängig und ggf. langsamen Antwortzeiten belästigt zu werden.
Mit add_ticker_symbol(self, *args): haben wir bereits die Funktion geschaffen, die Daten zu unserer scrollbaren Liste mit Aktiendaten hinzufügen soll.
Später wird hier eine API abgefragt, Daten gesammelt und aufbereitet und das Ergebnis-Objekt in die Komponente gefüllt.
Die ganze Arbeit sparen wir uns jetzt und schreiben einfach direkt unser Wunsch-Ergebnis-Objekt.
Hard coded direkt in die Funktion.
def add_ticker_symbol(self, *args):
dummy_data = {
'ticker': 'MSF.DE',
'name': 'Microsoft',
'price': '99,42 €'
}
So einfach kann es sein 😉
Dann machen wir mal weiter.
Die Daten müssen jetzt in einer Zeile angezeigt werden.
Aktien Zeile erstellen
Einzelne Funktionalitäten sollten immer in einzelnen Funktionen gruppiert sein.
Deshalb kommt auch das Erstellen einer Zeile in eine eigene Funktion.
Die Funktion ist Teil unserer StockView Klasse.
Wir wollen Texte anzeigen. Und Anzeigen werden immer über Kivy Label umgesetzt.
Das heißt, wir müssen für jede Spalte in unserer Aktien Zeile ein Label erzeugen.
Jedes Label wiederum muss der stock_list Komponente hinzugefügt werden.
Zur Erinnerung: stock_list ist das GridLayout, dass die einzelnen Zeilen darstellen soll und im ScrollView hinterlegt ist.
def add_ticker_row(self, ticker, name, price):
ticker = Label(text=ticker)
self.stock_list.add_widget(ticker)
name = Label(text=name)
self.stock_list.add_widget(name)
price = Label(text=price)
self.stock_list.add_widget(price)
delete = Button(text='Entfernen')
delete.bind(on_press=self.remove_ticker_row)
self.stock_list.add_widget(delete)
def remove_ticker_row(self, *args):
print('Aktien entfernen')
Alles klar. Damit sind Ticker Symbol, Name, Preis und einen Entfernen-Button zur Zeile hinzugefügt.
Die Daten kommen aus den Parametern der Funktion.
Für den Button haben wir wieder eine Dummy Funktion, die erstmal einfach nur etwas auf die Konsole ausgibt.
Jetzt müssen wir die Funktion nur noch aufrufen.
Der Aufruf geschieht natürlich da, wo wir unsere Daten sammeln.
Bzw. aktuell noch die Dummy Daten erstellen.
Also in der Funktion add_ticker_symbol.
self.add_ticker_row(dummy_data['ticker'], dummy_data['name'], dummy_data['price'])
Wenn du alles bis hier hin mit gemacht hast, sollte deine App in etwa so aussehen:
Das ist natürlich noch nicht schön.
Aber hey! Die Daten sind da! Die Funktionalität ist also da!
Aktien Zeile aufteilen
Aktuell verteilen sich die Größen der Spalten noch frei Schnauze.
Das soll natürlich nicht sein. Nur weil sich Inhalte (Namen zum Beispiel) ändern, sollen sich die Breiten ja nicht einfach mal anpassen.
Mit dem bereits bekannten size_hint_x können wir auch hier an den Komponenten einfach wieder ihre Breite festsetzen.
Dabei orientieren sie sich auch wieder an der umgebenden Komponente. Also dem GridLayout.
Eine Breite von 0.2 – also 20 % der Breite – ist demnach nicht 20 % der Bildschirmbreite, sondern 20 % der Breite des GridLayout.
def add_ticker_row(self, ticker, name, price):
ticker = Label(text=ticker, size_hint_x=0.2)
self.stock_list.add_widget(ticker)
name = Label(text=name, size_hint_x=0.4)
self.stock_list.add_widget(name)
price = Label(text=price, size_hint_x=0.2)
self.stock_list.add_widget(price)
delete = Button(text='Entfernen', size_hint_x=0.2)
delete.bind(on_press=self.remove_ticker_row)
self.stock_list.add_widget(delete)
Und schon geben wir vor, wie sich die Daten innerhalb der Zeile verteilen sollen.
Aktien Zeile stylen
Als Letztes fehlt noch die Höhe der Zeile.
Immer kleiner werdend, nur weil mehr Daten hinzukommen ist ja nicht wirklich was wir wollen.
Das sieht ja nach nichts aus.
Lass uns also noch eben die Höhe einer jeden Zeile festlegen.
Das machen wir direkt über das GridLayout.
Zunächst die Breite des GridLayout.
Hier können wir einfach eine 1 setzen. Wir nehmen also die volle verfügbare Breite.
Auch hier bedenken, dass es sich nur um die verfügbare Breite handelt.
Der StockView hat bereits eine Breite von 90 % der Bildschirmbreite. Damit kann keine Komponente im StockView breiter sein.
Für die Höhe wird es jetzt etwas tricky.
Wir wissen die Höhe bei der Erstellung nicht.
Die Höhe des gesamten GridLayout ändert sich ja mit jedem Eintrag in unsere Liste mit Aktiendaten.
Um dem gerecht zu werden, können wir die Höhe einfach auf die minimal nötige Höhe setzen.
Das erzielen wir mit height=self.minimum_height.
Das heißt, unser GridLayout kann jetzt mit der Anzahl der Einträge mit wachsen.
Da geht es jetzt noch an die Zeilenhöhe.
Dafür gibt es das Attribut row_default_height.
Damit können wir eine Standardhöhe für eine Zeile festsetzen.
Kombiniert wird das mit dem Attribut row_force_default=True.
Damit wird dann forciert, dass die Standardwerte auch genutzt werden sollen.
self.stock_list = GridLayout(cols=4,
size_hint=(1, None),
height=self.minimum_height,
row_default_height=30,
row_force_default=True)
Das sieht doch gleich viel besser aus!
Und wenn du jetzt genug Daten zufügst, dass der Bildschirm voll ist, dann wächst der Inhalt auch einfach über den Bildschirmrand hinaus und lässt sich scrollen.
Zusammenfassung
Einmal zusammengefasst, was wir gemacht haben:
- Dummy Daten vorbereitet
- Keine API Aufrufe während der Entwicklung
- Zeitersparnis, da keine API angebunden werden muss
- Funktion zur Erstellung der einzelnen Zeilen
- Dummy Daten werden an die Funktion übergeben, die sich um die Erstellung der Zeilen kümmert
- Spaltenbreiten innerhalb der Zeile festsetzen
- Zeilenhöhe festsetzen
Ingo Janssen ist ein Softwareentwickler mit über 10 Jahren Erfahrung in der Leitung seines eigenen Unternehmens.
Er studierte Wirtschaftsinformatik an der TH Deggendorf und hat Softwareentwicklung an der FOM Hochschule in München unterrichtet.
Ingo hat mit einer Vielzahl von Unternehmen zusammengearbeitet, von kleinen und mittelständischen Unternehmen bis hin zu MDAX- und DAX-gelisteten Unternehmen.
Ingo ist leidenschaftlich daran interessiert, sein Wissen und seine Expertise mit anderen zu teilen. Aus diesem Grund betreibt er einen YouTube-Kanal mit Programmier-Tutorials und eine Discord-Community, in der Entwickler miteinander in Kontakt treten und voneinander lernen können.
Sie können Ingo auch auf LinkedIn, Xing und Gulp finden, wo er Updates über seine Arbeit teilt und Einblicke in die Tech-Branche gibt.
YouTube | Discord | LinkedIn | Xing | Gulp Profile