Zum Inhalt

mte.ui — Formular-Spezifikations-Builder

Jede UI-Fläche der Phase 3 — ctx.docks.add_panel und ctx.settings_page.register — nimmt eine Formular-Spezifikation: ein einfaches Dict, das einen Widget-Baum beschreibt. Bauen Sie diese Spezifikationen mit den mte.ui.*-Helfern, damit Sie das JSON nicht von Hand schreiben müssen.

from mte.ui import (
    Column, Row, Group,
    Label, Button, Checkbox, LineEdit, NumberSpin, ComboBox, List,
)

Nichts in mte.ui spricht mit Qt oder PySide — jeder Helfer liefert ein Dict nach dem Wire-Schema, das der C++-Formularparser des Hosts erwartet. Komponieren Sie sie frei, verketten Sie Listen oder erzeugen Sie sie programmatisch:

from mte.ui import Column, Row, Label, Button

def make_toolbar(commands):
    return Row([Button(text=c["label"], on_click=c["id"])
                for c in commands])

form = Column([Label(text="Actions:"),
               make_toolbar(my_commands)])

Die Spezifikation wird hostseitig validiert; unbekannte Steuerelementtypen oder fehlende Pflichtfelder erzeugen einen InvalidParams-Fehler, den Sie im Protokoll sehen.


Layouts

Layout-Builder nehmen eine Liste von Kind-Dicts und ordnen sie vertikal oder horizontal an.

Column(children)

Stapelt Kinder von oben nach unten mit abschließender Dehnung — Steuerelemente behalten ihre natürliche Höhe, statt sich in einem hohen Dock aufzublähen.

Row(children)

Dieselbe Idee, von links nach rechts, mit abschließender horizontaler Dehnung.

Group(children, *, title="")

Ein betitelter Rahmen (gerendert als QGroupBox) mit vertikalem Stapel. Nutzen Sie ihn, um zusammengehörige Steuerelemente visuell zu gruppieren:

Group([
    Checkbox(id="cs", label="Case sensitive", binds="settings:cs"),
    Checkbox(id="ww", label="Whole words",    binds="settings:ww"),
], title="Search options")

Layouts verschachteln frei — eine Row in einer Column in einer Group ist in Ordnung.


Blatt-Steuerelemente

Jedes Blatt akzeptiert dieselben vier gemeinsamen Bindungen als Schlüsselwortargumente:

Argument Bedeutung
id= Stabile Id für ctx.ui.get / ctx.ui.set und (implizit) binds.
binds= "settings:<schlüssel>" — automatische Persistenz über ctx.settings.
on_click= Aufzurufende Befehls-Id — nur Buttons.
on_change= Handler-Id (ctx.docks.on_change(...)) — jedes andere Steuerelement.

Nur Blätter mit einem „Wert“ unterstützen binds und on_change.

Label(*, text="", id=None)

Statischer Text.

Button(*, text, on_click=None, id=None)

Eine Schaltfläche. Das Auslösen von on_click ruft den registrierten Befehl auf; wollen Sie die Schaltfläche mit etwas anderem synchron halten, können Sie ihren text per ctx.ui.set setzen.

Checkbox(*, label="", default=False, id=None, binds=None, on_change=None)

Boolesches Steuerelement. default ist der Anfangszustand; binds übersteuert ihn mit dem persistierten Wert, falls einer existiert.

LineEdit(*, placeholder="", default="", id=None, binds=None, on_change=None)

Einzeiliges Texteingabefeld.

NumberSpin(*, default=0, min=None, max=None, step=1, id=None, binds=None, on_change=None)

Ganzzahl-Spinbox. min und max begrenzen den Bereich (beide optional; die zugrundeliegende QSpinBox nutzt ihren Standardbereich, wenn ungesetzt). step ist das Inkrement der Pfeile.

int-Bereich

NumberSpin basiert auf QSpinBox, die einen int (32-Bit) speichert. Werte außerhalb von -2_147_483_648 … 2_147_483_647 sättigen am Plattformlimit.

ComboBox(*, items, default="", id=None, binds=None, on_change=None)

Dropdown. items ist eine Liste — jeder Eintrag darf eine einfache Zeichenkette sein oder ein Objekt wie {"value": "cpp", "label": "C++"} (heute wird nur value genutzt; label ist für eine spätere Verfeinerung reserviert).

List(*, items, id=None, on_change=None)

Listen-Widget mit Einzelauswahl. on_change feuert mit dem Text des neu gewählten Eintrags. Kein binds — persistieren Sie die Auswahl bei Bedarf selbst.


Zugriff zur Laufzeit

Sobald das Panel registriert ist, steuern Sie es aus jedem Befehl:

panel_id = ctx.docks.add_panel(id="my.panel", ..., form=Column([
    LineEdit(id="needle"),
    Checkbox(id="cs"),
]))

# Read current values
needle = ctx.ui.get(panel_id, "needle")
cs     = ctx.ui.get(panel_id, "cs") == "true"

# Write values (does NOT fire on_change)
ctx.ui.set(panel_id, "needle", "hello")
ctx.ui.set(panel_id, "cs", True)

Die vollständige Referenz: ctx.ui.


Werte persistieren

binds="settings:<schlüssel>" ist der kürzeste Weg, den Wert eines Steuerelements zu persistieren:

  • Beim Aufbau des Panels liest das Widget seinen Anfangswert aus ctx.settings.get(schlüssel, <default>).
  • Bei jeder Benutzeränderung schreibt das Widget über ctx.settings.set(schlüssel, neuer_wert) zurück.

Da Panels und Einstellungsseiten ctx.settings teilen, spiegeln sich zwei Steuerelemente mit derselben binds-Zeichenkette in Echtzeit. Genau so halten HelloPythons Dock und Einstellungsseite das „Loud“-Kästchen synchron.

Müssen Sie etwas persistieren, das das Vokabular nicht abdeckt (z. B. eine List-Auswahl), lesen/schreiben Sie direkt über ctx.settings in einem on_change-Callback.