Vega — Meine erste Anwendung

Von der leeren Datei zum laufenden Fenster: Anwendung anlegen, Fenster bauen, Knopf mit Handler, Ereignisschleife. Alles, was dieser Guide zeigt, gilt unverändert für größere Programme — Vega hat keinen zweiten, „richtigen„ Weg.

Vega VCL · Eigenschaften · Ereignisse · Komponenten


Das ganze Programm

unit Main;

import std.io;
import Vega.Types;
import Vega.Events;
import Vega.Canvas;
import Vega.Theme;
import Vega.Control;
import Vega.Font;
import Vega.Strings;
import Vega.Lists;
import Vega.Style;
import Vega.StdCtrls;
import Vega.Backend;
import Vega.BackendAuto;
import Vega.Forms;

var g_app: TApplication;
var g_ausgabe: TLabel;
var g_klicks: int64;

fn OnKlick(sender: TControl): void {
  g_klicks := g_klicks + 1;
  g_ausgabe.SetCaption(StrConcat("Klicks: ", IntToStr(g_klicks)));
}

fn OnBeenden(sender: TControl): void {
  g_app.Terminate();
}

fn main(): int64 {
  g_app := new TApplication(NewPlatformBackend());
  if (!g_app.Ready) {
    PrintLn("Kein Fenstersystem erreichbar (DISPLAY gesetzt?)");
    return 1;
  }

  var f: TForm := new TForm(320, 160, "Meine erste Anwendung");

  g_ausgabe := new TLabel("Klicks: 0");
  g_ausgabe.SetBounds(16, 16, 200, 20);
  g_ausgabe.SetParent(f);

  var b1: TButton := new TButton("Zaehlen");
  b1.SetBounds(16, 56, 120, 28);
  b1.OnClick := OnKlick;
  b1.SetParent(f);

  var b2: TButton := new TButton("Beenden");
  b2.SetBounds(160, 56, 120, 28);
  b2.OnClick := OnBeenden;
  b2.SetParent(f);

  if (!g_app.ShowForm(f)) {
    PrintLn("Fenster konnte nicht geoeffnet werden");
    return 2;
  }
  g_app.Run();
  g_app.Shutdown();
  return 0;
}

Übersetzen und starten — aus der Wurzel des lyx-vcl-Repositorys:

lyxc erste.lyx -I . -I platform/linux -o erste
./erste

Nachgemessen mit lyxc 1.1.3I: übersetzt fehlerfrei, rund 765 KB.


Die sieben Zeilen, auf die es ankommt

Zeile Wozu
import Vega.BackendAuto; Bringt NewPlatformBackend(). Welche Fassung das ist, entscheidet der Include-Pfad beim Übersetzen (platform/linux oder platform/win64), nicht der Quelltext.
new TApplication(NewPlatformBackend()) Die Anwendung: hält Fenster, Ereignisschlange und Zeitgeber.
if (!g_app.Ready) Kein Fenstersystem erreichbar (kein DISPLAY, kein X-Server). Immer prüfen — sonst stirbt das Programm später an einer Stelle, die nichts damit zu tun hat.
new TForm(320, 160, „…“) Ein Fenster mit Innenmaß und Titel.
SetBounds(links, oben, breite, hoehe) Position und Größe in einem Aufruf; Position ist relativ zum Elternteil.
b1.SetParent(f) Hängt das Element in den Baum. Ohne diesen Aufruf existiert es, wird aber nie gezeichnet.
g_app.ShowForm(f) / g_app.Run() Fenster anzeigen, dann die Ereignisschleife. Run kehrt erst nach Terminate() zurück.

Warum die Modulvariablen oben stehen

Handler sind freie Funktionen — sie bekommen nur ihren sender. Alles andere, was sie brauchen (die Anwendung, Anzeigefelder, Zustand), steht auf Modulebene. Damit ist der Zustand eines Fensters an einer Stelle sichtbar, statt über Abschlüsse verteilt.

Bis lyxc 1.1.3D kam ein zweiter Grund dazu: eine Modulvariable, die vor ihrer Deklaration benutzt wurde, zerfiel still in zwei Variablen (#1665). Das ist behoben — die Gewohnheit bleibt trotzdem die übersichtlichere.


Vier Fehler, die jeder einmal macht

  • SetParent vergessen. Das Element ist angelegt, hat Größe und Text — und ist unsichtbar.
  • Nach einer Zustandsänderung nicht Invalidate() rufen. Vega zeichnet nicht von selbst neu. SetCaption und die anderen Setter tun es für dich; wer ein Feld direkt schreibt (l.Caption := …), muss selbst neu zeichnen lassen.
  • Run() vergessen. Das Fenster erscheint kurz und das Programm endet.
  • Den Plattformpfad vergessen. Ohne -I platform/linux meldet der Compiler Modul nicht gefunden … Vega.BackendAuto.

Wie es weitergeht

Letzte Aktualisierung: 2026-08-19 — Beispiel mit lyxc 1.1.3I übersetzt.