Kontakt Ihre Anfrage

Erste Schritte mit der LVGL-Bibliothek

Veröffentlicht am 2026-11-08

LVGL ist eine offene, kostenlose Bibliothek zur Erstellung grafischer Benutzeroberflächen für eingebettete Geräte. Sie verfügt über zahlreiche Funktionen und Integrationen, wodurch sie sich hervorragend für den Aufbau sowohl einfacher als auch komplexer Schnittstellen eignet. Sie bietet eine breite Auswahl an Komponenten. Dank fertiger Integrationen mit externen Bibliotheken ist die Verwendung von Bildern in den Formaten PNG, JPEG oder WEBP; Animationen im Lottie-Format; Schriftarten im TrueType-, OpenType- oder WOFF-Format möglich; sogar das Laden von 3D-Modellen im glTF-Format ist möglich. Die Bibliothek unterstützt Mikrocontroller von Herstellern wie STMicroelectronics (STM32-Serie), Espressif oder NXP.

LVGL kann die Möglichkeiten moderner Mikroprozessoren für HMI-Anwendungen nutzen. Sie verfügt über eine fortschrittliche Rendering-Engine, die das Zeichnen von Bögen, halbtransparenten Elementen und Verläufen unterstützt. Zusätzlich sind eingebaute Treiber für dedizierte Grafikchips einiger Mikroprozessoren vorhanden.

Die Bibliothek kann eingeschränkt werden, sodass sie auch auf schwächeren Systemen eingesetzt werden kann. In der Konfigurationsdatei können alle nicht verwendeten Elemente, Unterstützung für verschiedene Farbformate, externe Bibliotheken und andere Funktionen deaktiviert werden, um die Dateigröße des Bundles zu reduzieren. Zudem kann eine weniger leistungsfähige Rendering-Engine verwendet werden, um die Prozessorbelastung zu senken. Die Bibliothek benötigt nicht viel Speicher, obwohl dies von der Anzahl der erstellten Elemente abhängt.

  1. Erste Schritte

Zuerst muss die Bibliothek installiert und dem Projekt hinzugefügt werden. Das Vorgehen variiert je nach Projekttyp. Zum Beispiel genügt es bei Projekten mit ESP-IDF, die Abhängigkeit lvgl/lvgl hinzuzufügen. Alternativ kann der Bibliothekscode direkt in das Projekt eingefügt werden.

Der nächste Schritt ist die Konfiguration. Diese erfolgt durch Bearbeitung der Datei lv_conf.h oder mit dem Kconfig-Tool. In der Konfiguration können Speichergrößen und deren Zuweisung eingestellt sowie verschiedene Funktionen aktiviert oder deaktiviert werden, einschließlich externer Bibliotheken oder verfügbarer Interface-Elemente.

Vor der Nutzung muss die Bibliothek mit dem Aufruf der Funktion lv_init() initialisiert werden. Danach wird mit lv_display_create() eine Anzeiginstanz lv_display_t erstellt. Das erste nach der Initialisierung erstellte Display wird zum Standarddisplay. Einige Funktionen akzeptieren statt einer lv_display_t-Instanz auch NULL und nutzen dann das Standarddisplay. Gemeinsam mit dem Display wird der Bildschirm erstellt, das UI-Objekt, das die Wurzel des Objektbaumes auf diesem Display bildet. Die Instanz des aktiven Bildschirms lässt sich mit lv_display_get_screen_active() abrufen.

Die Benutzeroberfläche wird aus Elementen aufgebaut, die in LVGL Objekte (objects) genannt werden. Diese sind hierarchisch in Form eines Baumes angeordnet. Funktionen zum Erstellen von Objekten nehmen als Parameter das Elternobjekt. Dieses kann jedes beliebige Element sein, insbesondere auch ein leeres, was die Gruppierung von Elementen ermöglicht. Dieser Mechanismus ähnelt der Verwendung des div-Tags in HTML. Eine detaillierte Beschreibung und Liste der Elemente findet man in der Bibliotheksdokumentation.

Elemente auf dem Bildschirm können absolut positioniert werden, indem ihre Koordinaten direkt über lv_obj_set_pos()/lv_obj_set_x()/lv_obj_set_y() gesetzt werden, oder dynamisch relativ zum Elternobjekt über lv_obj_align() oder relativ zu einem anderen Objekt mit lv_obj_align_to(). Erwähnenswert ist, dass die Position nur automatisch neu berechnet wird, wenn sie mit dem Elternobjekt verknüpft ist (also wenn sich dessen Position ändert).

Das Aussehen der Elemente kann durch Stile geändert werden. Stil-Eigenschaften können direkt für ein Objekt gesetzt oder durch Erstellung einer lv_style_t-Instanz eingestellt und mittels lv_obj_add_style() auf mehrere Komponenten angewendet werden. Der Mechanismus ähnelt CSS-Klassen, insbesondere da Stile in LVGL ebenfalls kaskadierend wirken. Eine vollständige Liste der Stil-Eigenschaften befindet sich in der Bibliotheksdokumentation.

