Skip to content

Commit 27e4020

Browse files
committed
Add documentation
1 parent 54985f5 commit 27e4020

File tree

3 files changed

+139
-3
lines changed

3 files changed

+139
-3
lines changed

src/pyqt_loading_button/loading_button.py

Lines changed: 114 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import math
2-
from qtpy.QtCore import QTimeLine, QEasingCurve, Qt
2+
from qtpy.QtCore import QTimeLine, QEasingCurve, Qt, Signal
33
from qtpy.QtGui import QPainter, QPen, QColor
44
from qtpy.QtWidgets import QPushButton
55
from .worker import Worker
@@ -8,9 +8,18 @@
88

99
class LoadingButton(QPushButton):
1010

11+
# Event
12+
finished = Signal()
13+
1114
def __init__(self, parent=None):
15+
"""Create a new LoadingButton instance
16+
17+
:param parent: the parent widget
18+
"""
19+
1220
super(LoadingButton, self).__init__(parent)
1321

22+
# LoadingButton attributes
1423
self.__text = ''
1524
self.__action = None
1625
self.__running = False
@@ -93,9 +102,13 @@ def __init__(self, parent=None):
93102
self.__timeline_dots_down_3.finished.connect(self.__timeline_dots_up_1.start)
94103
self.__timeline_dots_up_3.finished.connect(self.__timeline_dots_down_3.start)
95104

105+
# Execute __start_action() every time the button is clicked
96106
self.clicked.connect(self.__start_action)
97107

98108
def __start_action(self):
109+
"""Handles the button being clicked.
110+
Executes the connected method if not running already and starts the animation."""
111+
99112
if self.__action and not self.__running:
100113
self.__running = True
101114
super().setText('')
@@ -108,6 +121,9 @@ def __start_action(self):
108121
self.update()
109122

110123
def __end_action(self):
124+
"""Called once the executed method is finished.
125+
Handles stopping the animation and showing text again."""
126+
111127
super().setText(self.__text)
112128

113129
self.__timeline_circle_rotation.stop()
@@ -122,53 +138,78 @@ def __end_action(self):
122138
self.__timeline_dots_down_3.stop()
123139

124140
self.__running = False
141+
self.finished.emit()
125142
self.update()
126143

127144
def __handle_timeline_circle_decrease_span(self):
145+
"""Handles timeline for decreasing the circle span"""
146+
128147
self.__circle_span = self.__timeline_circle_decrease_span.currentFrame()
129148
self.update()
130149

131150
def __handle_timeline_circle_increase_span(self):
151+
"""Handles timeline for increasing the circle span"""
152+
132153
self.__circle_span = self.__timeline_circle_increase_span.currentFrame()
133154
self.__circle_additional_rotation = self.__timeline_circle_increase_span.currentFrame() - self.__circle_minimum_span
134155
self.update()
135156

136157
def __handle_timeline_circle_increase_span_start(self):
158+
"""Handles starting the timeline for increasing the circle span"""
159+
137160
self.__circle_previous_additional_rotation = (self.__circle_previous_additional_rotation +
138161
self.__circle_additional_rotation) % 360
139162
self.__timeline_circle_increase_span.start()
140163

141164
def __handle_timeline_dots_up_1(self, value):
165+
"""Handles timeline for moving the first dot upwards"""
166+
142167
self.__dots_offset_1 = self.__timeline_dots_up_1.currentFrame()
143168
if value > 0.75 and self.__timeline_dots_up_2.state() == QTimeLine.State.NotRunning:
144169
self.__timeline_dots_up_2.start()
145170
self.update()
146171

147172
def __handle_timeline_dots_down_1(self):
173+
"""Handles timeline for moving the first dot downwards"""
174+
148175
self.__dots_offset_1 = self.__timeline_dots_down_1.currentFrame()
149176
self.update()
150177

