UI-Adapter und Worker-Schnittstelle

Messklassen sind unabhängig von einer Terminal- oder Qt-Darstellung. Ein MeasurementUIAdapter überträgt Bedienerfragen, Logging und manuelle Interrupts über diese Grenze. Lang laufende Mess- und Geräteoperationen sind eine getrennte Aufgabe und werden in einem Worker ausgeführt.

Verantwortungsbereiche

Verantwortlichkeiten von UI und Worker

Komponente

Verantwortlich für

Nicht verantwortlich für

Messklasse

Ablauf, Autosave, Resume, EUT-Bewertung, Gerätelebenszyklus, Sicherheit

Widgetzustand und Qt-Ereignisverarbeitung

UI-Adapter

Fragen, Logtransport, Bedienereignisse, Interruptanforderungen

Messentscheidungen und direkten Gerätezugriff

Worker

Blockierende Skript- oder Geräteaufrufe, kooperativen Abbruch, Endzustand

Direkte Änderung von Widgets

GUI-Thread

Widgets, Dialoge, Plots und Ereignisschleife

Blockierende Mess- oder Kommunikationsaufrufe

Adaptermethoden

ask(msg, buttons, level, data) -> int

Zeigt eine Meldung und liefert den nullbasierten Index der gewählten Schaltfläche. buttons darf für eine reine Information leer sein. level und data sind Darstellungshinweise; die Messlogik darf nicht von einer bestimmten Widgetdarstellung abhängen.

emit_log(block, *args) -> None

Leitet einen Logblock an UI und konfigurierte Logziele weiter. Vollständige Fehler- und Sicherheitsmeldungen bleiben erhalten.

poll_key() -> int | None

Fragt ohne Blockierung ab und liefert einen Tastencode oder None. Messkerne rufen dies an definierten Bedien- und Sicherheitspunkten auf.

check_interrupt() -> int | None

Kompatibilitätsname, der an poll_key() delegiert.

pre_user_event() und post_user_event()

Markieren Anfang und Ende einer Bedieninteraktion, beispielsweise für den sichtbaren UI-Status oder die Terminalbehandlung.

run_interactive(obj, banner)

Startet eine interaktive Terminalsitzung, sofern unterstützt. Eine GUI darf melden, dass diese Funktion nicht verfügbar ist.

Der konkrete TUIAdapter erlaubt zusätzlich das Ersetzen von Messenger, Logger, Interrupttester, Pre-/Post-Callbacks und interaktivem Runner. Ein eigener Adapter benötigt den jeweiligen Setter nur, wenn Anwendungscode nach seiner Installation die entsprechende Measure.set_*-Methode aufruft.

Anbindung an Measure

Measure erzeugt standardmäßig einen TUIAdapter. set_ui_adapter(adapter) bindet folgende Kompatibilitätsattribute an den neuen Adapter:

messenger             -> ui.ask
UserInterruptTester   -> ui.check_interrupt
PollKey               -> ui.poll_key
PreUserEvent          -> ui.pre_user_event
PostUserEvent         -> ui.post_user_event

Gepflegter Code verwendet set_user_interrupt_tester. Die historische Schreibweise set_user_interrupt_Tester ist nur ein Kompatibilitätsalias. Beim Wiederherstellen eines Pickles wird der TUI-Standardadapter neu erzeugt, weil UI-Objekte und Callbacks nicht serialisiert werden. Skript oder Runner binden den gewünschten Adapter deshalb nach dem Laden erneut an.

resolve_poll_key(handler, caller_locals) bevorzugt einen expliziten Callback. Die Suche im Aufrufer-Frame bleibt nur als Rückfallebene erhalten. Neue Messkerne übergeben die Pollingfunktion ausdrücklich.

Qt-Adapter

QtUIAdapter kommuniziert mit MeasurementControlWidget über queued Qt-Signale:

prompt_requested

Überträgt Meldung, Schaltflächen, Level und Daten in den GUI-Thread.

log_requested

Fügt vollständigen Logtext ein, ohne das Widget aus dem Worker zu ändern.

status_changed

Aktualisiert den sichtbaren Lebenszykluszustand.

ask wartet im Mess-Worker auf einer threading.Condition, während die Qt-Ereignisschleife ansprechbar bleibt. Eine Schaltfläche ruft im GUI-Thread submit_answer auf und weckt den Worker. Diese blockierende Methode darf nicht aus dem GUI-Thread selbst aufgerufen werden.

Der gemeinsame qt_runner übernimmt die Standardanbindung:

  1. Text-Messskript als Modul laden;

  2. Konfiguration kopieren und aktualisieren;

  3. Quellen und Änderungen der effektiven Konfiguration erfassen;

  4. terminalgebundene messenger- und user_interrupt_tester-Callbacks entfernen;

  5. QtUIAdapter und dessen manuelle EUT-Überwachung anbinden;

  6. MeasurementTask in einen QThread verschieben;

  7. Erfolg, Stop und vollständige Exceptions über Signale zurückgeben;

  8. Worker und Thread nach Abschluss beenden und freigeben.