Zur Unterstützung von Eingabegeräten (Touchscreen, Maus, Tastatur) muss eine lv_indev_t-Instanz erstellt und eine Callback-Funktion mittels lv_indev_set_read_cb() zugewiesen werden, die die Gerätedaten ausliest. Bei Touchpanels mit Mehrfingereingabe (Multitouch) ist für jeden Punkt eine separate lv_indev_t-Instanz erforderlich. Eingabegeräte werden im aktiven Abfrageverfahren (Polling) betrieben, also zyklisch automatisch ausgelesen.

  1. Zähler hoch/runter

Im Folgenden wird gezeigt, wie man eine einfache Anwendung implementiert. Die App speichert den Zustand eines Zählers und zeigt ihn auf einem Label an. Der Nutzer kann den Zähler mit der Schaltfläche „-“ verringern oder mit der Schaltfläche „+“ erhöhen.

Zur Vereinfachung wurde die Möglichkeit genutzt, die SDL-Bibliothek als Laufzeitplattform einzusetzen. So können Tests direkt auf dem PC ohne Mikroprozessor mit Display durchgeführt werden. SDL2 muss installiert werden und dann wird in der Konfigurationsdatei LV_USE_SDL auf 1 gesetzt, um die Integration zu aktivieren.

Zu Beginn des Programms wird die Initialisierungsfunktion aufgerufen, ein Display sowie ein Eingabegerät erstellt. Bei SDL2 sind beide Funktionen bereits in LVGL implementiert und es genügt, diese fertigen Funktionen aufzurufen. Am Ende der main-Funktion befindet sich die Event-Loop-Behandlung, die für die Aktualisierung der UI bei Ereignissen wie Touch-Input zuständig ist.





Das erste hinzugefügte Element ist ein Label zur Anzeige des Ergebnisses. Es wird direkt als Kind des Standard-Bildschirms gesetzt. Das Label wird mit lv_obj_align in die Bildschirmmitte platziert. Die Funktion akzeptiert außerdem die Verschiebung in Pixeln, hier in beiden Achsen Null. lv_label_set_text_static wurde verwendet statt lv_label_set_text, weil ein Textliteral übergeben wurde, das während der gesamten Programmausführung verfügbar ist, sodass keine Textkopie in den internen Speicher des Labels nötig ist.

Als Nächstes werden zwei Buttons mit den Beschriftungen „+“ und „-“ hinzugefügt. Beim Hinzufügen wurde lv_obj_align verwendet, um sie etwas von den Bildschirmrändern weg zu positionieren. Der Button selbst enthält nicht den Text oder die Bilder, die auf ihm angezeigt werden. Diese sind eigene Elemente, die den Button als Elternteil haben. Hier reichte es, ein Label hinzuzufügen, da LVGL eine Symbolschriftart mitliefert. Eine vollständige Liste der Symbole ist in der Bibliotheksdokumentation verfügbar.





Damit die App interaktiv wird, müssen den Buttons Callback-Funktionen zugewiesen werden, die bei Betätigung ausgelöst werden. Der Zählerwert wird in der globalen Variablen g_counter gespeichert. Um auf das Label zuzugreifen, werden Baumzugriffs-funktionen lv_obj_get_parent und lv_obj_get_child verwendet. Der Index 0 bedeutet Zugriff auf das älteste (zuerst hinzugefügte) Kind. Negative Werte kehren die Reihenfolge um, so bedeutet -1 Zugriff auf das zuletzt hinzugefügte Kind.

Um Callback-Funktionen mit Ereignissen zu verbinden, wird lv_obj_add_event_cb verwendet. Der dritte Parameter ist ein Filter für Ereignisse, sodass eine Funktion verschiedene Ereignisse verarbeiten kann. Der vierte Parameter ist ein void*-Typ Parameter zum Übergeben von Benutzerparametern an die Callback-Funktionen.

Das Aussehen von Elementen kann direkt oder über Stile verändert werden. Stile sind nützlich, wenn mehrere Elemente dasselbe Aussehen erhalten sollen, denn sie verhindern Wiederholungen. Sie wirken kaskadierend, das heißt Eigenschaftswerte eines Stils können durch nachträglich hinzugefügte Stile überschrieben werden. Im Beispiel wurden zwei Buttons mit identischem Aussehen erstellt, was die Verwendung von Stilen sinnvoll macht.

Elemente haben unterschiedliche Zustände, wie z. B. wenn der Benutzer mit dem Cursor darüberfährt, das Element gedrückt wird oder inaktiv ist. Für verschiedene Zustände können unterschiedliche Stile definiert werden, die kaskadierend wirken. Beim Hinzufügen eines Stils zu einem Objekt muss der Selektor für den aktiven Zustand angegeben werden. Der Mechanismus ähnelt den Pseudoklassen in CSS. Einzelne Eigenschaften oder Elemente können auch direkt gesetzt werden.

Die Anwendungslogik kann mit dem Beobachter-Entwurfsmuster implementiert werden. LVGL stellt das beobachtete Objekt lv_subject_t bereit, an das Beobachter angeschlossen werden können. Einige Elemente haben eingebaute Funktionen, die Aktionen an beobachteten Objekten erleichtern, z.B. wird der Text eines Labels automatisch aktualisiert, wenn sich der überwachte Wert ändert. Ein Button kann z.B. beim Drücken den Wert ändern. Eigene Beobachter können ebenfalls als Callback-Funktion angebunden werden.