151178
def __handle_timeline_dots_up_2(self, value):
179+
"""Handles timeline for moving the second dot upwards"""
180+
152181
self.__dots_offset_2 = self.__timeline_dots_up_2.currentFrame()
153182
if value > 0.75 and self.__timeline_dots_up_3.state() == QTimeLine.State.NotRunning:
154183
self.__timeline_dots_up_3.start()
155184
self.update()
156185

157186
def __handle_timeline_dots_down_2(self):
187+
"""Handles timeline for moving the second dot downwards"""
188+
158189
self.__dots_offset_2 = self.__timeline_dots_down_2.currentFrame()
159190
self.update()
160191

161192
def __handle_timeline_dots_up_3(self):
193+
"""Handles timeline for moving the third dot upwards"""
194+
162195
self.__dots_offset_3 = self.__timeline_dots_up_3.currentFrame()
163196
self.update()
164197

165198
def __handle_timeline_dots_down_3(self):
199+
"""Handles timeline for moving the third dot downwards"""
200+
166201
self.__dots_offset_3 = self.__timeline_dots_down_3.currentFrame()
167202
self.update()
168203

169204
def paintEvent(self, event):
205+
"""Method that gets called every time the widget needs to be updated.
206+
207+
:param event: event sent by PyQt
208+
"""
209+
170210
super().paintEvent(event)
171211

212+
# Handle circle
172213
if self.__running and self.__animation_type == AnimationType.Circle:
173214

174215
painter = QPainter(self)
@@ -186,6 +227,7 @@ def paintEvent(self, event):
186227

187228
painter.drawArc(x, y, diameter, diameter, rotation, span)
188229

230+
# Handle dots
189231
elif self.__running and self.__animation_type == AnimationType.Dots:
190232

191233
painter = QPainter(self)
@@ -206,29 +248,69 @@ def paintEvent(self, event):
206248
self.__animation_stroke_width, self.__animation_stroke_width)
207249

208250
def text(self) -> str:
251+
"""Get the current button text
252+
253+
:return: button text
254+
"""
255+
209256
return self.__text
210257

211-
def setText(self, text: str) -> None:
258+
def setText(self, text: str):
259+
"""Set the button text
260+
261+
:param text: new button text
262+
"""
263+
212264
self.__text = text
213265
if not self.__running:
214266
super().setText(self.__text)
215267

216268
def setAction(self, action: callable):
269+
"""Set the action to be executed on button press
270+
271+
:param action: new action to be executed on button press
272+
"""
273+
217274
self.__action = action
218275

219276
def isRunning(self) -> bool:
277+
"""Get whether the button's action is currently being executed
278+
279+
:return: Whether the button's action is currently being executed
280+
"""
281+
220282
return self.__running
221283

222284
def getAnimationType(self) -> AnimationType:
285+
"""Get the current animation type
286+
287+
:return: animation type
288+
"""
289+
223290
return self.__animation_type
224291

225292
def setAnimationType(self, animation_type: AnimationType):
293+
"""Set the animation type
294+
295+
:param animation_type: new animation type
296+
"""
297+
226298
self.__animation_type = animation_type
227299

228300
def getAnimationSpeed(self) -> int:
301+
"""Get the current animation speed (in ms)
302+
303+
:return: animation speed (in ms)
304+
"""
305+
229306
return self.__animation_speed
230307

231308
def setAnimationSpeed(self, speed: int):
309+
"""Set the animation speed (in ms)
310+
311+
:param speed: new animation speed (in ms)
312+
"""
313+
232314
self.__animation_speed = speed
233315

234316
self.__circle_span_speed = int(self.__animation_speed * self.__circle_speed_coefficient)
@@ -246,19 +328,49 @@ def setAnimationSpeed(self, speed: int):
246328
self.__timeline_dots_down_3.setDuration(self.__dots_single_speed)
247329

248330
def getAnimationWidth(self) -> int:
331+
"""Get the current animation width
332+
333+
:return: animation width
334+
"""
335+
249336
return self.__animation_width
250337

