Repository navigation
project_database DE
QElectroTech baut fΓΌr jedes geΓΆffnete Projekt eine SQLite-Datenbank auf. Es lohnt sich, genau zu sagen, was diese Datenbank ist, denn ihr Name legt eine Annahme nahe, die nicht zutrifft:
Die Projektdatenbank ist ein abgeleiteter Cache im Arbeitsspeicher. Sie wird bei jedem Γffnen des Projekts aus dem
.qet-XML neu aufgebaut und nie in die Projektdatei zurΓΌckgeschrieben. Allein das XML ist dauerhaft.
Alles Weitere auf dieser Seite folgt aus diesem einen Satz.
Quelle: sources/dataBase/projectdatabase.{h,cpp}.
βListe alle Bauteile dieses Projekts mit Herstellerreferenzen, nach Folio
gruppiertβ aus einer Grafikszene zu beantworten, heiΓt Tausende von
QGraphicsItem zu durchlaufen und Zeichenketten zu vergleichen. Aus einer
Tabelle beantwortet, ist es ein SELECT.
QET hΓ€lt dieselbe Information deshalb in einer zweiten Form vor, die fΓΌr Abfragen taugt, und nutzt sie fΓΌr das, was von Natur aus eine Abfrage ist:
| Nutzer | Was gelesen wird |
|---|---|
| StΓΌcklistentabellen auf einem Folio |
element_nomenclature_view, ΓΌber ProjectDBModel
|
| Der Abfrage-Assistent der StΓΌckliste | jede der Sichten, zusammengesetzt in ElementQueryWidget
|
| Dialog der Verdrahtungsliste | wiring_list_view |
--export-bom (Kommandozeile) |
element_nomenclature_view |
--export-wires, --export-cables
|
wiring_list_view |
| Folio-Γbersichtstabellen | project_summary_view |
Nichts davon ist Speicherung. Jedes davon ist ein Bericht ΓΌber Daten, die im XML bereits vorliegen.
QETProject erzeugt
βββ projectDataBase erzeugt β createDataBase()
βββ ΓΆffnet eine namenlose SQLite-Verbindung
βββ CREATE TABLE Γ 6, CREATE VIEW Γ 3
βββ updateDB()
Projekt-XML gelesen
βββ updateDB() β vollstΓ€ndiger Neuaufbau, einmal, nach allem Laden
Benutzer bearbeitet das Folio
βββ addElement / removeElement / elementInfoChanged
addDiagram / removeDiagram / diagramInfoChanged / diagramOrderChanged
addConductor/ removeConductor / updateConductor β inkrementell
Projekt geschlossen
βββ Datenbank verworfen
QSqlDatabase::addDatabase("QSQLITE", β¦) wird ohne setDatabaseName()
aufgerufen; es gibt also keine Datei auf der Platte, auf die die Verbindung
zeigen kΓΆnnte. WΓ€hrend des Ladens sind die Signale der Datenbank blockiert, und
am Ende lΓ€uft ein einziges updateDB() statt eines EinfΓΌgevorgangs je Objekt
wΓ€hrend des Szenenaufbaus.
Direkt nach dem Γffnen werden drei PRAGMAs gesetzt β temp_store = MEMORY,
journal_mode = MEMORY, synchronous = OFF. FΓΌr eine Datenbank, an der einem
liegt, wΓ€ren diese Einstellungen leichtsinnig. Hier sind sie genau deshalb
richtig, weil ein Totalverlust nichts kostet: Beim nΓ€chsten Γffnen wird ohnehin
neu aufgebaut.
QETProject::readProjectXml() protokolliert die Dauer jeder Ladephase, den
Datenbankaufbau eingeschlossen. Die Kosten fΓΌr ein bestimmtes Projekt lassen
sich also direkt der Konsolenausgabe entnehmen, statt geschΓ€tzt zu werden.
Sechs Tabellen:
| Tabelle | SchlΓΌssel | Anmerkungen |
|---|---|---|
diagram |
uuid |
dazu pos, die Folio-Reihenfolge |
element |
uuid |
diagram_uuid, pos, type, sub_type
|
diagram_info |
diagram_uuid |
je eine Spalte pro QETInformation::diagramInfoKeys() β heute 9 |
element_info |
element_uuid |
je eine Spalte pro QETInformation::elementInfoKeys() β heute 57 |
terminal |
(uuid, element_uuid) |
siehe Β§4 |
conductor |
uuid |
beide Enden als Paare (Klemmen-uuid, Element-uuid) |
Drei Sichten: element_nomenclature_view, project_summary_view,
wiring_list_view.
Man beachte, was diese Spaltenlisten bedeuten: das Schema wird zur Laufzeit
aus elementInfoKeys() erzeugt. Ein neues Elementinformationsfeld fΓΌgt
automatisch eine Spalte hinzu, ohne Migration und ohne Schemaversion β denn es
gibt keine bestehende Datenbank zu migrieren. Das ist die praktisch wichtigste
Folge daraus, dass der Cache abgeleitet ist.
element enthΓ€lt alle Elementtypen, Slaves und Folioverweise
eingeschlossen. Die EinschrΓ€nkung auf βwas eine StΓΌckliste nennen sollteβ
(type IN ('simple','terminal','master','thumbnail')) geschieht innerhalb von
element_nomenclature_view.
Das war nicht immer so, und der Grund fΓΌr die Γnderung ist lehrreich: Lag der Filter in der Tabelle, fehlte ein Slave-Element (ein Relaiskontakt) in der Datenbank vollstΓ€ndig β jeder andere Leser der Tabelle, etwa die Verdrahtungsliste, verlor damit stillschweigend jeden Leiter, der an einem Relaiskontakt endete. Die Ansicht einer StΓΌckliste darΓΌber, was eine Position ist, gehΓΆrt nicht in das Modell, das ein Projekt von sich selbst hat.
Zeilen brauchen stabile SchlΓΌssel. Elemente und Folios haben echte UUIDs, also kein Problem. Klemmen nicht.
Terminal::uuid() stammt aus der Katalogdefinition .elmt. Es bezeichnet eine
Klemmenposition in einem Symbol β βdie obere Klemme eines SchΓΌtzesβ β und ist
daher fΓΌr jede platzierte Instanz dieses Symbols identisch. Zudem ist es bei
jedem Element leer, das vor EinfΓΌhrung dieses Feldes erstellt wurde, also beim
grΓΆΓten Teil der installierten Sammlung.
Zwei Konsequenzen, beide behandelt:
- Eine Klemmeninstanz ist nur als Paar (
uuid,element_uuid) eindeutig. Deshalb ist dieses Paar β und nichtuuidallein β der PrimΓ€rschlΓΌssel der Klemmentabelle und das Ziel der FremdschlΓΌssel der Leitertabelle. -
Terminal::stableUuid()liefert eine IdentitΓ€t, wenn die Definition keine vorgibt: als UUID v5, abgeleitet aus lokaler Position und Ausrichtung der Klemme innerhalb ihres Elements β derselben Grundlage, die das Projektformat ohnehin schon nutzt, um einen Leiter einer Klemme zuzuordnen. Namen bleiben bewusst auΓen vor, denn QET schreibt eine Klemme namens_als unbenannt zurΓΌck, wodurch sich die IdentitΓ€t beim ersten erneuten Speichern Γ€ndern wΓΌrde.
projectDataBase::excludedConductorCount() meldet, wie viele Leiter ΓΌberhaupt
nicht indizierbar waren β gezΓ€hlt aus der lebenden Szene, nicht aus der
Datenbank, βgenau deshalb, weil die Datenbank der Ort ist, an dem diese Leiter
nicht sindβ. Das erlaubt einer Verdrahtungsliste zu sagen βN DrΓ€hte fehlen,
und zwar aus diesem Grundβ, statt eine unvollstΓ€ndige Liste als vollstΓ€ndig
auszugeben.
Das ist die Randbedingung, die man bei jeder kΓΌnftigen Persistenzarbeit im Blick behalten muss. Solange die Datenbank abgeleitet ist, kostet eine aus der Geometrie erratene KlemmenidentitΓ€t einen Cache-Fehlschlag. Als Dateiformat wird aus derselben SchΓ€tzung eine endgΓΌltige, einmalige Migration der Projekte aller Anwender.
| Weil sie abgeleitet istβ¦ | β¦gilt dies |
|---|---|
| Bei jedem Γffnen neu aufgebaut | Keine Schemaversion, keine Migrationen, nie |
Nie ins .qet geschrieben |
Eine falsche Zeile kostet nichts β neu ΓΆffnen, und sie ist weg |
| Das XML ist maΓgeblich | Die Datenbank kann der Zeichnung nicht widersprechen; tut sie es doch, irrt die Datenbank |
| Beim SchlieΓen verworfen |
synchronous = OFF und Verwandtes sind unbedenklich |
| Lebt in einem Prozess | Sie ist weder geteilt noch nebenlΓ€ufig noch mehrbenutzerfΓ€hig |
Und die Kehrseite, ebenso wahr:
| Weil sie abgeleitet istβ¦ | β¦gilt auch dies |
|---|---|
| Nichts ΓΌberlebt das SchlieΓen | Alles, was nur die Datenbank weiΓ, geht verloren |
| Beim Γffnen vollstΓ€ndig neu aufgebaut | Die Γffnungskosten wachsen mit der ProjektgrΓΆΓe |
| Nicht in der Datei enthalten | Zwei Personen kΓΆnnen nicht dieselbe Projektdatenbank abfragen |
Mit QET_EXPORT_PROJECT_DB ΓΌbersetzte Programme haben einen MenΓΌeintrag,
Interne Projektdatenbank exportieren, der die lebende Datenbank ΓΌber die
Backup-API von SQLite in eine .sqlite-Datei kopiert. Die CMake-Option steht
standardmΓ€Γig auf OFF, doch die offiziellen Pakete fΓΌr Windows, macOS,
Flatpak und Snap schalten sie alle ein β in einer verΓΆffentlichten Version
ist der Eintrag also normalerweise vorhanden.
Die exportierte Datei ist eine Momentaufnahme zur Einsicht. Sie zu bearbeiten Γ€ndert nichts: Niemand liest sie je zurΓΌck.
sqlite3 meinprojekt.sqlite ".schema"
sqlite3 meinprojekt.sqlite "SELECT label, designation FROM element_nomenclature_view LIMIT 20;"Sie ist nicht die Projektdatei, keine gemeinsame Datenbank, mit der sich ein Team verbindet, und nicht die Architektur aus Bauteildatenbank plus Zeichnungsansicht, wie sie Werkzeuge wie EPLAN haben. Ein Projekt bleibt eine einzige XML-Datei; die Datenbank ist ein Abfrageindex darΓΌber, der lebt, solange das Fenster offen ist.
Ob das so bleiben soll, ist eine offene Frage β siehe die Seiten Vision und Entwicklungs-Roadmap. Jeder Schritt hin zu Persistenz ist eine Γnderung des Dateiformats, und das Problem der KlemmenidentitΓ€t aus Β§4 ist deren erste echte HΓΌrde.
Bis eine solche Entscheidung fΓ€llt, lohnt beim HinzufΓΌgen von Funktionen eine Faustregel: Erzeugen Sie keinen Zustand, den nur das XML kennt, und keinen, den nur die Datenbank kennt. Ersteres macht den Cache unvollstΓ€ndig; Letzteres ΓΌberlebt kein SchlieΓen.
Getting Started
π Languages β English Β· FranΓ§ais Β· Deutsch
Windows without admin rights β the portable archive, no installer
Guides
Conductors β wire properties, what feeds which export, cables, and hops where wires cross
Wires per terminal β limit the wires on a terminal, chain wiring instead of stars
Printing and exporting β paper, PDF, images, and what each path does differently
Linking elements β master, slave, terminal
PLC modules β I/O tables and linking a wire to a specific point
Using the element editor β drawing tools, saving, checks
Generic devices β a quick box symbol with terminals on any side, made by a wizard (pending)
Grid size and element size β why symbols aren't all the same scale, and scaling one without leaving the grid
Preferences reference β what each settings page does
Saving and loading settings β your whole setup in one file, to copy or keep
Keyboard-only control β mouseless QET, and what still needs a mouse
Mouse modifiers β what Shift, Ctrl and Alt change while you drag
3D mouse β SpaceMouse pan, zoom and buttons
Aligning items β snap symbols back to the grid, or line them up
Pictures on a sheet β labels, crop, transparency, what they cost in the file
Arcs and curved wires β the Arc tool, pulling an arc in or out, rounding a corner with a fillet, dashed arcs for lighting layouts
Grouping items β select, move and copy several items as one
Finding your place on a sheet β go to a cell like B13 or 4-B7, keep the headers in sight, show the cell limits, zoom and pan
Showing and hiding kinds of items β hide texts, wire numbers, shapes, pictures, tables or cross-references on every sheet
Drawing faster β place without dragging, the S shortcut bar, command search, gestures
Customising QElectroTech β keys, toolbar size and contents, the gesture ring (partly pending)
Managing collections β folders, writability, building your own shortlist
Templates β reusable multi-element blocks, placed by double-click or drag
Search & Replace β bulk property changes
Building a nomenclature query β the BOM/summary table builder
Linking wires across pages β sheet reports
Variables & formulas β %f, %{label}, sequences
Auto-numbering β schemes, sequences, freezing
Terminal strips β strips, levels, bridges
Title block templates β the .titleblock format
Importing EPLAN parts (.edz) β EPLAN Data Portal
DXF import & export β two unrelated features, one format; command-line export and layers
The project database β the in-memory SQLite cache
Development
Automating QET β CLI, XML formats, external tools
CLI Reference β command line usage
JavaScript Scripting β --run, geometry editing, undo
MCP server β let an AI assistant read, verify and edit projects
Connecting an AI assistant β setup for Claude, Copilot, Gemini, Codex, Cursor, LM Studio
Script buttons β stored scripts with an icon, by hand or by an assistant
Live mode β an assistant working in the open project while you watch
Macro recorder β record a task by hand, for an assistant to script
Vision β proposal, under discussion