Das Steuerfenster trennt Messung und effektive Konfiguration in Tabs. Der Konfigurationstab ist read-only und zeigt Wert sowie zuletzt ändernde Quelle. Die Schaltfläche Stop / RF Off liegt außerhalb der Tabs und bleibt daher auch beim Prüfen der Konfiguration unmittelbar erreichbar.

Stop und RF-Off

Die Qt-Schaltfläche Stop / RF Off verwendet zwei Pfade:

  • Bietet eine aktive Frage Quit an, wird diese Antwort ausgewählt.

  • Andernfalls wird eine thread-sichere Interruptanforderung gespeichert. poll_key liefert den synthetischen Tastencode genau einmal.

Der Adapter greift nicht auf Hardware zu. Der Mess-Worker erhält die Anforderung am nächsten Pollingpunkt und führt den regulären RF-Off- und Abschlusspfad aus. Die Reaktionszeit hängt daher von begrenzten Geräteaufrufen und kurzen, dokumentierten Pollingintervallen ab. Ein unbegrenzt im Treiber blockierter Worker wird nicht allein durch eine GUI-Schaltfläche sicher.

Ein separater unmittelbarer Hardware-Sicherheitspfad ist nur zulässig, wenn Gerät und Kommunikationsschicht dies ausdrücklich unterstützen. Zugriffe auf einen gemeinsamen Transport müssen serialisiert werden; konkurrierende Kommandos aus GUI- und Worker-Thread können den Protokollzustand beschädigen.

Manuelle und automatische EUT-Überwachung

Manuelle Intervention bleibt bei jeder Störfestigkeitsexposition verfügbar. QtUIAdapter.manual_eut_monitor wird durch qt_runner an passende Messparameter gebunden. Während der Exposition kann der Bediener degraded, failed oder not_evaluated melden. Nach der Exposition werden Zustand und Wiederherstellung getrennt eingegeben.

Automatische Kamera-, Kommunikations- oder Messkanalüberwachungen ergänzen diesen manuellen Pfad über CompositeEUTMonitor und können in einem ThreadedEUTMonitor laufen. Sie ersetzen die Bedienereingabe nicht. Die EUT-Ereignisstruktur und Bewertungsregeln legen die Rückmeldung an den Messkern fest. Die vollständige Verwendung und Erweiterung beschreibt EUT-Überwachung verwenden und erweitern.

Worker-Aufbau

Ein Worker benötigt genau einen Start-Slot, begrenzte Operationen, kooperativen Abbruch und genau einen Endzustand für Erfolg, Abbruch oder Fehler. Qt-Signale transportieren kleine, unveränderliche Objekte. Hochratige Scans müssen Fortschrittsdaten bündeln; tausende queued Einzelsignale können die GUI noch blockiert erscheinen lassen, wenn das Gerät bereits fertig ist.

Callbacks des ReceiverScanWorker laufen in dessen Python-Worker-Thread. Eine GUI überführt sie über Qt-Signale oder eine thread-sichere Queue in den GUI-Thread. Das optionale safety_stop wird bei Abbruch oder Fehler höchstens einmal ausgeführt.

Beim Schließen während einer laufenden Aufgabe wird Stop angefordert, begrenzt gewartet und ein eindeutiger Endzustand angezeigt. QThread.quit() beendet nur die Ereignisschleife des Threads; bereits laufender Python-Code in einem Worker-Slot wird dadurch nicht unterbrochen.

Implementierungs-Checkliste

Für eine neue Oberfläche:

  • alle Kernmethoden des Adapters mit obiger Rückgabesemantik implementieren;

  • Widgets ausschließlich im GUI-Thread erzeugen und ändern;

  • das vollständige Messskript in genau einem verwalteten Worker ausführen;

  • Fragen, Logs, Fortschritt, Abbruch und Exceptions ausdrücklich überbrücken;

  • manuelle EUT-Meldung jederzeit erreichbar halten;

  • Stop während Warten, Scan, Frage, Leveling und Fehlerbehandlung testen;

  • vollständigen RF-Off-/Abschlusspfad und Autosave-Zustand erhalten.

Tests

Qt-Tests laufen mit QT_QPA_PLATFORM=offscreen. Sie prüfen mindestens: ansprechbare UI, Wecken des Workers durch Fragen, inkrementellen Fortschritt, einmalige Stopverarbeitung mit RF-Off, vollständigen Traceback, getrennte EUT-Zustands- und Wiederherstellungsangaben sowie begrenztes Verhalten beim Schließen.

Die englischsprachige kuratierte UI-API listet Adapter, Runner und Worker-Einstiegspunkte.