Line data Source code
1 : # SPDX-FileCopyrightText: 2025 PairInteraction Developers
2 : # SPDX-License-Identifier: LGPL-3.0-or-later
3 1 : from __future__ import annotations
4 :
5 1 : from typing import TYPE_CHECKING, Generic, TypeVar
6 :
7 1 : from PySide6.QtCore import Qt
8 1 : from PySide6.QtWidgets import QFormLayout, QHBoxLayout, QLayout, QVBoxLayout, QWidget
9 :
10 : if TYPE_CHECKING:
11 : from PySide6.QtCore import QObject
12 :
13 : ChildType = TypeVar("ChildType", bound=QObject)
14 : from pairinteraction_gui.main_window import MainWindow
15 :
16 1 : LayoutType = TypeVar("LayoutType", bound=QLayout)
17 :
18 :
19 1 : class Widget(QWidget, Generic[LayoutType]):
20 : """Custom Widget class."""
21 :
22 1 : layout_type: type[LayoutType]
23 1 : margin: tuple[int, int, int, int] = (0, 0, 0, 0)
24 1 : spacing: int = 0
25 :
26 1 : def __init__(
27 : self,
28 : parent: QWidget | None = None,
29 : *,
30 : name: str | None = None,
31 : margin: tuple[int, int, int, int] | None = None,
32 : spacing: int | None = None,
33 : ) -> None:
34 : """Initialize the base section."""
35 1 : super().__init__(parent)
36 :
37 1 : if name is not None:
38 0 : self.setObjectName(name)
39 1 : if margin is not None:
40 0 : self.margin = margin
41 1 : if spacing is not None:
42 0 : self.spacing = spacing
43 :
44 1 : layout = self.layout_type(self) # can be accessed as self.layout()
45 1 : layout.setContentsMargins(*self.margin)
46 1 : layout.setSpacing(self.spacing)
47 :
48 1 : self.setupWidget()
49 1 : self.postSetupWidget()
50 :
51 1 : def layout(self) -> LayoutType:
52 1 : return super().layout() # type: ignore [return-value] # explicitly override type hints
53 :
54 1 : def window(self) -> MainWindow:
55 1 : return super().window() # type: ignore [return-value] # explicitly override type hints
56 :
57 1 : def findChild( # type: ignore [override] # explicitly override type hints
58 : self, type_: type[ChildType], name: str, options: Qt.FindChildOption | None = None
59 : ) -> ChildType:
60 1 : if options is None:
61 1 : options = Qt.FindChildOption.FindChildrenRecursively
62 1 : return super().findChild(type_, name, options) # type: ignore [return-value] # explicitly override type hints
63 :
64 1 : def setupWidget(self) -> None:
65 : """Set up the UI components.
66 :
67 : This method should be overwritten by subclasses to set up the UI components.
68 : """
69 :
70 1 : def postSetupWidget(self) -> None:
71 : """Post-process the UI components.
72 :
73 : This method should be overwritten by subclasses to post-process the UI components.
74 : """
75 :
76 :
77 1 : class WidgetV(Widget[QVBoxLayout]):
78 : """Custom Widget class with vertical (QVBoxLayout) layout."""
79 :
80 1 : layout_type = QVBoxLayout
81 :
82 :
83 1 : class WidgetH(Widget[QHBoxLayout]):
84 : """Custom Widget class with horizontal (QHBoxLayout) layout."""
85 :
86 1 : layout_type = QHBoxLayout
87 :
88 :
89 1 : class WidgetForm(Widget[QFormLayout]):
90 : """Custom Widget class with form (QFormLayout) layout."""
91 :
92 1 : layout_type = QFormLayout
93 1 : margin = (5, 15, 5, 5)
94 1 : spacing = 10
|