Embedded systems
2025-06-17
14 Minuten Lesezeit

LVGL GUI-Entwicklung: Ein umfassender Überblick

Przemysław Sowa
Przemysław Sowa Chief Technology Officer

Grafische Benutzeroberflächen (GUIs) werden in eingebetteten Geräten – von Haushaltsgeräten bis hin zu medizinischer Ausrüstung – zunehmend wichtiger, um eine benutzerfreundliche Erfahrung zu bieten. Doch die Entwicklung einer anspruchsvollen GUI auf ressourcenbeschränkter Hardware ist schwierig. LVGL (Light and Versatile Graphics Library) ist eine beliebte Lösung: ein kostenloses, quelloffenes Grafik-Framework für Mikrocontroller und eingebettete Systeme.

Als Spezialisten für die Entwicklung eingebetteter Systeme sind wir stets auf der Suche nach den besten Lösungen für eine schnelle Entwicklung. In diesem Artikel werfen wir einen genaueren Blick auf LVGL – seine Architektur, Funktionen und Vorteile – um Ihnen bei der Auswahl des richtigen Werkzeugs für Ihre Embedded-Projekte zu helfen.

LVGL im Überblick: Architektur & Funktionen

Leichtgewichtige C-Bibliothek

LVGL ist eine in C geschriebene Bibliothek für den Einsatz in eingebetteten Systemen. Sie hat minimale Hardwareanforderungen , läuft auf 16-, 32- oder 64-Bit-MCUs mit einer Taktrate von ≥ 64 MHz und benötigt nur einige Dutzend Kilobyte Speicher (etwa 48 KB RAM und 100 KB Flash für eine einfache GUI). LVGL funktioniert mit jedem MCU/MPU, jedem hochwertigen Display, jedem Betriebssystem oder sogar in Bare-Metal-Umgebungen . Es unterstützt gängige Displaytypen (TFT, OLED, ePaper usw.) sowie verschiedene Farbformate.

Modulare Architektur

Im Kern stellt LVGL eine Rendering-Engine für GUIs und eine Objekt-Hierarchie für UI-Elemente (sogenannte „Widgets“) bereit. Entwickler erstellen UI-Objekte (Buttons, Labels, Slider usw.) und LVGL übernimmt deren Darstellung, Eingabeverarbeitung und Animationen. LVGL verwendet ein relatives Layout-System , inspiriert vom Web/CSS-Paradigma – einschließlich Flexbox- und Grid-Layouts – sodass sich Widgets automatisch positionieren und skalieren können.

Umfangreiches Widget-Set und Zeichenfunktionen

Trotz seines kleinen Speicherbedarfs bietet LVGL umfassende GUI-Funktionalitäten:

  • UI-Widgets: LVGL enthält über 30 integrierte Widgets – Labels, Buttons, Slider, Fortschrittsbalken, Checkboxen, Schalter, Diagramme, Tabellen, Texteingabefelder, Tastaturen, Meldungsfenster und vieles mehr.

  • Erweiterte 2D-Grafik: Die Software-Rendering-Engine von LVGL unterstützt moderne visuelle Effekte bei hoher Effizienz. Sie zeichnet Formen mit Anti-Aliasing für glatte Kanten und unterstützt Funktionen wie Farbverläufe (linear, radial, konisch), Transparenz, Schatten und Bildtransformationen.

  • Styling und Themes: Jedes Widget in LVGL ist über ein Stylesystem hochgradig anpassbar. Es gibt über 100 Stil-Eigenschaften (Farben, Abstände, Rahmen usw.), die auf jedes Objekt oder seine Bestandteile angewendet werden können (z. B. kann ein Slider eigene Styles für Regler, Anzeige und Spur haben). Stile können sich automatisch je nach Status (gedrückt, fokussiert, deaktiviert usw.) ändern und mit Übergängen animiert werden.

  • Internationalisierung: LVGL wurde für den weltweiten Einsatz entwickelt. Es nutzt UTF-8-Codierung und unterstützt komplexe Textdarstellung – einschließlich rechts-nach-links-Schriften (Arabisch, Persisch, Hebräisch) sowie CJK-Zeichen. LVGL kann viele Sprachen und Regionen problemlos unterstützen – auch gemischte LTR- und RTL-Texte in einer Oberfläche.

  • Eingabeverarbeitung: Neben Touchscreens abstrahiert LVGL Eingabegeräte, sodass Buttons, Drehencoder, Tastaturen oder andere Eingabemethoden als Steuerung verwendet werden können.

  • Multi-Display und benutzerdefinierte Treiber: LVGL unterstützt mehrere Displays (für Geräte mit mehreren Bildschirmausgängen) sowie Offscreen-Rendering – ideal für kommerzielle Projekte mit vielseitigen Anforderungen an Aufbau, Anschluss und Konfiguration.

LVGL Architektur & Funktionen

LVGL-Bibliothek für die Entwicklung eingebetteter GUIs

