diff --git a/graphic_components/buttons.py b/graphic_components/buttons.py index 0f18e6b..2231207 100644 --- a/graphic_components/buttons.py +++ b/graphic_components/buttons.py @@ -13,12 +13,34 @@ from .textbox import AnimatedText class AnimBox(QGraphicsObject): - # Prepare the signal + """A Box that draws an outline when hover over. + + Attributes + ---------- + hoverEnter: pyqtSignal + Emitted when the mouse hover into the box + hoverExit: pyqtSignal + Emitted when the mouse hover out of the box + """ hoverEnter = pyqtSignal() hoverExit = pyqtSignal() - # Initialisation def __init__(self, x, y, width, height, parent=None): + """Prepares the box and animation + + Parameters + ---------- + x: float + x position of the top-left corner of the box + y: float + y position of the top-left corner of the box + width: float + Width of the box + height: float + Height of the box + parent: object + Passed into QGraphicsObject init method + """ super().__init__(parent=parent) self.x = x self.y = y @@ -26,17 +48,15 @@ class AnimBox(QGraphicsObject): self.height = height self.circumference = 2*(width+height) - # Set up pens for drawing self.default_pen = QPen() self.default_pen.setColor(Qt.white) self.outline_pen = QPen() self.outline_pen.setColor(Qt.white) self.outline_pen.setWidth(5) - # Whether the mouse hover over the box - self.detected = False + self.detected = False # Whether the mouse hover over the box self.btn_rect = QRectF(self.x, self.y, self.width, self.height) - # The 4 lines to construct the box + self.left = QLineF() self.down = QLineF() self.right = QLineF() @@ -46,9 +66,7 @@ class AnimBox(QGraphicsObject): self.set_freeze(False) - # Length of the box to be drawn self.length = 0 - # Set up the length to be animated self.anim = QPropertyAnimation(self, b'length') self.anim.setStartValue(0) for t in range(1, 10): @@ -56,6 +74,13 @@ class AnimBox(QGraphicsObject): self.anim.setEndValue(self.circumference) def set_freeze(self, freeze): + """Set whether the box should accept the mouse events + + Parameters + ---------- + freeze: bool + True to stop the box from accepting mouse inputs, False otherwise + """ if freeze: self.setAcceptedMouseButtons(Qt.NoButton) self.setAcceptHoverEvents(False) @@ -63,8 +88,14 @@ class AnimBox(QGraphicsObject): self.setAcceptedMouseButtons(Qt.LeftButton) self.setAcceptHoverEvents(True) - # Toggle the animation to be play forward or backward def toggle_anim(self, toggling): + """Toggle the highlight animation to be play forward or backward + + Parameters + ---------- + toggling: bool + True for forward, False for backwards + """ if toggling: self.anim.setDirection(QAbstractAnimation.Forward) else: @@ -72,16 +103,30 @@ class AnimBox(QGraphicsObject): self.anim.start() - # The logistic function that determines the animation motion def logistic_func(self, x): + """The logistic function that determines the animation motion + + Parameters + ---------- + x: list or numpy array + Values to be feed into the function + + Returns + ------- + list or numpy array + Values of the logistic function corresponding to the input range + + """ return self.circumference / (1+math.exp(-(x-0.5)*18)) - # Reimplemented boundingRect def boundingRect(self): + """Reimplemented from QGraphicsObject. + """ return QRectF(self.x-5, self.y-5, self.width+10, self.height+10) - # Reimplemented paint def paint(self, painter, style, widget=None): + """Reimplemented from QGraphicsObject. Draws the Box and the highlights. + """ painter.setPen(self.outline_pen) for line in self.line_order: if line.length() > 1: @@ -89,12 +134,13 @@ class AnimBox(QGraphicsObject): painter.setPen(self.default_pen) painter.drawRect(self.btn_rect) - # Defining the length to be drawn as a pyqtProperty @pyqtProperty(float) def length(self): + """float: The length of the highlight to be drawn. + When set, the length of the outlines are determined + """ return self._length - # Determine the length of the four lines to be drawn @length.setter def length(self, value): self._length = value @@ -128,8 +174,9 @@ class AnimBox(QGraphicsObject): self.x + remaining_length, self.y) self.update() - # Reimplemented hoverEvents to detect the mouse and toggle the animation def hoverEnterEvent(self, event): + """Reimplemented hoverEnterEvent. Detect the mouse and toggle the animation + """ if ~self.detected: self.hoverEnter.emit() self.detected = True @@ -137,6 +184,8 @@ class AnimBox(QGraphicsObject): super().hoverEnterEvent(event) def hoverLeaveEvent(self, event): + """Reimplemented hoverLeaveEvent. Detect the mouse leaving and reverse the animation + """ if self.detected: self.hoverExit.emit() self.detected = False @@ -145,16 +194,37 @@ class AnimBox(QGraphicsObject): class RingButton(AnimBox): - # Prepare the signal + """Button specific to the Number Ring. Contains the function to be transparent + + Attributes + ---------- + buttonClicked: pyqtSignal(str) + Emitted when it is clicked. Sends the text of the button + """ buttonClicked = pyqtSignal(str) # Initialisation def __init__(self, x, y, width, height, text, parent=None): + """Set the text and transparency + + Parameters + ---------- + text: str + Text of the button + The remaining parameters are passed into AnimBox init method + """ super().__init__(x, y, width, height, parent=parent) self.text = text self.transparent = False def set_transparent(self, state): + """Make the button transparent + + Parameters + ---------- + state: bool + True for transparent, False otherwise + """ self.transparent = state col = self.default_pen.color() if state: @@ -166,6 +236,8 @@ class RingButton(AnimBox): # Reimplemented paint def paint(self, painter, style, widget=None): + """Reimplement from AnimBox. Calls for AnimBox paint event first, then draw its background and text. + """ super().paint(painter, style, widget) painter.setPen(self.default_pen) if self.transparent: @@ -175,25 +247,47 @@ class RingButton(AnimBox): painter.drawText(self.boundingRect(), Qt.AlignCenter, self.text) def mousePressEvent(self, event): + """Reimplemented from QGraphicsObject. Receive the click event, + then reverse its animation and emit buttonClicked signal + """ + event.accept() self.toggle_anim(False) self.buttonClicked.emit(self.text) class MenuButton(AnimBox): - # Prepare the signal + """Button used in menu. Contains animated text. + + Attributes + ---------- + buttonClicked: pyqtSignal(str) + Emitted when it is clicked. Sends the text of the button + """ buttonClicked = pyqtSignal(str) - # Initialisation def __init__(self, x, y, width, height, text, parent=None): + """Set the text and create AnimatedText + + Parameters + ---------- + text: str + Text of the button + The remaining parameters are passed into AnimBox init method + """ super().__init__(x, y, width, height, parent=parent) self.text = text self.animText = AnimatedText(text, parent=self) def paint(self, painter, style, widget=None): + """Reimplement from AnimBox. Calls for AnimBox paint event first, then draw its background. + """ super().paint(painter, style, widget) painter.fillRect(self.btn_rect, Qt.black) def mousePressEvent(self, event): + """Reimplemented from QGraphicsObject. Receive the click event, + then reverse its animation and emit buttonClicked signal + """ self.toggle_anim(False) self.buttonClicked.emit(self.text)