Tabs der LNO-Docks in Scroll-Bereich packen (#104)

Ein langer Tab (Druck-Tab mit aufgeklapptem Basemap-Bereich) schob den
unteren Rand des QGIS-Fensters aus dem Bildschirm, weil Qt für das Dock
die Höhe des höchsten Tabs verlangt. BaseDockWidget.setWidget packt jetzt
jeden Tab eines QTabWidget in einen QScrollArea; das wirkt auch für
Fachplugins, die ihre Tabs selbst aufbauen. QScrollArea/QFrame im
qt_wrapper ergänzt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-05 21:53:50 +02:00
co-authored by Claude Opus 5.5
parent 1aadef73bd
commit 894b695ecf
4 changed files with 161 additions and 3 deletions
+42 -1
View File
@@ -56,6 +56,9 @@ QTableWidgetItem: Type[Any] = object
QTableWidgetSelectionRange: Type[Any] = object
QIcon: Type[Any] = object
QSize: Type[Any] = object
QScrollArea: Type[Any] = object
QFrame: Type[Any] = object
FrameNoFrame: Any = 0
def exec_dialog(dialog: Any) -> Any:
@@ -116,6 +119,8 @@ try:
QTableWidget as _QTableWidget,
QTableWidgetItem as _QTableWidgetItem,
QTableWidgetSelectionRange as _QTableWidgetSelectionRange,
QScrollArea as _QScrollArea,
QFrame as _QFrame,
)
from qgis.PyQt.QtGui import QFont as _QFont, QIcon as _QIcon
from qgis.PyQt.QtCore import (
@@ -176,6 +181,8 @@ try:
QTableWidget = _QTableWidget
QTableWidgetItem = _QTableWidgetItem
QTableWidgetSelectionRange = _QTableWidgetSelectionRange
QScrollArea = _QScrollArea
QFrame = _QFrame
QIcon = _QIcon
QSize = _QSize
# ✅ QT6 ENUMS
@@ -194,6 +201,7 @@ try:
SizePolicyPreferred = QSizePolicy.Policy.Preferred
SizePolicyMaximum = QSizePolicy.Policy.Maximum
DockWidgetMovable = QDockWidget.DockWidgetFeature.DockWidgetMovable
FrameNoFrame = QFrame.Shape.NoFrame
DockWidgetFloatable = QDockWidget.DockWidgetFeature.DockWidgetFloatable
DockWidgetClosable = QDockWidget.DockWidgetFeature.DockWidgetClosable
DockAreaLeft = Qt.DockWidgetArea.LeftDockWidgetArea
@@ -247,6 +255,8 @@ except (ImportError, AttributeError):
QTableWidget as _QTableWidget,
QTableWidgetItem as _QTableWidgetItem,
QTableWidgetSelectionRange as _QTableWidgetSelectionRange,
QScrollArea as _QScrollArea,
QFrame as _QFrame,
)
from PyQt5.QtGui import QFont as _QFont, QIcon as _QIcon
from PyQt5.QtCore import (
@@ -305,6 +315,8 @@ except (ImportError, AttributeError):
QTableWidget = _QTableWidget
QTableWidgetItem = _QTableWidgetItem
QTableWidgetSelectionRange = _QTableWidgetSelectionRange
QScrollArea = _QScrollArea
QFrame = _QFrame
QIcon = _QIcon
QSize = _QSize
@@ -325,6 +337,7 @@ except (ImportError, AttributeError):
SizePolicyPreferred = QSizePolicy.Preferred
SizePolicyMaximum = QSizePolicy.Maximum
DockWidgetMovable = QDockWidget.DockWidgetMovable
FrameNoFrame = QFrame.NoFrame
DockWidgetFloatable = QDockWidget.DockWidgetFloatable
DockWidgetClosable = QDockWidget.DockWidgetClosable
DockAreaLeft = Qt.LeftDockWidgetArea
@@ -492,9 +505,28 @@ except (ImportError, AttributeError):
def show(self) -> None: pass
def deleteLater(self) -> None: pass
def closeEvent(self, event) -> None: pass
def setWidget(self, widget) -> None: self._widget = widget
def widget(self): return getattr(self, "_widget", None)
def setFeatures(self, *args, **kwargs) -> None: pass
def setAllowedAreas(self, *args, **kwargs) -> None: pass
def setWindowTitle(self, title: str) -> None: self._title = title
QDockWidget = _MockQDockWidget
class _MockQScrollArea(_MockWidget):
def __init__(self, *args, **kwargs):
self._widget = None
self._resizable = False
def setWidget(self, widget) -> None: self._widget = widget
def widget(self): return self._widget
def setWidgetResizable(self, value: bool) -> None: self._resizable = bool(value)
def widgetResizable(self) -> bool: return self._resizable
def setFrameShape(self, *args, **kwargs) -> None: pass
QScrollArea = _MockQScrollArea
QFrame = _MockWidget
FrameNoFrame = 0
class _MockAction:
def __init__(self, *args, **kwargs):
self._checked = False
@@ -556,8 +588,17 @@ except (ImportError, AttributeError):
DockWidgetClosable = 4
class _MockTabWidget:
def __init__(self, *args, **kwargs): self._tabs = []
def __init__(self, *args, **kwargs):
self._tabs = []
self._aktuell = 0
def addTab(self, widget, title: str): self._tabs.append((widget, title))
def insertTab(self, index: int, widget, title: str): self._tabs.insert(index, (widget, title))
def removeTab(self, index: int): self._tabs.pop(index)
def count(self) -> int: return len(self._tabs)
def widget(self, index: int): return self._tabs[index][0] if 0 <= index < len(self._tabs) else None
def tabText(self, index: int) -> str: return self._tabs[index][1]
def currentIndex(self) -> int: return self._aktuell
def setCurrentIndex(self, index: int) -> None: self._aktuell = index
QTabWidget = _MockTabWidget