LVGL bietet zahlreiche Vorteile für die Entwicklung grafischer Benutzeroberflächen in Embedded-Systemen und ist daher eine beliebte Wahl für viele Entwicklerteams:

  • Kleiner Speicherbedarf & hohe Leistung :

    LVGL ist für ressourcenarme Systeme optimiert, benötigt nur wenige Kilobyte RAM und Flash-Speicher und bietet dennoch flüssige, smartphone-ähnliche Oberflächen. Die Rendering-Engine in C sorgt für hohe Leistung selbst auf stromsparenden Geräten. LVGL kann auf MCUs mit minimalen Ressourcen laufen und dennoch hohe Bildwiederholraten erzielen – ideal für batteriebetriebene Geräte wie Wearables.

  • Umfangreicher Funktionsumfang :

    Trotz seines kleinen Speicherbedarfs bietet LVGL viele Funktionen wie Widgets, Animationen, erweiterte 2D-Grafik, Eingabeverarbeitung und Multitouch-Gesten. Diese Features ermöglichen Entwicklern, attraktive Benutzeroberflächen mit minimalem eigenem Code zu erstellen. LVGL konkurriert mit vielen proprietären GUI-Lösungen und ermöglicht ausgefeilte Benutzeroberflächen auch auf Geräten mit begrenzten Ressourcen.

  • Flexibilität bei Hardware und Betriebssystem :

    LVGL ist äußerst flexibel und unterstützt zahlreiche Hardware-Plattformen und Betriebssysteme. Diese Plattformunabhängigkeit erlaubt es Teams, LVGL auf unterschiedlichen Systemen (z. B. STM32, NXP, Espressif usw.) und Betriebssystemen – ob Bare-Metal oder Linux – zu nutzen. Ein Windows-Simulator ermöglicht die GUI-Entwicklung ohne reale Hardware, was Flexibilität erhöht und Entwicklungsrisiken senkt.

  • Open Source mit aktiver Community :

    LVGL ist quelloffen unter der MIT-Lizenz – keine Lizenzgebühren oder Abgaben, was im Vergleich zu kommerziellen GUI-Bibliotheken Kosten spart. Eine wachsende und aktive Community bietet kontinuierliche Unterstützung, Updates und Fehlerbehebungen. Die Offenheit ermöglicht es Entwicklern, den Quellcode zu debuggen und LVGL bei Bedarf anzupassen. Große Unternehmen wie Xiaomi setzen LVGL in ihren Smart-Produkten ein und tragen zur Weiterentwicklung bei.

  • Anpassbarkeit und Kontrolle :

    LVGL gibt Entwicklern die vollständige Kontrolle über die GUI. Die Bibliothek ist hardwarenah und in C geschrieben, was eine feingranulare Steuerung und einfache Integration ins System ermöglicht. Eigene Widgets und Zeichenroutinen können bei Bedarf hinzugefügt werden, was LVGL besonders für komplexe oder sicherheitskritische Systeme anpassbar macht.

  • Kosteneffizient und kommerziell nutzbar :

    Dank MIT-Lizenz fallen keine versteckten Kosten oder Lizenzgebühren an – LVGL ist sehr kostengünstig. Unternehmen können teure kommerzielle Lizenzen vermeiden und Compliance vereinfachen. Bei Bedarf ist formeller Support verfügbar, aber optional – so bleibt die Flexibilität, den gewünschten Support-Level selbst zu wählen.

LVGL GUI Entwicklungsablauf

Einschränkungen

Kein Framework ist perfekt – es ist wichtig, auch die Einschränkungen und Herausforderungen von LVGL zu berücksichtigen, um eine fundierte Entscheidung zu treffen.

Eines der Hauptprobleme, das häufig bei der Arbeit mit LVGL genannt wird,

ist das Fehlen eines ausgereiften, nativen GUI-Builder-Tools .
Während Entwickler traditionell auf das Schreiben von C-Code oder die Nutzung von Drittanbieter-Editoren
wie SquareLine Studio oder GUI Guider angewiesen waren, wird diese Einschränkung nach und nach behoben.

Der offizielle LVGL UI-Editor befindet sich nun in aktiver Entwicklung durch das Kernteam.

Obwohl er sich noch in einem frühen Stadium befindet (v0.3, Stand Juli 2025) ,
bietet er bereits einen strukturierten Ansatz zur GUI-Erstellung – mit Echtzeit-Vorschau,
Code-Export, Figma-Integration, Drag-and-Drop-Layout, erweiterten Widgets und Datenbindung.
Die erste produktionsreife Version (v1.0) ist für Oktober 2025 geplant
und könnte den Arbeitsablauf für designorientierte Teams erheblich verbessern.

Ein weiterer Aspekt ist die Art des Supports und der Garantien .

Da LVGL ein Open-Source-Projekt ist, beinhaltet es standardmäßig keinen mitgelieferten Herstellersupport –
anders als kommerzielle Lösungen wie Qt for MCUs oder Embedded Wizard, die Support als Teil ihrer Lizenzierung anbieten.
Dies kann für Teams, die auf garantierte SLAs oder langfristige Wartung angewiesen sind, problematisch sein.

