eric7/EricWidgets/EricLineEdit.py

branch
eric7
changeset 8358
144a6b854f70
parent 8356
68ec9c3d4de5
child 8366
2a9f5153c438
equal deleted inserted replaced
8357:a081458cc57b 8358:144a6b854f70
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2009 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing specialized line edits.
8 """
9
10 import enum
11
12 from PyQt6.QtCore import pyqtSignal, Qt, QEvent
13 from PyQt6.QtWidgets import (
14 QLineEdit, QWidget, QHBoxLayout, QBoxLayout, QLayout, QApplication,
15 QSpacerItem, QSizePolicy
16 )
17
18
19 class EricLineEditSideWidget(QWidget):
20 """
21 Class implementing the side widgets for the line edit class.
22
23 @signal sizeHintChanged() emitted to indicate a change of the size hint
24 """
25 sizeHintChanged = pyqtSignal()
26
27 def __init__(self, parent=None):
28 """
29 Constructor
30
31 @param parent reference to the parent widget (QWidget)
32 """
33 super().__init__(parent)
34
35 def event(self, evt):
36 """
37 Public method to handle events.
38
39 @param evt reference to the event (QEvent)
40 @return flag indicating, whether the event was recognized (boolean)
41 """
42 if evt.type() == QEvent.Type.LayoutRequest:
43 self.sizeHintChanged.emit()
44 return QWidget.event(self, evt)
45
46
47 class EricLineEditSide(enum.Enum):
48 """
49 Class defining the line edit sides.
50 """
51 LEFT = 0
52 RIGHT = 1
53
54
55 class EricLineEdit(QLineEdit):
56 """
57 Class implementing a line edit widget showing some inactive text.
58 """
59 def __init__(self, parent=None, placeholderText=""):
60 """
61 Constructor
62
63 @param parent reference to the parent widget
64 @type QWidget
65 @param placeholderText text to be shown on inactivity
66 @type str
67 """
68 super().__init__(parent)
69
70 self.setMinimumHeight(22)
71
72 self.setPlaceholderText(placeholderText)
73
74 self.__mainLayout = QHBoxLayout(self)
75 self.__mainLayout.setContentsMargins(0, 0, 0, 0)
76 self.__mainLayout.setSpacing(0)
77
78 self.__leftMargin = 0
79 self.__leftWidget = EricLineEditSideWidget(self)
80 self.__leftWidget.resize(0, 0)
81 self.__leftLayout = QHBoxLayout(self.__leftWidget)
82 self.__leftLayout.setContentsMargins(0, 0, 2, 0)
83 if QApplication.isRightToLeft():
84 self.__leftLayout.setDirection(QBoxLayout.Direction.RightToLeft)
85 else:
86 self.__leftLayout.setDirection(QBoxLayout.Direction.LeftToRight)
87 self.__leftLayout.setSizeConstraint(
88 QLayout.SizeConstraint.SetFixedSize)
89
90 self.__rightWidget = EricLineEditSideWidget(self)
91 self.__rightWidget.resize(0, 0)
92 self.__rightLayout = QHBoxLayout(self.__rightWidget)
93 self.__rightLayout.setContentsMargins(0, 0, 2, 0)
94 if self.isRightToLeft():
95 self.__rightLayout.setDirection(QBoxLayout.Direction.RightToLeft)
96 else:
97 self.__rightLayout.setDirection(QBoxLayout.Direction.LeftToRight)
98
99 horizontalSpacer = QSpacerItem(
100 0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
101 self.__mainLayout.addWidget(
102 self.__leftWidget, 0,
103 Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignLeft)
104 self.__mainLayout.addItem(horizontalSpacer)
105 self.__mainLayout.addWidget(
106 self.__rightWidget, 0,
107 Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignRight)
108 if self.isRightToLeft():
109 self.__mainLayout.setDirection(QBoxLayout.Direction.RightToLeft)
110 else:
111 self.__mainLayout.setDirection(QBoxLayout.Direction.LeftToRight)
112
113 self.setWidgetSpacing(3)
114 self.__leftWidget.sizeHintChanged.connect(self._updateTextMargins)
115 self.__rightWidget.sizeHintChanged.connect(self._updateTextMargins)
116
117 def setLeftMargin(self, margin):
118 """
119 Public method to set the left margin.
120
121 @param margin left margin in pixel (integer)
122 """
123 self.__leftMargin = margin
124
125 def leftMargin(self):
126 """
127 Public method to get the size of the left margin.
128
129 @return left margin in pixel (integer)
130 """
131 return self.__leftMargin
132
133 def event(self, evt):
134 """
135 Public method to handle events.
136
137 @param evt reference to the event (QEvent)
138 @return flag indicating, whether the event was recognized (boolean)
139 """
140 if evt.type() == QEvent.Type.LayoutDirectionChange:
141 if self.isRightToLeft():
142 self.__mainLayout.setDirection(
143 QBoxLayout.Direction.RightToLeft)
144 self.__leftLayout.setDirection(
145 QBoxLayout.Direction.RightToLeft)
146 self.__rightLayout.setDirection(
147 QBoxLayout.Direction.RightToLeft)
148 else:
149 self.__mainLayout.setDirection(
150 QBoxLayout.Direction.LeftToRight)
151 self.__leftLayout.setDirection(
152 QBoxLayout.Direction.LeftToRight)
153 self.__rightLayout.setDirection(
154 QBoxLayout.Direction.LeftToRight)
155 return QLineEdit.event(self, evt)
156
157 def _updateTextMargins(self):
158 """
159 Protected slot to update the text margins.
160 """
161 left = (
162 self.__leftWidget.sizeHint().width()
163 if self.__leftMargin == 0 else
164 self.__leftMargin
165 )
166 right = self.__rightWidget.sizeHint().width()
167 top = 0
168 bottom = 0
169 self.setTextMargins(left, top, right, bottom)
170
171 def addWidget(self, widget, position):
172 """
173 Public method to add a widget to a side.
174
175 @param widget reference to the widget to add
176 @type QWidget
177 @param position position to add to
178 @type EricLineEditSide
179 """
180 if widget is None:
181 return
182
183 if self.isRightToLeft():
184 if position == EricLineEditSide.LEFT:
185 position = EricLineEditSide.RIGHT
186 else:
187 position = EricLineEditSide.LEFT
188 if position == EricLineEditSide.LEFT:
189 self.__leftLayout.addWidget(widget)
190 else:
191 self.__rightLayout.insertWidget(1, widget)
192
193 def removeWidget(self, widget):
194 """
195 Public method to remove a widget from a side.
196
197 @param widget reference to the widget to remove
198 @type QWidget
199 """
200 if widget is None:
201 return
202
203 self.__leftLayout.removeWidget(widget)
204 self.__rightLayout.removeWidget(widget)
205 widget.hide()
206
207 def widgetSpacing(self):
208 """
209 Public method to get the side widget spacing.
210
211 @return side widget spacing (integer)
212 """
213 return self.__leftLayout.spacing()
214
215 def setWidgetSpacing(self, spacing):
216 """
217 Public method to set the side widget spacing.
218
219 @param spacing side widget spacing (integer)
220 """
221 self.__leftLayout.setSpacing(spacing)
222 self.__rightLayout.setSpacing(spacing)
223 self._updateTextMargins()
224
225 def textMargin(self, position):
226 """
227 Public method to get the text margin for a side.
228
229 @param position side to get margin for
230 @type EricLineEditSide
231 @return text margin
232 @rtype int
233 """
234 spacing = self.__rightLayout.spacing()
235 w = 0
236 w = (
237 self.__leftWidget.sizeHint().width()
238 if position == EricLineEditSide.LEFT else
239 self.__rightWidget.sizeHint().width()
240 )
241 if w == 0:
242 return 0
243 return w + spacing * 2
244
245 class EricClearableLineEdit(EricLineEdit):
246 """
247 Class implementing a line edit widget showing some inactive text and a
248 clear button, if it has some contents.
249 """
250 def __init__(self, parent=None, placeholderText="",
251 side=EricLineEditSide.RIGHT):
252 """
253 Constructor
254
255 @param parent reference to the parent widget
256 @type QWidget
257 @param placeholderText text to be shown on inactivity
258 @type str
259 @param side side the clear button should be shown at
260 @type EricLineEditSide
261 """
262 super().__init__(parent, placeholderText)
263
264 self.setClearButtonEnabled(True)

eric ide

mercurial