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.
Die Beschriftungen in einer Formularspezifikation werden nicht übersetzt
Jede Beschriftung in einer Spezifikation — Panel-Titel, Checkbox-Labels,
Gruppenüberschriften — wird genau so angezeigt, wie Sie sie geschrieben
haben, unabhängig von der Sprache der Benutzeroberfläche. Es sind Daten, die
Ihr Plugin an den Editor sendet, keine Strings, die der Editor in einem
Übersetzungskatalog nachschlagen könnte. Soll Ihr Plugin mehrere Sprachen
sprechen, wählen Sie die Strings selbst, bevor Sie register aufrufen; die
aktuelle Sprache liefert
ctx.app_settings.get_string(mte.keys.UI_LANGUAGE) (leer bedeutet „dem
System folgen"). Dasselbe gilt für name und description aus Ihrer
plugin.json, die unter Einstellungen ▸ Erweiterungen erscheinen.
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:<key>" — 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:<key>" ist der kürzeste Weg, den Wert eines
Steuerelements zu persistieren:
- Beim Aufbau des Panels liest das Widget seinen Anfangswert aus
ctx.settings.get(key, <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.