Für professionelle Einsätze ist jedoch

offizieller kommerzieller Support direkt von den LVGL-Entwicklern über LVGL Services verfügbar .
Dieses Angebot umfasst SLAs, direkte technische Unterstützung, Beratung sowie Zugang zu einem wachsenden Partnernetzwerk.
Auch wenn es noch nicht so ausgereift oder weit verbreitet ist wie einige proprietäre Ökosysteme,
stellt es einen bedeutenden Schritt dar, um LVGL für professionelle und groß angelegte Einsätze nutzbar zu machen.

Das nischige Ökosystem von LVGL bedeutet, dass es weniger Drittanbieter-Erweiterungen und Integrationen gibt als bei größeren Frameworks wie Qt. Zwar bietet LVGL viele Funktionen von Haus aus, jedoch müssen Teams für spezifische Anforderungen unter Umständen eigene Lösungen entwickeln, da die verfügbaren Ressourcen und die Community kleiner sind.

Darüber hinaus ist LVGL in erster Linie ein GUI-Toolkit , weshalb andere wichtige Funktionen wie Netzwerkkommunikation, Dateisysteme oder Threading-Mechanismen durch separate Bibliotheken oder das zugrunde liegende Betriebssystem abgedeckt werden müssen. Dies ist typisch für eingebettete Systeme, dennoch sollten Teams im Hinterkopf behalten, dass sich LVGL ausschließlich auf die Benutzeroberfläche konzentriert.

Was das Feintuning der Performance betrifft: LVGL ist zwar sehr effizient, aber um optimale Leistung auf ressourcenbeschränkter Hardware zu erreichen, sind manchmal Low-Level-Anpassungen notwendig. Entwickler müssen u. U. das Rendering profilieren und den Speicherverbrauch optimieren, um Probleme wie Flackern oder übermäßige CPU-Auslastung zu vermeiden – besonders bei aufwendigen visuellen Effekten oder bei der Darstellung von Messwerten auf Monitoren. Hier können kommerzielle Lösungen im Vorteil sein, da sie oft bereits hardwareoptimierte Einstellungen mitbringen.

Schließlich kann das manuelle Speichermanagement eine Herausforderung darstellen – insbesondere für Teams, die an höher abstrahierte Frameworks mit Garbage Collection gewöhnt sind. Bei LVGL müssen Entwickler den Speicher manuell verwalten, was eine Umstellung bedeuten kann. Das korrekte Löschen von UI-Objekten und Screens ist entscheidend für die Speicherstabilität.

LVGL Einschränkungen

Framework-Vergleich: TouchGFX, Qt for MCUs, Embedded Wizard

LVGL ist nicht das einzige Framework für eingebettete GUIs. Weitere beliebte Lösungen sind TouchGFX , Qt for MCUs und Embedded Wizard . Jedes dieser Frameworks hat einen eigenen Ansatz und kann – je nach Projekt – besser oder schlechter geeignet sein. Nachfolgend finden Sie einen kurzen Vergleich dieser Frameworks mit LVGL:

Funktion

LVGL

TouchGFX

Qt for MCUs

Embedded Wizard

Lizenz

Kostenlos (Open Source)

Proprietär (kostenlos für STM32)

Kommerziell

Kommerziell

Open Source

Ja

Nein

Nein

Nein

Zielgruppe

Allgemeine Embedded-Systeme

STM32-Nutzer

Allgemeine Embedded-Systeme (Qt-Nutzer)

Allgemeine Embedded-Systeme

Benutzerfreundlichkeit

Moderat (manuelle Einrichtung mit XML)

Hoch (WYSIWYG-Editor)

Hoch (UI-Design mit QML)

Hoch (WYSIWYG-Editor)

Anpassbarkeit

Hoch (volle Kontrolle über den Code)

Mittel (eingeschränkte Anpassung)

Niedrig (weniger flexibel als LVGL)

Mittel (begrenzte Kontrolle über generierten Code)

Hardware-Support

Breite Unterstützung von MCUs

STM32-Mikrocontroller

Ausgewählte MCU-Familien ( STM32, NXP, Renesas)

Breite Unterstützung von MCU-Familien

Performance

Hoch (leichtgewichtig, optimiert)

Hoch (optimiert für STM32-Hardware)

Mittel (höherer Ressourcenverbrauch)

Hoch (optimiert für geringen Speicherbedarf)

Entwicklungstools

GUI-Editor in frühem Entwicklungsstadium

GUI-Designer (TouchGFX Designer)

Qt Design Studio, QML, Qt Quick Ultralite

WYSIWYG-Editor, Chora-Sprache

Kosten

Kostenlos

Kostenlos mit STM32, kommerzielle Nutzung benötigt ST-Lizenz

Kommerzielle Lizenz erforderlich

Kommerzielle Lizenz erforderlich

