|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2006 - 2010 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a LED widget. |
|
8 |
|
9 It was inspired by KLed. |
|
10 """ |
|
11 |
|
12 from PyQt4.QtGui import * |
|
13 from PyQt4.QtCore import * |
|
14 |
|
15 E5LedRectangular = 0 |
|
16 E5LedCircular = 1 |
|
17 |
|
18 class E5Led(QWidget): |
|
19 """ |
|
20 Class implementing a LED widget. |
|
21 """ |
|
22 def __init__(self, parent = None, color = None, shape = E5LedCircular, rectRatio = 1): |
|
23 """ |
|
24 Constructor |
|
25 |
|
26 @param parent reference to parent widget (QWidget) |
|
27 @param color color of the LED (QColor) |
|
28 @param shape shape of the LED (E5LedCircular, E5LedRectangular) |
|
29 @param rectRation ratio width to height, if shape is rectangular (float) |
|
30 """ |
|
31 QWidget.__init__(self, parent) |
|
32 |
|
33 if color is None: |
|
34 color = QColor("green") |
|
35 |
|
36 self.__led_on = True |
|
37 self.__dark_factor = 300 |
|
38 self.__offcolor = color.dark(self.__dark_factor) |
|
39 self.__led_color = color |
|
40 self.__framedLed = True |
|
41 self.__shape = shape |
|
42 self.__rectRatio = rectRatio |
|
43 |
|
44 self.setColor(color) |
|
45 |
|
46 def paintEvent(self, evt): |
|
47 """ |
|
48 Protected slot handling the paint event. |
|
49 |
|
50 @param evt paint event object (QPaintEvent) |
|
51 @exception TypeError The E5Led has an unsupported shape type. |
|
52 """ |
|
53 if self.__shape == E5LedCircular: |
|
54 self.__paintRound() |
|
55 elif self.__shape == E5LedRectangular: |
|
56 self.__paintRectangular() |
|
57 else: |
|
58 raise TypeError("Unsupported shape type for E5Led.") |
|
59 |
|
60 def __getBestRoundSize(self): |
|
61 """ |
|
62 Private method to calculate the width of the LED. |
|
63 |
|
64 @return new width of the LED (integer) |
|
65 """ |
|
66 width = min(self.width(), self.height()) |
|
67 width -= 2 # leave one pixel border |
|
68 return width > -1 and width or 0 |
|
69 |
|
70 def __paintRound(self): |
|
71 """ |
|
72 Private method to paint a round raised LED. |
|
73 """ |
|
74 # Initialize coordinates, width and height of the LED |
|
75 width = self.__getBestRoundSize() |
|
76 |
|
77 # Calculate the gradient for the LED |
|
78 wh = width / 2 |
|
79 color = self.__led_on and self.__led_color or self.__offcolor |
|
80 gradient = QRadialGradient(wh, wh, wh, 0.8 * wh, 0.8 * wh) |
|
81 gradient.setColorAt(0.0, color.light(200)) |
|
82 gradient.setColorAt(0.6, color) |
|
83 if self.__framedLed: |
|
84 gradient.setColorAt(0.9, color.dark()) |
|
85 gradient.setColorAt(1.0, self.palette().color(QPalette.Dark)) |
|
86 else: |
|
87 gradient.setColorAt(1.0, color.dark()) |
|
88 |
|
89 # now do the drawing |
|
90 paint = QPainter(self) |
|
91 paint.setRenderHint(QPainter.Antialiasing, True) |
|
92 paint.setBrush(QBrush(gradient)) |
|
93 paint.setPen(Qt.NoPen) |
|
94 paint.drawEllipse(1, 1, width, width) |
|
95 paint.end() |
|
96 |
|
97 def __paintRectangular(self): |
|
98 """ |
|
99 Private method to paint a rectangular raised LED. |
|
100 """ |
|
101 # Initialize coordinates, width and height of the LED |
|
102 width = self.height() * self.__rectRatio |
|
103 left = max(0, int((self.width() - width) / 2) - 1) |
|
104 right = min(int((self.width() + width) / 2), self.width()) |
|
105 height = self.height() |
|
106 |
|
107 # now do the drawing |
|
108 painter = QPainter(self) |
|
109 painter.setRenderHint(QPainter.Antialiasing, True) |
|
110 color = self.__led_on and self.__led_color or self.__offcolor |
|
111 |
|
112 painter.setPen(color.light(200)) |
|
113 painter.drawLine(left, 0, left, height - 1) |
|
114 painter.drawLine(left + 1, 0, right - 1, 0) |
|
115 if self.__framedLed: |
|
116 painter.setPen(self.palette().color(QPalette.Dark)) |
|
117 else: |
|
118 painter.setPen(color.dark()) |
|
119 painter.drawLine(left + 1, height - 1, right - 1, height - 1) |
|
120 painter.drawLine(right - 1, 1, right - 1, height - 1) |
|
121 painter.fillRect(left + 1, 1, right - 2, height - 2, QBrush(color)) |
|
122 painter.end() |
|
123 |
|
124 def isOn(self): |
|
125 """ |
|
126 Public method to return the LED state. |
|
127 |
|
128 @return flag indicating the light state (boolean) |
|
129 """ |
|
130 return self.__led_on |
|
131 |
|
132 def shape(self): |
|
133 """ |
|
134 Public method to return the LED shape. |
|
135 |
|
136 @return LED shape (E5LedCircular, E5LedRectangular) |
|
137 """ |
|
138 return self.__shape |
|
139 |
|
140 def ratio(self): |
|
141 """ |
|
142 Public method to return the LED rectangular ratio (width / height). |
|
143 |
|
144 @return LED rectangular ratio (float) |
|
145 """ |
|
146 return self.__rectRatio |
|
147 |
|
148 def color(self): |
|
149 """ |
|
150 Public method to return the LED color. |
|
151 |
|
152 @return color of the LED (QColor) |
|
153 """ |
|
154 return self.__led_color |
|
155 |
|
156 def setOn(self, state): |
|
157 """ |
|
158 Public method to set the LED to on. |
|
159 |
|
160 @param state new state of the LED (boolean) |
|
161 """ |
|
162 if self.__led_on != state: |
|
163 self.__led_on = state |
|
164 self.update() |
|
165 |
|
166 def setShape(self, shape): |
|
167 """ |
|
168 Public method to set the LED shape. |
|
169 |
|
170 @param shape new LED shape (E5LedCircular, E5LedRectangular) |
|
171 """ |
|
172 if self.__shape != shape: |
|
173 self.__shape = shape |
|
174 self.update() |
|
175 |
|
176 def setRatio(self, ratio): |
|
177 """ |
|
178 Public method to set the LED rectangular ratio (width / height). |
|
179 |
|
180 @param ratio new LED rectangular ratio (float) |
|
181 """ |
|
182 if self.__rectRatio != ratio: |
|
183 self.__rectRatio = ratio |
|
184 self.update() |
|
185 |
|
186 def setColor(self, color): |
|
187 """ |
|
188 Public method to set the LED color. |
|
189 |
|
190 @param color color for the LED (QColor) |
|
191 """ |
|
192 if self.__led_color != color: |
|
193 self.__led_color = color |
|
194 self.__offcolor = color.dark(self.__dark_factor) |
|
195 self.update() |
|
196 |
|
197 def setDarkFactor(self, darkfactor): |
|
198 """ |
|
199 Public method to set the dark factor. |
|
200 |
|
201 @param darkfactor value to set for the dark factor (integer) |
|
202 """ |
|
203 if self.__dark_factor != darkfactor: |
|
204 self.__dark_factor = darkfactor |
|
205 self.__offcolor = self.__led_color.dark(darkfactor) |
|
206 self.update() |
|
207 |
|
208 def darkFactor(self): |
|
209 """ |
|
210 Public method to return the dark factor. |
|
211 |
|
212 @return the current dark factor (integer) |
|
213 """ |
|
214 return self.__dark_factor |
|
215 |
|
216 def toggle(self): |
|
217 """ |
|
218 Public slot to toggle the LED state. |
|
219 """ |
|
220 self.setOn(not self.__led_on) |
|
221 |
|
222 def on(self): |
|
223 """ |
|
224 Public slot to set the LED to on. |
|
225 """ |
|
226 self.setOn(True) |
|
227 |
|
228 def off(self): |
|
229 """ |
|
230 Public slot to set the LED to off. |
|
231 """ |
|
232 self.setOn(False) |
|
233 |
|
234 def setFramed(self, framed): |
|
235 """ |
|
236 Public slot to set the __framedLed attribute. |
|
237 |
|
238 @param framed flag indicating the framed state (boolean) |
|
239 """ |
|
240 if self.__framedLed != framed: |
|
241 self.__framedLed = framed |
|
242 self.__off_map = None |
|
243 self.__on_map = None |
|
244 self.update() |
|
245 |
|
246 def isFramed(self): |
|
247 """ |
|
248 Public method to return the framed state. |
|
249 |
|
250 @return flag indicating the current framed state (boolean) |
|
251 """ |
|
252 return self.__framedLed |
|
253 |
|
254 def sizeHint(self): |
|
255 """ |
|
256 Public method to give a hint about our desired size. |
|
257 |
|
258 @return size hint (QSize) |
|
259 """ |
|
260 return QSize(18, 18) |
|
261 |
|
262 def minimumSizeHint(self): |
|
263 """ |
|
264 Public method to give a hint about our minimum size. |
|
265 |
|
266 @return size hint (QSize) |
|
267 """ |
|
268 return QSize(18, 18) |