Die Implementierung würde folgendermaßen aussehen: Die globale Zählervariable wird durch eine lv_subject_t-Instanz ersetzt. Der Labeltext wird mit lv_label_bind_text an das beobachtete Objekt angebunden. Die Buttons addieren oder subtrahieren bei Klick automatisch +1 bzw. -1. Hierfür dient lv_obj_add_subject_increment_event, welche eine Inkrementierung an das beobachtete Objekt mit dem übergebenen Wert für das Ereignis als Callback registriert.

Nachfolgend ist der erforderliche Code zur Nutzung von lv_observer_t angegeben. Die Callback-Funktionen s_on_down_clicked sowie s_on_up_clicked und die Initialisierung des Labeltexts werden hier nicht mehr benötigt.

  1. Beispielanwendung: Texteditor

Als Beispiel für eine komplexere Anwendung, die Vektorschriften, Integration in ein Dateisystem und erweiterte UI-Elemente nutzt, wird ein Texteditor vorgestellt. Das UI ist einerseits von traditionellen Desktop-Anwendungen inspiriert, dank der Symbolleiste, andererseits für Touchscreens mit einer Bildschirmtastatur angepasst. Es wurden fertige Komponenten der Bibliothek ohne größere Änderungen verwendet sowie eigene Elemente auf deren Basis erstellt.

Zur Anordnung der Elemente wird ein Flex-Layout verwendet. Tastatur, Textfeld und Symbolleiste sind in einer Spalte angeordnet. Die Symbolleiste ist ein Flex-Container mit Zeilenrichtung. Automatisch berechnete Abstände zwischen den Elementen werden unterstützt und genutzt, um etwa den Schließen-Button zu positionieren. Das Flex-Layout in LVGL ist dem aus CSS ähnlich und sehr praktisch, um Komponenten einfach auf dem Bildschirm anzuordnen.

Ein Beispiel für eine erweiterte Komponentenverwendung ist das Dateiauswahlfenster zum Speichern (und Laden) von Dateien. Es wird das lv_msgbox-Element verwendet, welches normalerweise zur Anzeige kurzer Nachrichten dient. Die Hauptkomponente ist meist ein Label mit der Nachricht. Stattdessen können jedoch zusätzliche Elemente eingefügt werden, sodass das Nachrichtenfenster als allgemeines Fenster dient. Die Dateiliste basiert auf einer Tabelle mit einer eigenen Zeichenfunktion und benötigt viel weniger Speicher als eine Listendarstellung mit Labels.

Dank der stb_truetype-Bibliothek unterstützt LVGL Vektorfonts im TrueType-Format. Um dies zu nutzen, muss der Tiny TTF Font-Engine in der Konfiguration aktiviert werden. Die Schriftart eines Elements (z. B. Textfeld) kann während der Laufzeit geändert werden. Das Element wird dann automatisch zum Neuzeichnen markiert. Die Engine unterstützt Größenänderungen der Schriftart jederzeit nach dem Laden. Das Anwenden der neuen Stiländerung muss manuell markiert werden, damit die Elemente aktualisiert werden, die den Stil verwenden. UTF-8-Codierung wird unterstützt, sodass mehrsprachige Schriftarten voll genutzt werden können. Eine große Auswahl freier TrueType-Schriftarten findet sich auf der Seite Google Fonts.

Die Anwendung verwendet das Modul lv_fs zur Dateiverwaltung, welches eine einheitliche Schnittstelle für verschiedene Dateisysteme bietet. Es gibt mehrere Implementierungen u.a. basierend auf der Standard-C-Bibliothek, POSIX oder Win32 APIs. Mehrere Implementierungen können gleichzeitig aktiv sein. Pfade beginnen mit einem Großbuchstaben, der das Laufwerk bzw. den Dateisystem-Treiber identifiziert. Zum Beispiel könnte P: für POSIX und W: für Win32 stehen. Somit wird der Pfad P:/home/user/file.txt über POSIX, W:C:\Users\user\file.txt über Win32 gehandhabt.

  1. Zusammenfassung

LVGL ist vielseitig einsetzbar: von einfachen Interfaces auf Geräten mit sehr begrenzten Ressourcen bis hin zu umfangreichen Interfaces, die mobilen Apps ähneln. Die Entwicklung wird durch eine große Auswahl an fertigen, aber leicht anpassbaren Komponenten erleichtert. Ein Stilsystem sowie Flex- und Grid-Layouts, ähnlich denen in CSS, helfen bei der Gestaltung. Die Unterstützung von Dateisystemen, Speicherverwaltung und Logging unabhängig von der Plattform ermöglicht die Erstellung vollständig portabler oder einfach portierbarer Anwendungen. Das Ausführen auf Linux-, Windows- oder Mac-Rechnern beschleunigt das UI-Design. Somit ist LVGL eine sehr gute Wahl für professionelle grafische Benutzeroberflächen auf eingebetteten Systemen.