251338
def setAnimationWidth(self, width: int):
339+
"""Set the animation width
340+
341+
:param width: new animation width
342+
"""
343+
252344
self.__animation_width = width
253345

254346
def getAnimationStrokeWidth(self) -> int:
347+
"""Get the current animation stroke width
348+
349+
:return: animation stroke width
350+
"""
351+
255352
return self.__animation_stroke_width
256353

257354
def setAnimationStrokeWidth(self, width: int):
355+
"""Set the animation stroke width
356+
357+
:param width: new animation stroke width
358+
"""
359+
258360
self.__animation_stroke_width = width
259361

260362
def getAnimationColor(self) -> QColor:
363+
"""Get the current animation color
364+
365+
:return: animation color
366+
"""
367+
261368
return self.__animation_color
262369

263370
def setAnimationColor(self, color: QColor):
371+
"""Set the animation color
372+
373+
:param color: new animation color
374+
"""
375+
264376
self.__animation_color = color

src/pyqt_loading_button/worker.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,21 @@
33

44
class Worker(QThread):
55

6+
# Event
67
finished = Signal()
78

89
def __init__(self, action: callable):
10+
"""Create a new Worker instance
11+
12+
:param action: action to be executed
13+
"""
14+
915
super(Worker, self).__init__()
1016

1117
self.__action = action
1218

1319
def run(self):
20+
"""Executes the specified action"""
21+
1422
self.__action()
1523
self.finished.emit()

tests/loading_button_test.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ def test_initial_values(qtbot):
2222

2323

2424
def test_set_text(qtbot):
25+
"""Test setting the button text"""
26+
2527
loading_button = LoadingButton()
2628
qtbot.addWidget(loading_button)
2729

@@ -30,6 +32,8 @@ def test_set_text(qtbot):
3032

3133

3234
def test_set_animation_type(qtbot):
35+
"""Test setting the animation type"""
36+
3337
loading_button = LoadingButton()
3438
qtbot.addWidget(loading_button)
3539

@@ -38,6 +42,8 @@ def test_set_animation_type(qtbot):
3842

3943

4044
def test_set_animation_speed(qtbot):
45+
"""Test setting the animation speed"""
46+
4147
loading_button = LoadingButton()
4248
qtbot.addWidget(loading_button)
4349

@@ -46,6 +52,8 @@ def test_set_animation_speed(qtbot):
4652

4753

4854
def test_set_animation_width(qtbot):
55+
"""Test setting the animation width"""
56+
4957
loading_button = LoadingButton()
5058
qtbot.addWidget(loading_button)
5159

@@ -54,14 +62,18 @@ def test_set_animation_width(qtbot):
5462

5563

5664
def test_set_animation_stroke_width(qtbot):
65+
"""Test setting the animation stroke width"""
66+
5767
loading_button = LoadingButton()
5868
qtbot.addWidget(loading_button)
5969

6070
loading_button.setAnimationStrokeWidth(5)
6171
assert loading_button.getAnimationStrokeWidth() == 5
6272

6373

64-
def test_setAnimationColor(qtbot):
74+
def test_set_animation_color(qtbot):
75+
"""Test setting the animation color"""
76+
6577
loading_button = LoadingButton()
6678
qtbot.addWidget(loading_button)
6779

@@ -71,6 +83,8 @@ def test_setAnimationColor(qtbot):
7183

7284

7385
def test_click_event_circle(qtbot):
86+
"""Test the click event for the circular animation"""
87+
7488
loading_button = LoadingButton()
7589
qtbot.addWidget(loading_button)
7690

@@ -94,6 +108,8 @@ def action():
94108

95109

96110
def test_click_event_dots(qtbot):
111+
"""Test the click event for the dotted animation"""
112+
97113
loading_button = LoadingButton()
98114
qtbot.addWidget(loading_button)
99115

0 commit comments

Comments
 (0)