Zusammenfassend ergibt sich ein objektives Bild dieser Frameworks:

  • LVGL ist Open Source, sehr portabel und kostengünstig , erfordert jedoch mehr Eigenleistung beim Codieren und Support.

  • TouchGFX ist kostenlos und benutzerfreundlich für STM32-Nutzer mit integriertem Designer, bindet jedoch an das ST-Ökosystem und ist geschlossen.

  • Qt for MCUs bietet ein modernes UI-Konzept und leistungsstarke Tools , verursacht jedoch Lizenzkosten und höheren Ressourcenbedarf.

  • Embedded Wizard ermöglicht eine ausgereifte GUI-Entwicklung mit breitem Hardware-Support, ist aber eine proprietäre Lösung mit Investitionsbedarf.

Die Entscheidung hängt von den Projektanforderungen ab – etwa dem verwendeten Mikrocontroller, den Fähigkeiten des Teams, der Komplexität der UI und dem verfügbaren Budget. Viele Hersteller (wie NXP, ST, Renesas) unterstützen in ihren SDKs mehrere dieser Frameworks, da jedes seine eigene Nische hat. Die gute Nachricht ist: LVGL ist oft die flexibelste Wahl , wenn man unabhängig vom Anbieter und kostenbewusst entwickeln möchte – vorausgesetzt, man ist bereit, die GUI selbst zu programmieren.

Anwendungsfälle für die LVGL-Grafikbibliothek

Die Vielseitigkeit von LVGL macht es für eine breite Palette von Branchen geeignet. In der Medizintechnik wird es für Benutzeroberflächen von Geräten wie Blutzuckermessgeräten, Herzfrequenzmonitoren und Beatmungsgeräten eingesetzt. Es liefert gestochen scharfe Grafiken und Echtzeitdatenanzeige auf ressourcenarmen Systemen. Sein Open-Source-Charakter ist insbesondere in regulierten Branchen wie dem Gesundheitswesen von Vorteil, da Lizenzprobleme vermieden werden.

In der industriellen Automatisierung kommt LVGL in HMI-Systemen für Steuerungspanels, SPS-Bildschirme und CNC-Maschinen zum Einsatz. Der geringe Ressourcenverbrauch und das deterministische Verhalten machen es ideal für Echtzeitanwendungen mit hoher Zuverlässigkeit. Besonders geschätzt wird in der Industrie die Möglichkeit, Benutzeroberflächen individuell anzupassen – etwa für gebrandete, einzigartige Bedienoberflächen.

In der Unterhaltungselektronik und bei Wearables treibt LVGL Smartwatches, Fitness-Tracker und Haushaltsgeräte an. Dank skinbarer UI und geringer Overhead eignet sich LVGL hervorragend zur Erstellung moderner Benutzeroberflächen mit flüssigen Animationen – selbst auf kostengünstiger Hardware.

Auch im Automobilbereich findet LVGL Anwendung, z. B. für Fahrzeugdisplays, Infotainment-Systeme und digitale Kombiinstrumente – dank schneller Startzeiten und geringem Speicherbedarf. Es wird in eingebetteten Fahrzeuganzeigen genutzt, um verlässliche Grafiken für Navigation, Klimasteuerung und mehr darzustellen.

Insgesamt ist LVGL eine flexible Lösung für Aufgaben der grafischen Benutzeroberfläche in Embedded-Systemen – mit überzeugender Leistung, Zuverlässigkeit und Anpassungsfähigkeit für 2D-orientierte Anwendungen.

LVGL-Codebeispiel für grafische Benutzeroberflächen

In diesem Beispiel erstellen wir ein einfaches Smart-Home-Bedienfeld mit LVGL. Die Oberfläche enthält einen Temperaturanzeige-Button und einen Slider. Der Slider erlaubt dem Benutzer, die Raumtemperatur einzustellen, und der Button zeigt dynamisch den aktuellen Temperaturwert an.

Da LVGL primär für Embedded-Systeme entwickelt wurde, habe ich dieses Beispiel im LVGL-Windows-Simulator ausgeführt. So lässt sich die Anwendung direkt unter Windows entwickeln, testen und aufzeichnen – ganz ohne echte Hardware.

Dieses Setup ist ideal für Prototyping und das Erstellen von Demos wie dieser.

LVGL Beispiel-GUI

Hauptzeile und Hintergrund

Wir beginnen mit der Anpassung des Bildschirmlayouts und bereiten den Bereich vor, der unsere Smart-Home-Steuerelemente aufnehmen soll.

1. Standard-Styles entfernen und dunklen Hintergrund setzen  

Wir entfernen alle bestehenden Styles vom aktiven Bildschirm und setzen einen dunkelgrauen Hintergrund mit voller Deckkraft:

lv_obj_remove_style_all(lv_scr_act());
lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(0x161616), 0);
lv_obj_set_style_bg_opa(lv_scr_act(), LV_OPA_COVER, 0);

2. Einen horizontalen Container (Hauptzeile) erstellen  

