Aligning items, grouping items, DXF command line and layers (PRs #1073, #1074, #1078, #1079, pending)

New pages aligning_items (snap to grid) and grouping_items; dxf gains
--export-dxf and the layer table with a rendered example; cli_reference
and scripting list --export-dxf / exportDxf(). Each section carries a
pending notice naming its PR. Sidebar and see-also links added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ispyisail
2026-09-27 22:31:59 +13:00
parent c0e059ce77
commit 2a946a4b21
10 changed files with 347 additions and 10 deletions
+7 -3
@@ -34,13 +34,17 @@
**[Preferences reference](preferences)** — what each settings page does
**[Keyboard-only control](keyboard_control)** — mouseless QET, and the one real gap
**[Keyboard-only control](keyboard_control)** — mouseless QET, and what still needs a mouse
**[Mouse modifiers](mouse_modifiers)** — what Shift, Ctrl and Alt change while you drag
**[Aligning items](aligning_items)** — snap symbols back to the grid *(pending)*
**[Grouping items](grouping_items)** — select, move and copy several items as one *(pending)*
**[Finding your place on a folio](navigating_folios)** — go to a cell like B13 or 4-B7, keep the headers in sight, show the cell limits
**[Drawing faster](drawing_faster)** — place without dragging, the S shortcut bar, command search, gestures *(mostly pending)*
**[Drawing faster](drawing_faster)** — place without dragging, the S shortcut bar, command search, gestures
**[Managing collections](collection_browser)** — folders, writability, building your own shortlist
@@ -62,7 +66,7 @@
**[Importing EPLAN parts (.edz)](edz_import)** — EPLAN Data Portal
**[DXF import & export](dxf)** — two unrelated features, one format
**[DXF import & export](dxf)** — two unrelated features, one format; command-line export and layers *(pending)*
**[The project database](project_database)** — the in-memory SQLite cache
+102
@@ -0,0 +1,102 @@
# Aligning items: putting symbols back on the grid
Wires in QElectroTech run straight when the terminals at both ends line up,
and terminals line up when their symbols sit on the grid. A symbol that is
even a few pixels off the grid gives a bent or stepped wire.
Symbols leave the grid more easily than you might think:
- **Alt+arrow** moves a selection by 1 pixel (see
**[Mouse modifiers](mouse_modifiers)**, §6), so a few presses leave it
between grid points.
- **Ctrl while dragging** places freely, ignoring the grid.
- Projects made with older versions, or with a different grid setting, may
already contain symbols off the grid.
In the example projects that ship with QElectroTech, 508 of 3,678 placed
symbols (14 %) are off the grid.
Until now nothing put them back: you had to drag each symbol by eye until it
happened to land on a grid point. This page covers the commands that do it for
you. They were proposed in
[discussion #1069](https://github.com/qelectrotech/qelectrotech-source-mirror/discussions/1069)
and are built one pull request at a time.
Menu names are given in French, as QElectroTech shows them until the
translations are updated, with an English gloss in italics.
| Command | What it does | Pull request |
|---|---|---|
| [Snap to grid](#snap-to-grid) | puts the selected items back on the grid | [#1073](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1073) |
| Align, distribute, straighten wires | line symbols up, space them evenly, straighten the wires between them | planned in discussion #1069, not built yet |
---
## Snap to grid
> **Status: pending.** This section describes
> [PR #1073](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1073),
> not yet merged. Nothing here works until that lands — check the PR before
> trying any of this against your own build. This section will drop this
> notice once it does.
### Using it
1. Select the items to fix. **Ctrl+A** selects everything on the folio,
which is the quickest way to tidy a whole page.
2. Choose **Édition ▸ Aligner ▸ Aligner sur la grille** (*Edit ▸ Align ▸
Snap to grid*). The same command is in the right-click menu of the
selection, and in command search (**Ctrl+Shift+M**, type "grille").
Each selected item moves to the nearest grid point, and the status bar says
what happened:
| Status bar | Meaning |
|---|---|
| *3 objet(s) remis sur la grille* | 3 items were off the grid and have been moved |
| *La sélection est déjà sur la grille* | nothing needed moving; no undo step is added |
| *(1 objet(s) verrouillé(s) laissé(s) en place)* | added when locked items were in the selection; they were not moved |
**One undo step** (Ctrl+Z) puts every item back where it was.
### Which items move, and to which grid
| Item | Snaps to |
|---|---|
| Symbols | the folio grid, by the symbol's origin point: exactly where dragging it would have dropped it |
| Pictures | the folio grid |
| Free texts | the text grid, the finer step set under **Affichage ▸ Grille des textes** (*View ▸ Text grid*), so a text you placed on a finer step is not pulled onto the coarser folio grid |
| Shapes (lines, rectangles, polygons) | not moved: a shape is several points, and no single one is the obvious one to snap |
| Locked items | not moved |
| Wires | follow their symbols, as they do when you drag |
Items already on the grid stay exactly where they are.
### Things worth knowing
- **Half a step rounds up.** A symbol exactly half a grid step off (5 px on
the default 10 px grid) goes to the next grid point, so "back on the grid"
is not always "back where it was before the nudge".
- **Holding Ctrl makes no difference.** Unlike dragging, where Ctrl means
"ignore the grid", this command always snaps to the grid, so it still works
if you give it a shortcut that includes Ctrl.
- **No default shortcut.** You can assign one under **Configurer
QElectroTech ▸ Raccourcis** (*Settings ▸ Shortcuts*); the command is listed
in the *Éditeur de schémas* group.
- **The grid is the folio's own grid.** If you changed the grid size in the
preferences, symbols snap to that size.
- **A symbol whose terminals are off the grid inside the symbol itself**
still gives bent wires after snapping. That is a problem in the symbol, not
its position; fix it in the **[element editor](element_editor)**.
---
## See also
- **[Grid size and element size](grid_and_element_size)** — the folio grid,
and why symbols are drawn to it
- **[Mouse modifiers](mouse_modifiers)** — what Ctrl, Shift and Alt change
while you drag or nudge
- **[Grouping items](grouping_items)** — moving several items as one
- **[Drawing faster](drawing_faster)** — command search and other commands at
the cursor
+4 -2
@@ -186,6 +186,7 @@ Arguments are **positional**, not `--flag=value`. The shape is always
|---|---|
| `--export-pdf` | one PDF, all folios |
| `--export-png` / `--export-svg` | a directory, one image per folio |
| `--export-dxf` | a directory, one DXF per folio — *pending, [PR #1078](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1078)*; see **[DXF import & export](dxf)** |
| `--export-bom` | CSV bill of materials |
| `--export-wiring` | CSV from-to wiring list |
| `--export-cables` | CSV wiring list, built from the document XML |
@@ -198,7 +199,8 @@ Arguments are **positional**, not `--flag=value`. The shape is always
| `--check-elements` | validates `.elmt` files or a directory of them |
| `--run` | run a JavaScript macro against a project — see **[JavaScript Scripting](scripting)** |
Plus `--show-terminals`, which paints terminal markers into PDF/PNG/SVG output.
Plus `--show-terminals`, which paints terminal markers into PDF/PNG/SVG output
(and DXF, with PR #1078).
Exit codes: `0` success, `1` the work failed, `2` called wrongly — so these are
safe to chain in a script with `set -e`.
@@ -469,7 +471,7 @@ wait # Wait for all to finish
|-----------|-----------|
| No CLI option to create or edit a diagram *from a flag* | Use JavaScript scripting (`--run`) for edits with real undo, or the `.qet` XML directly for anything scripting doesn't cover — see **[JavaScript Scripting](scripting)** and **[Automating QElectroTech](api_reference)** |
| One project per invocation | Loop in the shell; each run is independent |
| No DXF export from the CLI | Use GUI export (File → Export) |
| No DXF export from the CLI | Use GUI export (File → Export). `--export-dxf` is pending in [PR #1078](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1078) |
> **Corrected September 2026.** This section previously claimed QET had no
> headless export and no CLI PDF export, and pointed readers at Python
+101 -5
@@ -13,6 +13,7 @@ you're looking for "import a DXF drawing as a folio", that isn't what either
of these does — see §3.
Source: `sources/createdxf.{cpp,h}`, `sources/dxfpaintdevice.{cpp,h}`,
`sources/dxfexport.{cpp,h}` (with PR #1078),
`sources/dxf/dxftoelmt.{cpp,h}`.
---
@@ -22,8 +23,100 @@ Source: `sources/createdxf.{cpp,h}`, `sources/dxfpaintdevice.{cpp,h}`,
*File → Export*, same dialog as PDF/PNG/SVG, one `.dxf` file per folio. The
border, title block and every diagram item on that folio are included.
**There is no CLI verb for it.** `--export-pdf`, `--export-png` and
`--export-svg` exist; DXF export is GUI-only today.
In current builds DXF export is GUI-only: `--export-pdf`, `--export-png` and
`--export-svg` exist, but there is no DXF equivalent. The next section adds
one.
### From the command line: `--export-dxf`
> **Status: pending.** This section describes
> [PR #1078](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1078),
> not yet merged. Nothing here works until that lands — check the PR before
> trying any of this against your own build. This section will drop this
> notice once it does.
```bash
qelectrotech --export-dxf myproject.qet out/
qelectrotech --export-dxf myproject.qet out/ --show-terminals
```
- **One file per folio**, named like the PNG and SVG exports: the folio
number on two digits, then its title — `01_General.dxf`,
`02_Macro 3.dxf`. The output folder is created if it does not exist.
- **The same file the Export dialog writes**, with the dialog's default
options, which come from the export settings in the preferences (border,
title block and so on). Given the same settings, the two are
byte-identical. The column numbers across the top border follow the
preference that starts them at 0 or 1, so a machine with a different
setting gives a different border.
- **`--show-terminals`** draws the terminals, as the dialog's option does.
- **Pictures** become outline boxes, as in the dialog (see below), and a
note is printed saying so.
- **Scripts** run with `--run` get the same export as
`qet.exportDxf(outDir, showTerminals)` — see
**[JavaScript Scripting](scripting)**.
Exit codes are the same as the other exports: `0` success, `1` the export
failed (for example, the output folder cannot be written), `2` called wrongly.
**Two exports of the same folio give identical files**, so a DXF can be
compared with an earlier one to see what changed. That needs
[PR #1075](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1075),
which ships with this one: before it, every export wrote its entities in a
different order.
### Layers
> **Status: pending.** This section describes
> [PR #1079](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1079),
> not yet merged. Nothing here works until that lands — check the PR before
> trying any of this against your own build. This section will drop this
> notice once it does.
Until now everything in an exported DXF sat on **layer 0**, so a CAD program
could not tell the border from the wires. With this change each kind of
content goes on its own layer:
| Layer | What is on it |
|---|---|
| `QET_BORDER` | the folio frame, with its column and row headers |
| `QET_TITLEBLOCK` | the title block |
| `QET_SYMBOLS` | the drawing of each symbol |
| `QET_SYMBOL_TEXTS` | texts belonging to symbols: labels and the like |
| `QET_TERMINALS` | terminal markers, only when terminals are drawn (`--show-terminals` or the dialog option) |
| `QET_WIRES` | the wires |
| `QET_WIRE_NUMBERS` | the texts on wires |
| `QET_JUNCTIONS` | junction dots |
| `QET_TEXTS` | free texts |
| `QET_XREFS` | cross-references: contact tables beside a master, labels beside a slave |
| `QET_SHAPES` | lines, rectangles, ellipses and polygons drawn on the folio |
| `QET_TABLES` | tables such as the parts list |
| `QET_IMAGES` | the outline boxes that stand in for pictures |
The names are fixed and English, whatever language QElectroTech runs in, so
a CAD user's layer filters and scripts keep working. The `QET_` prefix keeps
them together in the layer list and apart from the receiving drawing's own
layers.
![Left: a folio as exported. Middle: the same file with the border, title block and tables layers switched off. Right: the wires layer recoloured red and the symbols layer blue](https://raw.githubusercontent.com/wiki/qelectrotech/qelectrotech-source-mirror/images/dxf-layers.png)
*`2612_ats_singlephase.qet`, folio 1, exported with this change and rendered
with ezdxf. Only layer settings in the viewer differ between the three.*
**Colours.** Where QElectroTech sets no colour of its own, entities take
their layer's colour (*BYLAYER*), so recolouring a layer in the CAD program
recolours everything on it. The file still looks the same when opened, since
every layer starts white on black, black on white. Wires keep the colour they
have on the folio: until this change every wire was exported in the default
colour, and 723 of the 3,190 wires in the example projects lost theirs. A
two-colour wire gets its main colour.
**What does not change:** the lines themselves, their positions and the DXF
version. Only the layer each entity is on and its colour code differ from an
older export.
Not included yet: an option to put everything back on layer 0, symbols as
DXF blocks, and dashed wires (they come out continuous).
### How it's rendered
@@ -100,11 +193,14 @@ project, not with QET.
- **Not round-trip safe.** Export's outline-only, no-image limitations (§1)
mean a `.dxf` written by QET is not a faithful source to import back,
even setting aside that import and export use entirely different code.
- **Not a general CAD interchange path**, in the sense of preserving layers,
blocks, or DXF metadata beyond raw geometry — both directions work at the
level of individual drawing primitives.
- **Not a general CAD interchange path**, in the sense of preserving blocks
or DXF metadata beyond raw geometry — both directions work at the level of
individual drawing primitives. Export puts content on named layers once
[PR #1079](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1079)
lands (§1, *Layers*).
---
See also: **[Automating QElectroTech](api_reference)** ·
**[CLI Reference](cli_reference)** ·
**[Linking elements](element_linking)**
+1
@@ -120,4 +120,5 @@ against neighbouring symbols and resize by hand if it needs to match.
- **[Preferences reference](preferences)** — where the grid settings live in the UI
- **[Using the element editor](element_editor)** — drawing tools, saving, checks
- **[Mouse modifiers](mouse_modifiers)** — Shift/Ctrl/Alt while dragging
- **[Aligning items](aligning_items)** — putting symbols that left the grid back on it *(pending)*
- **[Elements XML](elements_XML)** — the `<definition>` `width`/`height`/`hotspot` attributes
+124
@@ -0,0 +1,124 @@
# Grouping items on a folio
Some things on a folio belong together: a picture and its caption, a symbol
with a frame drawn round it, a block of symbols with the notes that explain
them. Without groups they have to be selected piece by piece every time they
move or are copied, and it is easy to leave one behind.
**Grouper** (*Group*) ties selected items together so that they select,
move, copy and delete as one. **Dégrouper** (*Ungroup*) undoes it. This was
asked for in [issue #349](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/349)
and on the forum ([#2467](https://qelectrotech.org/forum/viewtopic.php?id=2467),
[#356](https://qelectrotech.org/forum/viewtopic.php?id=356)), and proposed in
[discussion #1070](https://github.com/qelectrotech/qelectrotech-source-mirror/discussions/1070).
Menu names are given in French, as QElectroTech shows them until the
translations are updated, with an English gloss in italics.
> **Status: pending.** Everything on this page describes
> [PR #1074](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/1074),
> not yet merged. Nothing here works until that lands — check the PR before
> trying any of this against your own build. This page will drop this
> notice once it does.
---
## 1. Making a group
1. Select two or more items. Any mix of these can be grouped:
- symbols,
- free texts,
- shapes (lines, rectangles, ellipses, polygons),
- pictures.
2. Choose **Édition ▸ Grouper** (*Edit ▸ Group*). It is also in the
right-click menu of the selection, and in command search
(**Ctrl+Shift+M**, type "grouper").
**Grouper** is greyed out when the selection is fewer than two items, or is
already exactly one group.
**Wires are never part of a group.** They are drawn between symbols, so they
follow their symbols when the group moves, exactly as they do today.
## 2. Working with a group
| You do | What happens |
|---|---|
| Click any member | the whole group is selected |
| Drag a member | the whole group moves |
| Arrow keys, with the group selected | the whole group moves |
| Draw a selection rectangle that touches part of a group | the whole group is selected when you release the mouse |
| **Ctrl**+click a member of a selected group | the whole group leaves the selection, as a single item would |
| **Ctrl**+click a member of an unselected group | the whole group joins the selection |
| Copy, cut, **Delete** | act on the whole group |
| **Shift+Space**, **Pivoter le groupe** (*rotate as group*) | the whole group turns 90° round its centre, keeping its layout |
| **Space**, **Pivoter** (*rotate*) | each member turns where it stands, as for any selection |
| Paste | the copy is a new group of its own, separate from the original |
| Duplicate a folio | each group on it becomes a new group on the copy |
Clicking a member of a group that is already selected keeps the whole group
selected.
**Grouping groups merges them.** Select a group and another item (or
another group) and choose **Grouper**: the result is one group holding all of
them. There are no groups inside groups.
## 3. Ungrouping
Select a group, or any member of it, and choose **Édition ▸ Dégrouper**
(*Edit ▸ Ungroup*), also in the right-click menu and command search. Every
member becomes a separate item again, and nothing moves.
Both commands are undoable. Undoing **Dégrouper** restores exactly the groups
there were before, not new ones.
Neither command has a default shortcut (**Ctrl+G** is already *go to
element*). You can assign one under **Configurer QElectroTech ▸ Raccourcis**
(*Settings ▸ Shortcuts*), in the *Éditeur de schémas* group.
## 4. In the project file
Each grouped item carries one extra attribute, `group`, holding the group's
id; members of the same group share the id. Nothing else in the file
changes:
- A project **without** groups saves exactly as it did before, byte for byte.
- An **older version** of QElectroTech opens a project with groups, shows
every item, and simply ignores the grouping. If it saves the project, the
groups are lost.
Groups are also recorded in the project database (a `group_uuid` column on
the element, shape, free-text and picture tables), so a query or script can
find which items belong together. See
**[The project database](project_database)**.
## 5. Not included yet
Planned in [discussion #1070](https://github.com/qelectrotech/qelectrotech-source-mirror/discussions/1070),
not built:
- **Editing one member without ungrouping.** For now, ungroup, edit, and
group again.
- **Space rotating a group as a unit.** Today Space turns each member in
place; use **Shift+Space** (*Pivoter le groupe*) to turn the group as a
whole.
- **Nested groups.**
- **Locked items.** A locked member is not treated specially: it stays where
it is while the rest of its group moves.
- **Groups in the symbol editor** ([element editor](element_editor)).
**Grouper les textes sélectionnés** (*group the selected texts*), which
groups the texts of one symbol, is a different, older feature and is not
affected.
---
## See also
- **[Aligning items](aligning_items)** — putting symbols back on the grid
- **[Templates](templates)** — saving a set of items for reuse: select them
and use **Créer un template** in the right-click menu
- **[Mouse modifiers](mouse_modifiers)** — what Ctrl and Shift change while
you select and drag
- **[The project database](project_database)** — the tables a query or script
can read
BIN
Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

+6
@@ -119,6 +119,10 @@ With something selected and no text being edited:
Both grids are configurable in **[Preferences → General](preferences)**,
separately from the grid the mouse snaps to.
A few **Alt**+arrow presses leave a symbol between grid points, which bends
its wires. **[Aligning items](aligning_items)** describes the command that
puts it back *(pending, PR #1073)*.
---
## 7. View and navigation
@@ -175,4 +179,6 @@ rotating. It keeps its own grid settings, separate from the diagram's.
- **[Keyboard-only control](keyboard_control)** — driving QET without a mouse
- **[Preferences reference](preferences)** — the grid and movement settings
- **[Templates](templates)** — which are placed by dragging, and nothing else
- **[Aligning items](aligning_items)** — snap a selection back to the grid *(pending)*
- **[Grouping items](grouping_items)** — select and move several items as one *(pending)*
- **[Tips & Tricks](tips_and_tricks)** — faster drawing generally
+1
@@ -83,6 +83,7 @@ script instead of a flag:
qet.exportPdf(output, showTerminals = false)
qet.exportPng(outDir, showTerminals = false)
qet.exportSvg(outDir, showTerminals = false)
qet.exportDxf(outDir, showTerminals = false) // pending, PR #1078
qet.exportCables(output)
qet.exportWires(output)
qet.exportBom(output)
+1
@@ -191,5 +191,6 @@ path, or copy the `.qetmak` files into the default folder above.
- **[Using the element editor](element_editor)** — for building the single
symbols a template is assembled from
- **[Preferences reference](preferences)** — where the templates folder is set
- **[Grouping items](grouping_items)** — keeping items together on the folio, rather than saving them for reuse *(pending)*
- **[Tips & Tricks](tips_and_tricks)** — other ways to speed up repeated
drawing