From 96da2ee56610da61c1f5415466303bb5f0868d1e Mon Sep 17 00:00:00 2001 From: daniel Date: Mon, 23 Mar 2026 14:25:14 +0100 Subject: [PATCH] =?UTF-8?q?Kartenschildbox=20und=20Linien=20hinzugef=C3=BC?= =?UTF-8?q?gt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/layout.py | 184 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 153 insertions(+), 31 deletions(-) diff --git a/ui/layout.py b/ui/layout.py index f82192c..f688abf 100644 --- a/ui/layout.py +++ b/ui/layout.py @@ -4,6 +4,7 @@ sn_plan41/ui/layout.py – Aufbau von Drucklayouts für Plan41. from __future__ import annotations import math +import importlib from typing import Any from sn_basis.functions.qt_wrapper import QFont @@ -47,19 +48,23 @@ class Layout: _OBJECT_TEMPLATES = { "hauptkarte": { "id": "Hauptkarte", + "object_name": "Hauptkarte", }, "quellenangabe": { "id": "Quellenangabe", + "object_name": "Quellenangabe", "size_mm": (180.0, 100.0), "format": "Format_1", }, "seitenzahl": { "id": "Seitenzahl", + "object_name": "Seitenzahl", "size_mm": (60.0, 8.0), "format": "Format_1", }, "textfeld": { "id": "Textfeld", + "object_name": "Textfeld", "size_mm": (60.0, 8.0), "format": "Format_1", "html_mode": True, @@ -92,15 +97,54 @@ class Layout: y_mm: float, width_mm: float, height_mm: float, + object_name: str | None = None, ) -> Any: template = self._OBJECT_TEMPLATES[template_name] map_item = QgsLayoutItemMap(layout) map_item.setId(template["id"]) + set_object_name = getattr(map_item, "setObjectName", None) + if callable(set_object_name): + set_object_name(object_name or template.get("object_name", template["id"])) layout.addLayoutItem(map_item) map_item.attemptMove(QgsLayoutPoint(x_mm, y_mm, MM)) map_item.attemptResize(QgsLayoutSize(width_mm, height_mm, MM)) return map_item + def _set_item_frame_stroke_width(self, item: Any, stroke_width_mm: float) -> None: + set_frame_stroke_width = getattr(item, "setFrameStrokeWidth", None) + if not callable(set_frame_stroke_width): + return + + try: + set_frame_stroke_width(stroke_width_mm) + return + except Exception: + pass + + try: + qgis_core = importlib.import_module("qgis.core") + QgsLayoutMeasurement = getattr(qgis_core, "QgsLayoutMeasurement", None) + except Exception: + QgsLayoutMeasurement = None + + if QgsLayoutMeasurement is not None: + try: + set_frame_stroke_width(QgsLayoutMeasurement(stroke_width_mm, MM)) + return + except Exception: + pass + + frame_stroke_width = getattr(item, "frameStrokeWidth", None) + if callable(frame_stroke_width): + try: + measurement = frame_stroke_width() + set_length = getattr(measurement, "setLength", None) + if callable(set_length): + set_length(stroke_width_mm) + set_frame_stroke_width(measurement) + except Exception: + pass + def add_text_label( self, text: str, @@ -112,6 +156,7 @@ class Layout: height_mm: float | None = None, html_mode: bool = False, expression_enabled: bool = False, + object_name: str | None = None, ) -> Any: """Einfache öffentliche Methode zum Hinzufügen eines Text-Labels. @@ -130,13 +175,14 @@ class Layout: height_mm=height_mm, html_mode=html_mode, expression_enabled=expression_enabled, + object_name=object_name, ) def _setup_layout_objects(self, kartenfenster_untere_rechte_ecke_mm: tuple, is_atlas: bool = False) -> None: """Zentrale Methode zum Hinzufügen aller Standard-Objekte ins Layout. Diese Methode wird sowohl von create_single_page_layout() als auch von create_atlas_layout() aufgerufen. - + Relatipunkt des Objekts ist die untere linke Ecke, berechnet von der unteren, rechten Ecke des Kartefensters Args: kartenfenster_untere_rechte_ecke_mm: Tupel (x_mm, y_mm) der unteren rechten Kartenecke is_atlas: True für Atlas-Layout, False für Einzelblatt-Layout @@ -166,7 +212,61 @@ class Layout: html_mode=True, ) print("[Layout] Quellenangabe zum Layout hinzugefügt") + # Kartenschild-Box, -Linien und -Text werden hier ergänzt (TODO) + #Kartenschild-Box + kartenschild_x = kartenfenster_untere_rechte_ecke_mm[0] + 10.0 + kartenschild_y = kartenfenster_untere_rechte_ecke_mm[1] + self._create_rectangle_box_item( + self._current_layout, + "Kartenschild", + kartenschild_x, + kartenschild_y, + 180.0, + 92.0, + stroke_width_mm= 1.0, + ) + print("[Layout] Kartenschild-Box zum Layout hinzugefügt") + #Kartenschild-Linien + kartenschild_line_x = kartenfenster_untere_rechte_ecke_mm[0] + 10.0 + kartenschild_line_offsets_y = (-10.0, -20.0, -30.0, -46.0, -62.0, -82.0) + for index, offset_y in enumerate(kartenschild_line_offsets_y, start=1): + self._create_rectangle_box_item( + self._current_layout, + f"Kartenschild_Linie_{index}", + kartenschild_line_x, + kartenfenster_untere_rechte_ecke_mm[1] + offset_y, + 180.0, + 0.0, + stroke_width_mm=0.1, + ) + print("[Layout] 6 Kartenschild-Linien zum Layout hinzugefügt") + + #Kartenschild-Text + #Herausgeber + self.add_text_label("@Amt", 10.0, -92.0, text_format="Format_1", object_name="Herausgeber") + #Bezeichnung_Flurbereinigung + + #Name Flurbereinigung + + #Stadt_Gemeinde + + #Landkreis + + #Kartenname + + #Ergänzung(Seitenzahl) + + #gefertigt + + #geprüft + + #Maßstab + + #Ausgabedatum + + #Aktenzeichen + # Seitenzahl nur bei Atlas-Layout if is_atlas: seitenzahl_x = kartenfenster_untere_rechte_ecke_mm[0] + 5.0 @@ -197,10 +297,14 @@ class Layout: height_mm: float | None = None, html_mode: bool = False, expression_enabled: bool = False, + object_name: str | None = None, ) -> Any: template = self._OBJECT_TEMPLATES[template_name] label = QgsLayoutItemLabel(layout) label.setId(template["id"]) + set_object_name = getattr(label, "setObjectName", None) + if callable(set_object_name): + set_object_name(object_name or template.get("object_name", template["id"])) label.setText(text) if html_mode: @@ -245,6 +349,52 @@ class Layout: layout.addLayoutItem(label) return label + def _create_rectangle_box_item( + self, + layout: Any, + object_name: str, + x_mm: float, + y_mm: float, + width_mm: float, + height_mm: float, + stroke_width_mm: float = 0.3, + ) -> Any: + box = QgsLayoutItemLabel(layout) + box.setId(object_name) + + set_object_name = getattr(box, "setObjectName", None) + if callable(set_object_name): + set_object_name(object_name) + + box.setText("") + + set_reference_point = getattr(box, "setReferencePoint", None) + lower_left = getattr(getattr(QgsLayoutItem, "ReferencePoint", object), "LowerLeft", None) + if callable(set_reference_point) and lower_left is not None: + set_reference_point(lower_left) + + box.attemptMove(QgsLayoutPoint(x_mm, y_mm, MM)) + box.attemptResize(QgsLayoutSize(width_mm, height_mm, MM)) + + set_frame_enabled = getattr(box, "setFrameEnabled", None) + if callable(set_frame_enabled): + try: + set_frame_enabled(True) + except Exception: + pass + + self._set_item_frame_stroke_width(box, stroke_width_mm) + + set_background_enabled = getattr(box, "setBackgroundEnabled", None) + if callable(set_background_enabled): + try: + set_background_enabled(False) + except Exception: + pass + + layout.addLayoutItem(box) + return box + def create_single_page_layout( self, name: str, @@ -335,7 +485,7 @@ class Layout: set_frame_stroke_width = getattr(hauptkarte, "setFrameStrokeWidth", None) if callable(set_frame_stroke_width): try: - set_frame_stroke_width(0.5) + self._set_item_frame_stroke_width(hauptkarte, 0.5) print(f"[Layout] Rahmenstrichbreite auf 0.5 mm gesetzt") except Exception as exc: print(f"[Layout] WARN: setFrameStrokeWidth(0.5) fehlgeschlagen: {exc}") @@ -383,34 +533,6 @@ class Layout: self._setup_layout_objects(kartenfenster_untere_rechte_ecke_mm, is_atlas=False) - #Kartenschild-Box - - #Kartenschild-Linien - - #Kartenschild-Text - #Herausgeber - - #Bezeichnung_Flurbereinigung - - #Name Flurbereinigung - - #Stadt_Gemeinde - - #Landkreis - - #Kartenname - - #Ergänzung(Seitenzahl) - - #gefertigt - - #geprüft - - #Maßstab - - #Ausgabedatum - - #Aktenzeichen layout_manager.addLayout(layout) print("[Layout] Layout zum LayoutManager hinzugefügt") self._current_layout = None @@ -531,7 +653,7 @@ class Layout: set_frame_stroke_width = getattr(hauptkarte, "setFrameStrokeWidth", None) if callable(set_frame_stroke_width): try: - set_frame_stroke_width(0.5) + self._set_item_frame_stroke_width(hauptkarte, 0.5) except Exception: pass