ESP32-S3 Bench Guide
ESP32‑S3 N16R8 벤치 가이드: 실시간 핀아웃, 강의, 시뮬레이터 및 벤치 로그
아마추어 무선 N·E·A 등급 시험 학습·시험 트레이너, 자유·오픈소스, Linux·Windows·macOS·Android 지원
Lern- und Prüfungstrainer für die Amateurfunkprüfung der Klassen N, E und A. Frei, quelloffen, für Linux, Windows, macOS und Android.
교육C++ · QMLGitHub @janmetz76-byte온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Lern- und Prüfungstrainer für Amateurfunk (Klassen N, E, A) mit bearbeitbaren XML-Fragenkatalogen
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Neu aufgebaut von Jan - DC6DX.
Lern- und Prüfungstrainer für den Amateurfunk, mit ausdrücklich bearbeitbaren Fragenkatalogen für die Prüfungsklassen N, E und A.
Der Quellcode steht unter der GNU General Public License v3 oder später (siehe LICENSE).
Die Fragentexte selbst sind nicht unter der GPL. Sie stammen aus dem maschinenlesbaren Fragenkatalog der Bundesnetzagentur und stehen unter der Datenlizenz Deutschland – Namensnennung – Version 2.0 (DL-DE-BY-2.0). Diese Lizenz erlaubt ausdrücklich Vervielfältigung, Bearbeitung und Weitergabe, verlangt aber den Quellenvermerk und den Hinweis auf Änderungen. Beides ist in den Metadaten jedes Katalogs abgelegt — siehe Lizenz und Quellenvermerk.
Das Vorgängerprogramm HamRadioTrainer von DM1OLI wird nicht mehr
weiterentwickelt. Der Originalquellcode liegt nicht vor, die Fragenkataloge des
Vorgängers lagen in einem verschlüsselten Binärformat (.etq) vor und sind
inhaltlich veraltet.
Deshalb wird hier bewusst neu aufgebaut:
| Plattform | Status |
|---|---|
| Linux (X11/Wayland) | gebaut und getestet |
| Windows 10/11 x64 | CI-Build (GitHub Actions), Paketierung über windeployqt |
| macOS 12 oder neuer | Universal-Binary (Intel und Apple Silicon) als .dmg, gebaut und getestet unter macOS 14 auf Intel |
Voraussetzungen: CMake ≥ 3.21, ein C++20-fähiger Compiler, Qt 6.5 oder neuer
mit den Modulen Core, Gui, Widgets, Xml und optional Test.
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build
./build/HamRadioTrainer2026
Distributionen mit Qt 6:
# Arch / CachyOS
sudo pacman -S --needed cmake ninja qt6-base
# Debian / Ubuntu
sudo apt install cmake ninja-build qt6-base-dev
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release
cmake --install build --prefix dist
cmake --install ruft windeployqt auf und legt die Qt-Laufzeitbibliotheken
neben der EXE ab. Ergebnis ist ein Verzeichnis dist, das ohne Installation auf
einem anderen Windows-Rechner läuft.
sudo pacman -S --needed llvm-mingw 7zip qt6-base qt6-svg
tools/windows-cross.sh
Das Skript lädt Qt für Windows (llvm-mingw) in derselben Version wie das
Host-Qt nach ~/.local/share/hamradiotrainer-cross, baut nach build-win/ und
stellt in dist-win/ einen portablen Ordner mit allen benötigten DLLs und
Qt-Plugins zusammen, zusätzlich als HamRadioTrainer2026-windows-x64.zip.
Einzelschritte: setup, build, deploy.
Auf einem Mac genügen die Xcode Command Line Tools; Homebrew ist nicht nötig.
xcode-select --install
tools/macos-build.sh # setup, build, test und package
Das Skript holt CMake, Ninja und Qt in ein eigenes Verzeichnis unter
~/.local/share/hamradiotrainer-macos, baut ein Universal-Binary für Intel und
Apple Silicon nach build-macos/ und legt
hamradiotrainer-2026-<version>-macos-universal.dmg ins Quellverzeichnis.
macdeployqt packt Qt, Kataloge und Symbol in das Bundle und signiert es ad
hoc. Einzelschritte: setup, build, test, package.
Die App ist nicht von Apple beglaubigt (Notarisierung braucht ein kostenpflichtiges Entwicklerkonto). Beim ersten Start öffnet man sie daher per Rechtsklick → „Öffnen“; ab macOS 15 über Systemeinstellungen → Datenschutz & Sicherheit → „Dennoch öffnen“.
sudo pacman -S --needed qt6-base qt6-svg qt6-declarative 7zip
tools/android-build.sh # APK für Handys (arm64-v8a)
tools/android-build.sh install # per USB-Debugging aufs Handy
HRT_ANDROID_ABI=x86_64 tools/android-build.sh # für den Emulator
Unter Android läuft eine eigene Oberfläche mit Qt Quick (src/mobile/) auf
demselben Kern wie die Desktop-Version: gleiche Lernregeln, gleiche
Prüfungsauswertung, gleiche Fortschrittsdatei. Voraussetzung sind Android SDK
mit NDK und JDK 17. Das Skript lädt Qt für Android in der Version des Host-Qt.
Die APK ist mit dem Debug-Schlüssel signiert und damit für eigene Geräte
gedacht. App-Symbol und Startbildschirm in android/res/ erzeugt
tools/android-icons.sh aus resources/icons/app.svg.
Am Desktop lässt sich die Handy-Oberfläche als hrt-mobile-preview in
Handygröße starten.
Das Format ist in schema/catalog.xsd definiert und
absichtlich streng gehalten:
<catalog schemaVersion="1">
<metadata>
<title>Prüfungskatalog Klasse E</title>
<examClass>E</examClass> <!-- N | E | A -->
<examId>DE-E</examId>
<catalogVersion>2026-01</catalogVersion>
<validFrom>2026-01-01</validFrom>
</metadata>
<parts>
<part id="DE-E-1" title="Teil 1" order="1">
<section id="DE-E-1-1" title="Recht" order="1">
<selection questions="40" errorPoints="360"/>
<chapters>
<chapter id="DE-E-1-1-1" title="Allgemeines" order="1">
<questions>
<question id="DE-E-1-1-1-001" order="1" type="single" points="2">
<text>Frage?</text>
<answers>
<answer id="DE-E-1-1-1-001-a" order="1" correct="true" text="Richtig"/>
<answer id="DE-E-1-1-1-001-b" order="2" correct="false" text="Falsch"/>
</answers>
<explanation>Begründung</explanation>
<history>
<addedOn>2026-01-01</addedOn>
<changedOn>2026-07-01</changedOn>
<retiredOn>2027-01-01</retiredOn>
</history>
</question>
</questions>
</chapter>
</chapters>
</section>
</part>
</parts>
</catalog>
Die Element- und Attributnamen sind englisch, damit Werkzeuge sprachneutral bleiben. Oberfläche und Dokumentation sind deutsch.
Kennungen (id) sind dokumentweit eindeutig und beginnen mit der Kennung des
übergeordneten Kapitels, damit die Zuordnung beim Nachtragen von Fragen
nachvollziehbar bleibt.
points und Fehlerpunktepoints ist die Zahl der Fehlerpunkte, die im amtlichen Prüfungswesen für eine
falsche Antwort auf diese Frage berechnet werden. Prüfungssimulationen werden
danach zusammengestellt, dass Fehlerpunktbudget der Prüfungsordnung eingehalten
wird.
historyaddedOn, changedOn und retiredOn machen den Stand einer Frage nachvollziehbar.
Zurückgezogene Fragen (retiredOn) bleiben im Katalog, damit alte Lernstatistiken
reproduzierbar bleiben, werden aber nie neu gezogen. Gesperrte Fragen
(locked="true") werden ebenfalls nie gezogen, können aber noch in alten
Statistiken vorkommen.
Das Programm prüft beim Start, ob die geladene Katalogdatei noch die
ausgelieferte ist. Der Vergleich läuft über data/catalogs/catalog-manifest.json,
das beim Import mitgeschrieben wird und je Klasse Prüfsumme, Auflagenzahl und
Auflage enthält. Der Prüfbericht sagt daraufhin:
Das ist der ganze Nachrichtenstand, den es geben kann: ob die Bundesnetzagentur inzwischen eine neue Auflage veröffentlicht hat, weiß nur das Archiv, das man selbst herunterlädt. Das Programm sagt das ausdrücklich, statt eine Versionsnummer zu erfinden.
Aktualisieren: Datei → Fragenkatalog aktualisieren… wählt das Verzeichnis
mit fragenkatalog3b.json aus dem geladenen Archiv. Das Programm schreibt
alle drei Klassen und die Bilder in das Verzeichnis der geöffneten Katalogdatei,
fragt vorher nach und nennt danach, wie viele Fragen und Bilder übernommen
wurden. Anschließend lädt es den Katalog neu.
Zwei Folgen sind gewollt und werden vorher angekündigt:
data/catalogs eine Sicherung an, bevor er überschreibt.Der Aufruf hrt-catalog-import macht dasselbe auf der Kommandozeile und ist
der Weg für eigene Katalogdateien und für die CI.
Geschrieben wird in das Verzeichnis der gerade geöffneten Katalogdatei. Bei
einer Systeminstallation unter /usr oder /usr/local gehört das dem
Administrator; das Programm sagt das, wenn es dort keine Sicherung anlegen
kann, statt es zu versuchen und halb zu scheitern.
Die amtlichen Daten liegen als fragenkatalog3b.json plus Verzeichnis svgs/
vor. hrt-catalog-import erzeugt daraus je Prüfungsklasse einen Katalog,
kopiert die benötigten Bilder und schreibt den Sollstand:
./build/hrt-catalog-import \
--source /pfad/zum/Pruefungsfragen \
--output data/catalogs
Ergebnis des Imports der 3. Auflage, März 2024:
| Katalog | N | E | A | Betriebliche Kenntnisse | Kenntnisse von Vorschriften | gesamt |
|---|---|---|---|---|---|---|
| Klasse N | 195 | – | – | 172 | 204 | 571 |
| Klasse E | 195 | 463 | – | 172 | 204 | 1034 |
| Klasse A | 195 | 463 | 716 | 172 | 204 | 1750 |
Ein Zertifikat deckt alle technischen Blätter bis zur eigenen Klasse ab: Klasse N
umfasst V, B und N, Klasse E zusätzlich E, Klasse A zusätzlich A. Die Zahlen
stammen aus dem Import der 3. Auflage und lassen sich mit
./build/hrt-catalog-import --source … --output /tmp/pruefung nachrechnen.
Es werden 687 SVG-Dateien kopiert.
Die BNetzA führt „Betriebliche Kenntnisse" und „Kenntnisse von Vorschriften" ausschließlich mit der Klassenangabe 1. Ihre Zugehörigkeit zu den Klassen E und A lässt sich aus den Prüfungsunterlagen begründen:
Für den Erwerb einer Amateurfunkprüfungsbescheinigung müssen die Prüfungsteile „Technische Kenntnisse", „Betriebliche Kenntnisse" und „Kenntnisse von Vorschriften" erfolgreich abgelegt werden. Die Inhalte und Anforderungen der Prüfungsteile unterscheiden sich bei den Klassen A, E und N nur im Prüfungsteil „Technische Kenntnisse". — Bundesnetzagentur, https://www.bundesnetzagentur.de/Amateurfunk
Alle drei Prüfungsteile werden also für jede Klasse verlangt, und nur „Technische Kenntnisse" ist klassenspezifisch. Der Import behandelt die beiden anderen deshalb als gemeinsamen Pool aller Klassen und interpretiert die Klassenangabe 1 als „eingeführt mit Klasse N", nicht als „nur in Klasse N".
Das ist eine Auslegung der Prüfungsordnung, keine Aussage der Datei. Sie
steht deshalb in den notes jedes erzeugten Katalogs und lässt sich mit
--no-shared-parts abschalten. Zwei Tests sichern die Regel ab: jeder Katalog
muss drei Prüfungsteile führen, und die beiden gemeinsamen Teile müssen in allen
drei Klassen identisch sein.
Daraus folgt auch die Erklärung der Zahlen aus dem vorherigen Abschnitt: Klasse N
umfasst mehr Fragen als E, weil N alle drei Prüfungsteile abdeckt, E und A
dagegen nur die Technischen Kenntnisse klassenspezifisch haben. Die Poolgröße
ist nicht der Prüfungsumfang – wie viele Fragen tatsächlich gezogen werden,
steht nicht in der Quelldatei (siehe selection).
Zwei Eigenheiten der Quelle, die im Format berücksichtigt sind:
answer_a. Der Importer verteilt sie
deshalb beim Import auf einen der vier Plätze, sonst verriete schon das
Katalogfile die Lösung. Für die Prüfungssimulation werden die Antworten
zusätzlich gemischt.answer ein Attribut image ohne text.Fehlerpunkte werden in der Quelle nicht veröffentlicht. Alle importierten
Fragen haben daher points="0", was im Schema „unbekannt" bedeutet. Die
Prüfungssimulation kann das Fehlerpunktbudget der Prüfungsordnung erst
einhalten, wenn die Punkte ergänzt werden; der Validator weist darauf einmal je
Katalog hin.
Die fünf Prüfungsteile und der Prüfungsumfang folgen der Amtsblatt-Verfügung 29/2024 (gültig ab 24.06.2024), nicht der Gliederung der Quelldatei:
| Prüfungsteil | Inhalt | Fragen | Punkte | Bestehen | Fehlerpunkte | Zeit |
|---|---|---|---|---|---|---|
| V | Kenntnisse von Vorschriften | 25 | 25 | 19 | 6 | 45 min |
| B | Betriebliche Kenntnisse | 25 | 25 | 19 | 6 | 45 min |
| N | Technische Kenntnisse, Klasse N | 25 | 25 | 19 | 6 | 45 min |
| E | Technische Kenntnisse, Klasse E | 25 | 25 | 19 | 6 | 45 min |
| A | Technische Kenntnisse, Klasse A | 25 | 25 | 19 | 6 | 60 min |
Eine Frage zählt einen Fehlerpunkt, da die Verfügung für jede richtige Antwort einen Punkt vorsieht. Bestanden sind 19 der 25 Punkte, also sind 6 falsche Antworten zulässig. Wird nur ein Teil nicht bestanden, folgt die mündliche Nachprüfung in genau diesem Teil.
Eine Bescheinigung umfasst alle Teile bis einschließlich der eigenen Klasse, weil Inhaber einer niedrigeren Klasse nur die höheren Teile ablegen:
| Zertifikat | Prüfungsteile | Bögen | Fragen je Prüfung | Pool im Katalog |
|---|---|---|---|---|
| Klasse N | V, B, N | 3 | 75 | 571 |
| Klasse E | V, B, N, E | 4 | 100 | 1034 |
| Klasse A | V, B, N, E, A | 5 | 125 | 1750 |
Die Quelldatei kennt diese Aufteilung nicht. Sie gliedert nach „Betriebliche Kenntnisse“, „Kenntnisse von Vorschriften“ und „Technische Kenntnisse“; letztere trägt je Frage eine Klassenmarkierung, die Teile V und B tragen überhaupt keine. Der Importer führt diese Gliederung in die amtlichen Prüfungsteile über: V und B werden klassenübergreifend gemeinsam genutzt, die technischen Fragen werden nach ihrer Klassenmarkierung auf N, E und A verteilt. Für Klasse E enthält der Katalog deshalb auch den N-Prüfungsteil, für Klasse A zusätzlich N und E.
Prüfungsfragen/fragenkatalog3b.json, 3. Auflage, März 2024, gültig ab 24.06.2024Pruefungsfragen/svgs/, 687 benötigte BilderIn der Quelle ist die erste Antwort richtig; im Katalog steht sie deshalb an
wechselnden Plätzen. Die Quelldatei nennt keine
Fehlerpunkte je Frage; der Wert 1 stammt aus der Verfügung und steht als
defaultPoints in den Katalogmetadaten.
hrt-catalog-import --source <Pfad zu Pruefungsfragen> --output data/catalogs
hrt-catalog-tool --info data/catalogs/*.xml
Bestehende Katalogdateien lassen sich ohne Neuimport umstellen; das Skript bildet dieselbe Permutation nach, die der Import anwendet:
python3 tools/catalog-reshuffle-answers.py data/catalogs/*.xml
Unverschlüsseltes, handeditierbares XML gemäß schema/catalog.xsd. Es lässt
sich in jedem Texteditor öffnen, gezielt durchsuchen und ergänzen. Die
Prüfungsumfang-Angaben liegen am Prüfungsteil:
<part id="DE-A-teil5-a" title="A (Technische Kenntnisse, Klasse A) …" order="5">
<selection questions="25" errorPoints="6" passScore="19" minutes="60"/>
<section id="DE-A-teil5-a-abschnitt1" title="…" order="1">
<chapters>
<chapter id="…" title="…" order="1">
<question id="DE-A-a-0123" type="single">
<text>…</text>
<answers>
<answer id="DE-A-a-0123-a" correct="true">…</answer>
</answers>
</question>
</chapter>
</chapters>
</section>
</part>
Lizenzen: Programm GPL-3.0-or-later, Fragentexte und Bilder
DL-DE-BY-2.0 mit verpflichtendem <attribution>.
Der Quellkatalog führt die richtige Antwort immer an erster Stelle. Diese Reihenfolge darf den Lernenden nie erreichen, sonst wäre „immer das erste Feld anklicken" eine gewinnende Strategie.
Deshalb wird sie schon beim Import verteilt: spreadAnswers() in
hrt-catalog-import bildet aus FNV-1a über die Fragekennung eine
Fisher-Yates-Permutation und schreibt die richtige Antwort an einen der vier
Plätze – in den ausgelieferten Katalogen etwa zu je einem Viertel. Der
Vorgang hängt nur von der Kennung ab, nicht von der Prozess-ID: derselbe
Quellkatalog ergibt stets dieselbe Datei, und tools/catalog-reshuffle-answers.py
rechnet dieselbe Permutation in Python nach, um bestehende Dateien ohne
Neuimport umzustellen.
PaperBuilder mischt zusätzlich für jede Frage eine eigene
Antwortreihenfolge, abgeleitet aus einer Startzahl der Prüfung. Gleiche
Startzahl und gleiche Frage ergeben immer dieselbe Reihenfolge – eine Prüfung
lässt sich damit später exakt nachvollziehen oder erneut ausdrucken. Eine
feste Reihenfolge wie D,B,A lässt sich vorgeben, etwa für einen gemeldeten
Fehler in der Originalprüfung.
Sicher beherrschte Fragen sollen seltener gestellt werden als unsichere. Der
Scheduler hält je Frage eine Lernstufe (0–5), die Trefferquote, das
Datum der letzten Beantwortung, den Fälligkeitstermin und die
Selbsteinschätzung des Lernenden.
Gewicht einer Frage:
| Faktor | Wirkung |
|---|---|
| noch nie gestellt | Faktor 10, damit der Pool vollständig einmal durchlaufen wird |
| Lernstufe (Leitner) | Faktor 0,45 je Stufe |
| „sicher" beantwortet | × 0,30 |
| „ziemlich sicher" | × 0,55 |
| „unsicher" | × 1,60 |
| „geraten" | × 2,20 |
| heute schon gestellt | × 0,05, verhindert Doppelungen in einer Sitzung |
| lange nicht gesehen | × bis 2,0 nach 60 Tagen |
Eine richtige Antwort, die der Lernende aber nur geraten hat, erhöht die Stufe kaum – sie kommt also bald wieder. Eine als „sicher" empfundene richtige Antwort erhöht ihn doppelt und verschiebt die Frage weit hinaus. Falsche Antworten senken die Stufe um zwei.
Eine Prüfungssimulation kann die Fragen je Prüfungsteil als Quote vorgeben
(Options::questionsPerPart), was für Klasse N mit ihren drei Prüfungsteilen
notwendig ist.
Stand: alle 168 Tests in 14 Programmen sind grün. Die Anwendung ist funktionsfähig; offen sind vor allem die Verpackung in weitere Linux-Formate und die Veröffentlichung.
Erledigt:
hrt-catalog-tool und hrt-catalog-importDie Bedienelemente tragen Bilder aus resources/icons/: Menüpunkte, die drei
Ansichten, die Knöpfe im Lernen und in der Prüfung, der Kopierknopf im
Prüfbericht. Die Bilder liegen im Programm, statt aus dem System zu kommen —
auf Windows gibt es gar kein Icon-Thema, und auf Linux wäre die Anwendung von
einem Tag auf den nächsten anders ausgestaltet.
Jedes Bild existiert zweimal, mit dunkler und mit heller Tinte; das Programm
wählt zur Laufzeit die passende Variante. Die Strichzeichnungen entstehen aus
resources/icons/generate.py: 24er Raster, 1,7 Strichstärke, abgerundete
Enden. Wer eines ändert, ändert eine Zeile dort und lässt das Skript laufen,
statt eine einzelne Datei zu überschreiben.
Die sechs stufe-*.svg gehören zur Lernstufenleiste und entstehen nicht von
Hand: Sie unterscheiden sich nur darin, wie viele von fünf Balken gefüllt sind,
und werden deshalb im Skript aus der Stufennummer erzeugt. Gezeichnet wird die
Stufe als Empfänger — fünf Balken, die von links nach rechts zunehmen und sich
mit der Stufe füllen, von Grau über Rot, Orange und Bernstein bis Grün.
Jede Stufe hat zwei Farben, eine für hellen und eine für dunklen Grund, weil ein einzelnes Rot auf Weiß gut sichtbar und auf Schwarz fast weg ist. Alle Töne liegen über 3:1 Kontrast auch gegen die dunkelste Zellenfarbe. Stufe 0 bleibt farblos: „neu" ist kein schlechtes Ergebnis, sondern schlicht keins.
Die Form trägt die Information neben der Farbe mit — fünf gefüllte Balken sind auch ohne Farbunterscheidung von einem gefüllten zu unterscheiden. Wer Rot und Grün nicht unterscheiden kann, liest die Stufe trotzdem richtig.
Der Zellenhintergrund bleibt deshalb grau und wird nur dunkler, je mehr Fragen in der Stufe liegen. Er trägt die Anzahl, das Bild die Stufe; ein grüner Hintergrund unter einem gelben Stufenbild läse sich sonst als mittlere Stufe, obwohl die Zelle über die Anzahl sagt und nichts über die Stufe.
app.svg ist das Programmsymbol. Für Windows entsteht daraus app.ico
(16 bis 256 Pixel), weil Windows das Bild aus der Programmdatei selbst liest —
ohne sie zeigt der Explorer ein Platzhalterbild und die Taskleiste gar keins.
Beide Dateien werden erzeugt von
python3 resources/icons/generate.py
Ist rsvg-convert oder ImageMagick nicht vorhanden, entfällt das .ico; die
Anwendung baut dann weiter und meldet es beim Einrichten.
Der Test icons prüft den Satz: dass jedes Bild lädt, dass jedes etwas zeichnet
und keines zu schwer ist, dass jeder Menüpunkt und jeder Knopf ein Bild trägt
und dass kein Bild im Satz herumliegt, das niemand benutzt.
Der Fortschritt liegt je Prüfung im Anwendungsdatenverzeichnis, nicht im Katalog, weil die Kataloge bearbeitbar und Teil der Auslieferung sind:
| System | Pfad |
|---|---|
| Linux | ~/.local/share/HamRadioTrainer2026/fortschritt-de-e.json |
| Windows | %APPDATA%\HamRadioTrainer2026\fortschritt-de-e.json |
Die Datei wird nach jeder ausgewerteten Prüfung und beim Beenden atomar geschrieben. Sie enthält Lernstufe, Trefferquote, Fälligkeit, Selbsteinschätzung, den SHA-256-Abdruck der Katalogdatei, zu der sie gehört, und je Frage einen Fingerabdruck ihres Wortlauts.
Ein geänderter Katalog kostet den Fortschritt nicht. Das Programm vergleicht nicht die ganze Datei, sondern Frage für Frage:
| Fall | Was mit dem Lernstand geschieht |
|---|---|
| Frage unverändert | Stand bleibt vollständig |
| Kennung noch da, Wortlaut anders | Frage zählt neu — die alte Antwort galt einem anderen Wortlaut |
| Frage gibt es nicht mehr | Stand entfällt, wird aber gezählt |
Beim Start mit geändertem Katalog fragt das Programm und nennt die Zahlen:
Fortschritt übernehmen (Voreinstellung) oder Neu beginnen. Ein Schließen des
Fensters oder Escape gilt als übernehmen — eine unbeabsichtigte Antwort darf
nichts kosten. Vorher landet die bisherige Datei als fortschritt-<klasse>.json.bak
neben der neuen, damit auch die Wahl Neu beginnen nichts endgültig löscht.
Warum nicht einfach alles behalten: eine umformulierte Frage, deren alte Antwort mit „Lernstufe 4“ dasteht, sagt nichts darüber aus, wie gut die neue Fassung beherrscht wird. Sie neu zu zählen ist ehrlicher als sie zu belügen — und kostet nur diese eine Frage.
Eine Fortschrittsdatei ohne Fingerabdrücke (Formatstand 1, vor dieser Erweiterung) wird nach der Kennung übernommen. Das Programm sagt dabei, dass es nur die Nummer verglichen hat und nicht den Wortlaut.
Unter Datei lässt sich der Fortschritt bewusst zurücksetzen.
Die Ansichtsleiste links entspricht der Arbeitsweise des Originals von 2015: Katalogansicht, Fragen lernen, Prüfungssimulation. Die Katalogansicht zeigt den Kapitelbaum mit Fragezahlen, daneben die Fragen des gewählten Kapitels mit den Spalten Kennung, Frage, Lernstufe, Letzte Abfrage, Wiedervorlage und darunter die Frage mit ihren Antworten, dem Lösungshinweis und dem Lernfortschritt. Dieselben Spaltennamen benutzt das Original, damit die Ansicht für Lernende wiedererkennbar bleibt.
Der Bereich Lernen zeigt den Stand und lädt zum Üben ein:
Nach jeder Antwort fragt die Runde, wie sicher die Antwort war. Das ist der Punkt, an dem eine Prüfung nicht weiterkommt: eine Prüfung enthält keine Selbstauskunft und speichert deshalb ein neutrales Ergebnis. Erst die Übungsrunde erhebt sie, und damit sinkt eine richtig geratene Frage schneller zurück als eine sicher gewusste.
Ohne Angabe fällt der Wert „unsicher“ an: die bereits gemeldete Selbsteinschätzung bleibt erhalten, statt überschrieben zu werden.
Wird „nur fällige“ gewählt, kommen die fälligen Wiederholungen vor den noch nie gesehenen Fragen. Sonst würde eine kurze Runde vollständig aus neuen Fragen bestehen und das Filterziel verfehlt.
219 der 1750 Fragen der Klasse A enthalten Formeln. Der Vorrat wurde in den Katalogen selbst gemessen und ist klein:
| Formelstellen | 355 |
Umgebungen (\begin{…}) | keine |
| Befehle | \lambda, \Omega, \eta, \varphi, \text, \textrm, \cdot, \circ, \frac, \dfrac, \sqrt, \left, \right |
Damit rechtfertigt der Bestand keine vollständige TeX-Installation. LatexFormatter
bildet genau diese Befehle auf Qt-Richtext ab – griechische Buchstaben als
Unicode, ^{…} und _{…} als Hoch- bzw. Tiefstellung, Brüche als
Zähler⁄Nenner und \sqrt als √(…). Das wiegt deutlich leichter als KaTeX
mit QtWebEngine und hängt nicht an einer zusätzlichen Laufzeitabhängigkeit.
Es werden drei Delimiter unterstützt: $…$, $$…$$ und \[…\].
Ein nicht abgedeckter Befehl wird nicht entfernt, sondern bleibt sichtbar stehen. Eine Formel, die nicht dargestellt werden kann, soll einen sichtbaren Riss zeigen und nicht stillschweigend fehlen.
Der Test everyFormulaOfTheCatalogsRenders prüft alle 356 Formeln der
ausgelieferten Kataloge darauf, dass keinerlei Rückstriche übrig bleiben.
Drei Stellen der Quelle schreiben Markup außerhalb jeder Formel (4 \mOhm,
4,7 \kiloOhm, ein \glqq). Der Import schreibt sie als mΩ, kΩ und
„ in den Katalog, damit die von Hand zu bearbeitenden Dateien lesbar bleiben.
Noch offen:
| Gegenstand | Lizenz |
|---|---|
| Quellcode der Anwendung | GPL-3.0-or-later |
| Fragentexte und Bilder | DL-DE-BY-2.0 |
Der Quellenvermerk steht in jedem Katalog in drei Feldern, weil die Angaben unterschiedliche Fragen beantworten:
| Element | Inhalt |
|---|---|
<attribution> | die Fragenbasis, wörtlich |
<authority> | der Herausgeber mit Anschrift |
<licenseName> / <license> | die Lizenz im Klartext und als Kennung |
Fragenbasis: Prüfungsfragen zum Erwerb von Amateurfunkprüfungsbescheinigungen, Bundesnetzagentur, 3. Auflage, März 2024 (www.bundesnetzagentur.de/amateurfunk)
Herausgeber: Bundesnetzagentur für Elektrizität, Gas, Telekommunikation, Post und Eisenbahnen, Tulpenfeld 4, 53113 Bonn
Lizenz Fragenkatalog: Datenlizenz Deutschland – Namensnennung – Version 2.0 (www.govdata.de/dl-de/by-2-0) Datenlizenz: DL-DE-BY-2.0
Die Hilfe (Hilfe → Über HamRadioTrainer 2026) zeigt genau diese drei Blöcke,
aus den Metadaten der geladenen Datei. Vorher stand dort ein Bausatz, in dem die
Lizenz mitten im Quellenvermerk hing und der Prüfungsumfang aus der
Amtsblatt-Verfügung genannt wurde — beides gehört an andere Stellen: der
Umfang in die Prüfungsteile und die notes des Katalogs, die Lizenz auf ihre
eigene Zeile.
Sobald ein Katalog von Hand geändert wird, verlangt DL-DE-BY-2.0 zusätzlich den
Hinweis auf die Änderung. Dafür gibt es das Element
<modifiedSinceSource>true</modifiedSinceSource>; der Validator erinnert daran.
Beides gehört in die Anzeige der Anwendung.
DL-DE-BY-2.0 und GPL-3.0 stehen nicht im Widerspruch: Die Namensnennungsplicht bindet den Fragentext, nicht den Anwendungscode.
Beim ersten Start fragt ein Einrichtungsassistent nach der Prüfung, den Prüfungsteilen und – freiwillig – dem Prüfungstermin. Das Vorbild ist der Konfigurations-Assistent des Originals von 2015, der dasselbe fragte.
Angeboten sind nur die Kombinationen, die es nach Amtsblatt-Verfügung 29/2024 tatsächlich gibt: V+B+N, V+B+N+E und alle fünf Prüfungsteile. Die gewählten Teile bestimmen, welche Teile in die Prüfungssimulation aufgenommen werden.
Der Termin wird nur angezeigt, etwa als Countdown in der Statuszeile. Er ändert nicht, welche Fragen gestellt werden – dafür gibt es keine belastbare Grundlage, und eine scheinbar kluge Berechnung wäre schlimmer als gar keine. Über Datei ▸ Einrichtungsassistent lässt sich die Auswahl jederzeit ändern.
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
QT_QPA_PLATFORM=offscreen ctest --test-dir build
Zum Ausprobieren ohne Installation genügt
cmake --install build; das Programm findet seine Kataloge danach von selbst.
Wird kein Katalog angegeben, lädt es den zuletzt benutzten oder den ersten
gefundenen.
| Ziel | Ergebnis |
|---|---|
| Windows | eine .exe (NSIS, mitgelieferte Qt-Laufzeit) |
| macOS | .dmg mit der App zum Ziehen nach „Programme“ |
| Debian, Ubuntu und Verwandte | .deb |
| Fedora, RHEL, CentOS Stream | .rpm |
| openSUSE, SuSE | .rpm läuft meist, ist dort aber nicht offiziell unterstützt |
| Arch Linux | kein Binärpaket – siehe unten |
| alles andere | .deb/.rpm als Ausgangspunkt, sonst ein noch nicht fertiges AppImage |
Gebaut wird mit CPack, die Paketabhängigkeiten werden dabei aus den wirklich
benutzten Bibliotheken ermittelt. Einzelheiten, auch zu den Grenzen je
Distribution, stehen in packaging/README.md.
Arch lässt sich hier nicht fertig ausliefern, und das ist keine
Nachlässigkeit, sondern so vorgesehen. Arch installiert ausschließlich aus
dem AUR, und ein AUR-Eintrag ist eine PKGBUILD, die aus dem Quelltext baut –
kein fertiges Binary. Jemand, der Arch unterstützen will, muss dafür ein
AUR-Konto haben und den Eintrag fortlaufend pflegen; das kann dieses Projekt
nicht übernehmen.
Geliefert wird alles Übrige: packaging/PKGBUILD ist
fertig, das Quellarchiv muss als Release mit Prüfsumme bereitstehen. Wer Arch
ohne AUR bedienen möchte, baut selbst:
git clone https://aur.archlinux.org/hamradiotrainer-2026.git
cd hamradiotrainer-2026
makepkg -si
.deb oder .rpm
(Void, Gentoo, Solus, Slackware) ist nicht eingerichtet. Es braucht ein
zusätzliches Werkzeug (appimagetool oder linuxdeployqt) beim Bauen und
liefert ohne Installation lauffähige Dateien auf jedem x86-64-Linux..etq, verschlüsselt.