Als Nächstes erstellen wir einen Vollbild-Container, der Button und Slider enthält. Dieser nutzt das Flex-Layout von LVGL mit horizontalem Fluss und Abstand zwischen den Elementen:

lv_obj_t *main_row = lv_obj_create(lv_scr_act());
lv_obj_remove_style_all(main_row);
lv_obj_set_size(main_row, LV_PCT(100), LV_PCT(100));
lv_obj_set_flex_flow(main_row, LV_FLEX_FLOW_ROW);
lv_obj_set_style_pad_column(main_row, 15, 0); // 15 pixels spacing between children
lv_obj_set_style_bg_opa(main_row, LV_OPA_TRANSP, 0);
// Add margins:
lv_obj_set_style_pad_top(main_row, 30, 0);   // 30 pixels top margin
lv_obj_set_style_pad_left(main_row, 30, 0);  // 30 pixels left margin
 lv_obj_align(main_row, LV_ALIGN_CENTER, 0, 0);

Diese main_row dient als Basis-Layout, das den Temperatur-Button und den Slider nebeneinander anordnet.

Button

Nun fügen wir links im Panel einen Button hinzu, der die aktuelle Temperatur anzeigt und auf Klicks reagiert.

1. Button erstellen und Styles anwenden  

Wir fügen ein Kindelement zu main_row hinzu, entfernen dessen Standard-Styles und setzen die Größe auf 300×300 Pixel. Der Hintergrund erhält eine dunkelgraue Farbe (#404040), volle Deckkraft und leicht abgerundete Ecken:

button = lv_obj_create(main_row);
lv_obj_remove_style_all(button);
lv_obj_set_size(button, 300, 300);
lv_obj_set_style_bg_color(button, lv_color_hex(0x404040), 0);
lv_obj_set_style_bg_opa(button, LV_OPA_COVER, 0);
lv_obj_set_style_radius(button, 8, 0);
lv_obj_align(button, LV_ALIGN_CENTER, 0, 0);

2. Klick-Interaktion hinzufügen  

Wir registrieren eine Callback-Funktion (siehe weiter unten), die auf Klick-Ereignisse reagiert:

lv_obj_add_event_cb(button, button_event_cb, LV_EVENT_CLICKED, NULL);

3. Temperatur-Label hinzufügen und stylen  

Innerhalb des Buttons fügen wir ein Label ein, das die aktuelle Temperatur anzeigt. Es wird zentriert und in einem hellgrauen Farbton (#BBBBBB) dargestellt:

g_temp_label = lv_label_create(button);
lv_label_set_text_fmt(g_temp_label, "Temperature: %d°C", temperature);
lv_obj_set_style_text_color(g_temp_label, lv_color_hex(0xBBBBBB), 0);
 lv_obj_center(g_temp_label);

Dieser Button dient als dynamische Temperaturanzeige und interaktives Element im Panel.

Slider

Als Nächstes fügen wir rechts im Layout einen vertikalen Slider hinzu. Dieser ermöglicht es dem Benutzer, die Temperatur anzupassen. Ein Label auf dem Slider zeigt dabei in Echtzeit den aktuellen Wert an.

1. Slider erstellen und Größe/Bereich definieren  

Der Slider wird als Kindelement zu main_row hinzugefügt, von Standard-Styles befreit und auf 50×300 Pixel gesetzt. Er wird vertikal zentriert und erlaubt Werte von 0°C bis 30°C, mit einem Anfangswert von 13°C:

lv_obj_t *slider = lv_slider_create(main_row);
lv_obj_remove_style_all(slider);
lv_obj_set_size(slider, 50, 300);
lv_obj_align(slider, LV_ALIGN_CENTER, 0, 0);
lv_slider_set_range(slider, 0, 30);
lv_slider_set_value(slider, 13, LV_ANIM_OFF);

2. Hauptspur des Sliders stylen  

Der Hintergrund des Sliders erhält eine dunkelgraue Farbe (#444444), volle Deckkraft und große Rundungen:

lv_obj_set_style_bg_color(slider, lv_color_hex(0x444444), LV_PART_MAIN);
lv_obj_set_style_bg_opa(slider, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_radius(slider, 50, LV_PART_MAIN);

3. Gefüllten Bereich (Indikator) stylen  

Der Indikator zeigt, wie viel des Sliders gefüllt ist. Er wird in Rot (#FF0000) dargestellt, mit voller Deckkraft und kleineren Rundungen:

lv_obj_set_style_bg_color(slider, lv_color_hex(0xFF0000), LV_PART_INDICATOR);
lv_obj_set_style_bg_opa(slider, LV_OPA_COVER, LV_PART_INDICATOR);
lv_obj_set_style_radius(slider, 10, LV_PART_INDICATOR);

4. Dynamisches Wert-Label hinzufügen  

Im Slider platzieren wir ein Label, das den aktuellen Wert (z. B. „13°C“) anzeigt. Es wird zentriert und in weißem Text dargestellt:

    lv_obj_t *slider_val_label = lv_label_create(slider);
    lv_label_set_text_fmt(slider_val_label, "%d°C", 13);
    lv_obj_set_style_text_color(slider_val_label, lv_color_white(), 0);
    lv_obj_align(slider_val_label, LV_ALIGN_CENTER, 0, 0);

Wir verknüpfen das Label mit dem Slider per lv_obj_set_user_data(), damit es im Event-Callback dynamisch aktualisiert werden kann.

5. Wertänderungen behandeln  

Zum Schluss registrieren wir einen Callback für Wertänderungen, der Temperatur und Label aktualisiert:

lv_obj_set_user_data(slider, slider_val_label);
lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);

Button-Callback

Die Funktion button_event_cb reagiert auf Klick-Ereignisse des Temperatur-Buttons. Beim Klick wechselt ein internes selected-Flag den Zustand, um festzuhalten, ob der Button aktiviert ist.

Visuell zeigt sich die Auswahl durch einen roten Rand um den Button. Wenn der Button ausgewählt ist, wird ein 4 Pixel breiter roter Rahmen hinzugefügt. Bei erneutem Klick und Deaktivierung verschwindet der Rahmen, und der Button erhält wieder sein ursprüngliches graues Aussehen.

static void button_event_cb(lv_event_t *e)
{
    selected = !selected;
    if (selected)
    {        
        lv_obj_set_style_border_width(button, 4, 0);
        lv_obj_set_style_border_color(button, lv_color_hex(0xFF0000), 0);
        lv_obj_set_style_border_opa(button, LV_OPA_COVER, 0);
    }
    else
    {
        lv_obj_set_style_border_width(button, 0, 0);
        lv_obj_set_style_bg_color(button, lv_color_hex(0x404040), 0);
        lv_obj_set_style_bg_opa(button, LV_OPA_COVER, 0);
    }
}

Slider-Callback

Die Funktion slider_event_cb verarbeitet Änderungen des Slider-Werts. Immer wenn der Benutzer den Slider bewegt, wird dieser Callback ausgelöst.

Zuerst wird geprüft, ob es sich um ein LV_EVENT_VALUE_CHANGED-Ereignis handelt. Dann wird der neue Wert ausgelesen und zwei Labels aktualisiert:

  • Das Label im Slider selbst, das den aktuellen Wert zentriert darstellt (z. B. „17°C“).

  • Das Temperatur-Label im Button , damit beide UI-Elemente synchron sind.

Dadurch bietet der Slider sofortiges Feedback sowohl lokal als auch global in der Oberfläche – für eine intuitive und reaktionsschnelle Temperatursteuerung.

static void slider_event_cb(lv_event_t *e)
{
    if (lv_event_get_code(e) == LV_EVENT_VALUE_CHANGED)
    {
        lv_obj_t *slider = lv_event_get_target(e);
        lv_obj_t *slider_val_label = (lv_obj_t *)lv_obj_get_user_data(slider);
        int val = lv_slider_get_value(slider);
        if (slider_val_label)
        {
            lv_label_set_text_fmt(slider_val_label, "%d°C", val);
        }
        if (g_temp_label)
        {
            lv_label_set_text_fmt(g_temp_label, "Temperature: %d°C", val);
        }
    }
}

Vollständiges Beispiel

Nachfolgend finden Sie den vollständigen Code für unser einfaches Smart-Home-Temperaturpanel mit LVGL. Er enthält das Layout, die interaktiven Komponenten (Button und Slider) sowie deren zugehörige Event-Callbacks für dynamische UI-Aktualisierungen.

/**
 * @file lv_demo_scythe.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_demo_scythe.h"
#include "../../lvgl_private.h"


/* Forward declares */
static void button_event_cb(lv_event_t *e);
static void slider_event_cb(lv_event_t *e);

/* Global pointers */
bool selected = false;
int temperature = 13; // Initial temperature value
static lv_obj_t *button = NULL;
static lv_obj_t *g_temp_label = NULL;

/***********************************************************
 * MAIN DEMO FUNCTION
 ***********************************************************/

void lv_demo_scythe(void)
{
    /* 1) background */
    lv_obj_remove_style_all(lv_scr_act());
    lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(0x161616), 0);
    lv_obj_set_style_bg_opa(lv_scr_act(), LV_OPA_COVER, 0);

    // Create a row container for button and side panel
    lv_obj_t *main_row = lv_obj_create(lv_scr_act());
    lv_obj_remove_style_all(main_row);
    lv_obj_set_size(main_row, LV_PCT(100), LV_PCT(100));
    lv_obj_set_flex_flow(main_row, LV_FLEX_FLOW_ROW);
    lv_obj_set_style_pad_column(main_row, 15, 0); // 15 pixels spacing between children
    lv_obj_set_style_bg_opa(main_row, LV_OPA_TRANSP, 0);

    // Add margins:
    lv_obj_set_style_pad_top(main_row, 30, 0);   // 30 pixels top margin
    lv_obj_set_style_pad_left(main_row, 30, 0);  // 30 pixels left margin

    lv_obj_align(main_row, LV_ALIGN_CENTER, 0, 0);

    // Button (left)
    button = lv_obj_create(main_row);
    lv_obj_remove_style_all(button);
    lv_obj_set_size(button, 300, 300);
    lv_obj_set_style_bg_color(button, lv_color_hex(0x404040), 0);
    lv_obj_set_style_bg_opa(button, LV_OPA_COVER, 0);
    lv_obj_set_style_radius(button, 8, 0);
    lv_obj_align(button, LV_ALIGN_CENTER, 0, 0);
    lv_obj_add_event_cb(button, button_event_cb, LV_EVENT_CLICKED, NULL);

    g_temp_label = lv_label_create(button);
    lv_label_set_text_fmt(g_temp_label, "Temperature: %d°C", temperature);
    lv_obj_set_style_text_color(g_temp_label, lv_color_hex(0xBBBBBB), 0);
    lv_obj_center(g_temp_label);

    // Slider (right, directly in the row)
    lv_obj_t *slider = lv_slider_create(main_row);
    lv_obj_remove_style_all(slider);
    lv_obj_set_size(slider, 50, 300);
    lv_obj_align(slider, LV_ALIGN_CENTER, 0, 0);
    lv_slider_set_range(slider, 0, 30);
    lv_slider_set_value(slider, 13, LV_ANIM_OFF);

    lv_obj_set_style_bg_color(slider, lv_color_hex(0x444444), LV_PART_MAIN);
    lv_obj_set_style_bg_opa(slider, LV_OPA_COVER, LV_PART_MAIN);
    lv_obj_set_style_radius(slider, 50, LV_PART_MAIN);

    lv_obj_set_style_bg_color(slider, lv_color_hex(0xFF0000), LV_PART_INDICATOR);
    lv_obj_set_style_bg_opa(slider, LV_OPA_COVER, LV_PART_INDICATOR);
    lv_obj_set_style_radius(slider, 10, LV_PART_INDICATOR);

    lv_obj_t *slider_val_label = lv_label_create(slider);
    lv_label_set_text_fmt(slider_val_label, "%d°C", 13);
    lv_obj_set_style_text_color(slider_val_label, lv_color_white(), 0);
    lv_obj_align(slider_val_label, LV_ALIGN_CENTER, 0, 0);
    lv_obj_set_user_data(slider, slider_val_label);
    lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
}

/***********************************************************
 * CALLBACKS
 ***********************************************************/
static void button_event_cb(lv_event_t *e)
{
    selected = !selected;

    if (selected)
    {        
        lv_obj_set_style_border_width(button, 4, 0);
        lv_obj_set_style_border_color(button, lv_color_hex(0xFF0000), 0);
        lv_obj_set_style_border_opa(button, LV_OPA_COVER, 0);
    }
    else
    {
        lv_obj_set_style_border_width(button, 0, 0);
        lv_obj_set_style_bg_color(button, lv_color_hex(0x404040), 0);
        lv_obj_set_style_bg_opa(button, LV_OPA_COVER, 0);
    }
}

static void slider_event_cb(lv_event_t *e)
{
    if (lv_event_get_code(e) == LV_EVENT_VALUE_CHANGED)
    {
        lv_obj_t *slider = lv_event_get_target(e);
        lv_obj_t *slider_val_label = (lv_obj_t *)lv_obj_get_user_data(slider);
        int val = lv_slider_get_value(slider);

        if (slider_val_label)
        {
            lv_label_set_text_fmt(slider_val_label, "%d°C", val);
        }

        if (g_temp_label)
        {
            lv_label_set_text_fmt(g_temp_label, "Temperature: %d°C", val);
        }
    }
}

Ergebnisse und Fazit

Dieses einfache Smart-Home-Panel zeigt, wie schnell man mit LVGL saubere, reaktionsschnelle Benutzeroberflächen erstellen kann. Mit nur wenigen Zeilen Code haben wir ein modernes Layout mit direkter Interaktion zwischen UI-Elementen realisiert – ein Temperatur-Button, der auf Benutzereingaben reagiert, und ein Slider, der die Werte sofort aktualisiert.

LVGL Example GUI

Dieses Beispiel eignet sich hervorragend als Ausgangspunkt für fortgeschrittene Smart-Home-Oberflächen, Dashboards oder eingebettete Anwendungen. Egal ob Sie Steuerungen für Heizung, Beleuchtung oder Haushaltsgeräte entwickeln – mit LVGL haben Sie die richtigen Werkzeuge zur Hand, um intuitive und visuell ansprechende GUIs zu erstellen.

Fazit & weiterführende Ressourcen

Zusammenfassend ist LVGL ein leistungsstarkes Werkzeug, um ansprechende GUIs auf kleinen Mikrocontrollern zu realisieren. Die Welt der grafischen Benutzeroberflächen im Embedded-Bereich ist groß – und wächst stetig weiter. Egal, ob Sie sich für LVGL oder ein anderes Framework entscheiden, das Ziel bleibt dasselbe: eine Oberfläche zu schaffen, die Nutzer begeistert und gleichzeitig den technischen Einschränkungen des Geräts gerecht wird.

Bei der Auswahl eines GUI-Frameworks sollten Sie nicht nur die Bibliothek selbst betrachten, sondern das große Ganze im Blick behalten: die Anforderungen Ihres Produkts, das Know-how Ihres Teams und die langfristige Wartbarkeit. Manche Unternehmen entscheiden sich dafür, mit spezialisierten GUI-Entwicklungspartnern zusammenzuarbeiten. Die Zusammenarbeit mit Entwicklern, die umfassende Erfahrung mit Frameworks wie Qt oder LVGL haben, kann Ihnen eine objektive Einschätzung liefern, welches Werkzeug für Ihr Projekt am besten geeignet ist. Solche Partnerschaften können die Entwicklung beschleunigen und sicherstellen, dass die gewählte Technologie optimal genutzt wird – sei es LVGL oder eine andere Lösung – ohne voreingenommene Präferenzen. Bei Somco Software verfügen wir über ein GUI-fokussiertes Entwicklungsteam und haben festgestellt, dass eine gründliche Evaluierung im Vorfeld viel Zeit in späteren Phasen spart. Durch den gezielten Einsatz von Experten treffen Sie die richtige Wahl und implementieren das Framework, das Ihrem Embedded-Produkt die beste Benutzererfahrung bietet.

Wenn Sie LVGL näher kennenlernen möchten, finden Sie hier einige nützliche Ressourcen : Die offizielle LVGL-Dokumentation und Tutorials (verfügbar unter docs.lvgl.io) bieten detaillierte Anleitungen – vom Erstellen einfacher Widgets bis hin zu fortgeschrittener Anpassung. Im GitHub-Repository von LVGL finden Sie viele Beispiele und ein Simulationsprojekt, mit dem Sie gleich loslegen können. Außerdem gibt es ein aktives Forum ( forum.lvgl.io), in dem Sie Fragen stellen und sich mit anderen Entwicklern austauschen können, die vor ähnlichen Herausforderungen standen.

Ähnliche beiträge

IoT
2025-08-20

IoT-Geräteauthentifizierung: Warum sie wichtig ist und wie man sie implementiert

Da das Internet der Dinge (IoT) allgegenwärtig wird, sind mittlerweile Milliarden von verbundenen IoT-Geräten mit den Netzwerken verbunden – von intelligenten Thermostaten und Fabriksensoren bis hin zu Insulinpumpen und Fahrzeug-ECUs. Doch mit dieser Konnektivität kommt auch ein Risiko: Wie wissen Sie, ob das Gerät, mit dem Sie sprechen, echt ist, und kein bösartiger Klon oder ein kompromittierter Knoten? Genau hier kommt die IoT-Geräteauthentifizierung ins Spiel.
Michał Woźniak
Michał Woźniak Software Developer
FinTech
2025-08-18

FIX-Engine-Integration in Finanzsysteme: Ein umfassender Leitfaden

Financial Information eXchange (FIX) ist der weltweite Standard für den elektronischen Handel. Von Aktien bis zu Devisen ermöglicht FIX es Systemen auf den Kapitalmärkten, Aufträge, Ausführungen und Marktdaten in Echtzeit auszutauschen. Obwohl das Protokoll standardisiert ist, stellt die Integration in reale Systeme sowohl eine technische als auch eine geschäftliche Herausforderung dar.
Jakub Wincenciak
Jakub Wincenciak Head of Operations
Cybersecurity
2025-08-06

Codeabdeckung vs. Testabdeckung: Metriken, die für Compliance und Qualität entscheidend sind

Die Sicherstellung hoher Qualität und regulatorischer Konformität in qualitätsorientierten Branchen erfordert rigorose Softwaretests und Validierung. Zu den wichtigsten Kennzahlen zur Bewertung der Testeffektivität gehören Codeabdeckung und Testabdeckung. Obwohl eng miteinander verwandt, haben diese Begriffe unterschiedliche Bedeutungen und Implikationen.
Michał Woźniak
Michał Woźniak Software Developer

Kontaktieren Sie uns

Wir beantworten jede Anfrage und finden die optimale Strategie für den Erfolg Ihres Projekts.

Füllen Sie das Formular aus, und wir melden uns in Kürze bei Ihnen.

Lukas Kosiński

Lukas Kosiński

Chief Executive Officer

Der Administrator der personenbezogenen Daten ist Somco Software sp. z o.o., ul. Gen. Ottokara Brzoza-Brzeziny 13, 05-220 Zielonka, KRS: 855688. Die personenbezogenen Daten werden verarbeitet, um die im Kontaktformular gestellte Anfrage zu beantworten. Weitere Informationen, einschließlich einer Beschreibung der Rechte der betroffenen Personen, finden Sie in der Datenschutzerklärung.