Document buttons
parent
6b54d1838b
commit
7d269b4041
|
@ -13,12 +13,34 @@ from .textbox import AnimatedText
|
||||||
|
|
||||||
|
|
||||||
class AnimBox(QGraphicsObject):
|
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()
|
hoverEnter = pyqtSignal()
|
||||||
hoverExit = pyqtSignal()
|
hoverExit = pyqtSignal()
|
||||||
|
|
||||||
# Initialisation
|
|
||||||
def __init__(self, x, y, width, height, parent=None):
|
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)
|
super().__init__(parent=parent)
|
||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
|
@ -26,17 +48,15 @@ class AnimBox(QGraphicsObject):
|
||||||
self.height = height
|
self.height = height
|
||||||
self.circumference = 2*(width+height)
|
self.circumference = 2*(width+height)
|
||||||
|
|
||||||
# Set up pens for drawing
|
|
||||||
self.default_pen = QPen()
|
self.default_pen = QPen()
|
||||||
self.default_pen.setColor(Qt.white)
|
self.default_pen.setColor(Qt.white)
|
||||||
self.outline_pen = QPen()
|
self.outline_pen = QPen()
|
||||||
self.outline_pen.setColor(Qt.white)
|
self.outline_pen.setColor(Qt.white)
|
||||||
self.outline_pen.setWidth(5)
|
self.outline_pen.setWidth(5)
|
||||||
|
|
||||||
# Whether the mouse hover over the box
|
self.detected = False # Whether the mouse hover over the box
|
||||||
self.detected = False
|
|
||||||
self.btn_rect = QRectF(self.x, self.y, self.width, self.height)
|
self.btn_rect = QRectF(self.x, self.y, self.width, self.height)
|
||||||
# The 4 lines to construct the box
|
|
||||||
self.left = QLineF()
|
self.left = QLineF()
|
||||||
self.down = QLineF()
|
self.down = QLineF()
|
||||||
self.right = QLineF()
|
self.right = QLineF()
|
||||||
|
@ -46,9 +66,7 @@ class AnimBox(QGraphicsObject):
|
||||||
|
|
||||||
self.set_freeze(False)
|
self.set_freeze(False)
|
||||||
|
|
||||||
# Length of the box to be drawn
|
|
||||||
self.length = 0
|
self.length = 0
|
||||||
# Set up the length to be animated
|
|
||||||
self.anim = QPropertyAnimation(self, b'length')
|
self.anim = QPropertyAnimation(self, b'length')
|
||||||
self.anim.setStartValue(0)
|
self.anim.setStartValue(0)
|
||||||
for t in range(1, 10):
|
for t in range(1, 10):
|
||||||
|
@ -56,6 +74,13 @@ class AnimBox(QGraphicsObject):
|
||||||
self.anim.setEndValue(self.circumference)
|
self.anim.setEndValue(self.circumference)
|
||||||
|
|
||||||
def set_freeze(self, freeze):
|
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:
|
if freeze:
|
||||||
self.setAcceptedMouseButtons(Qt.NoButton)
|
self.setAcceptedMouseButtons(Qt.NoButton)
|
||||||
self.setAcceptHoverEvents(False)
|
self.setAcceptHoverEvents(False)
|
||||||
|
@ -63,8 +88,14 @@ class AnimBox(QGraphicsObject):
|
||||||
self.setAcceptedMouseButtons(Qt.LeftButton)
|
self.setAcceptedMouseButtons(Qt.LeftButton)
|
||||||
self.setAcceptHoverEvents(True)
|
self.setAcceptHoverEvents(True)
|
||||||
|
|
||||||
# Toggle the animation to be play forward or backward
|
|
||||||
def toggle_anim(self, toggling):
|
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:
|
if toggling:
|
||||||
self.anim.setDirection(QAbstractAnimation.Forward)
|
self.anim.setDirection(QAbstractAnimation.Forward)
|
||||||
else:
|
else:
|
||||||
|
@ -72,16 +103,30 @@ class AnimBox(QGraphicsObject):
|
||||||
|
|
||||||
self.anim.start()
|
self.anim.start()
|
||||||
|
|
||||||
# The logistic function that determines the animation motion
|
|
||||||
def logistic_func(self, x):
|
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))
|
return self.circumference / (1+math.exp(-(x-0.5)*18))
|
||||||
|
|
||||||
# Reimplemented boundingRect
|
|
||||||
def boundingRect(self):
|
def boundingRect(self):
|
||||||
|
"""Reimplemented from QGraphicsObject.
|
||||||
|
"""
|
||||||
return QRectF(self.x-5, self.y-5, self.width+10, self.height+10)
|
return QRectF(self.x-5, self.y-5, self.width+10, self.height+10)
|
||||||
|
|
||||||
# Reimplemented paint
|
|
||||||
def paint(self, painter, style, widget=None):
|
def paint(self, painter, style, widget=None):
|
||||||
|
"""Reimplemented from QGraphicsObject. Draws the Box and the highlights.
|
||||||
|
"""
|
||||||
painter.setPen(self.outline_pen)
|
painter.setPen(self.outline_pen)
|
||||||
for line in self.line_order:
|
for line in self.line_order:
|
||||||
if line.length() > 1:
|
if line.length() > 1:
|
||||||
|
@ -89,12 +134,13 @@ class AnimBox(QGraphicsObject):
|
||||||
painter.setPen(self.default_pen)
|
painter.setPen(self.default_pen)
|
||||||
painter.drawRect(self.btn_rect)
|
painter.drawRect(self.btn_rect)
|
||||||
|
|
||||||
# Defining the length to be drawn as a pyqtProperty
|
|
||||||
@pyqtProperty(float)
|
@pyqtProperty(float)
|
||||||
def length(self):
|
def length(self):
|
||||||
|
"""float: The length of the highlight to be drawn.
|
||||||
|
When set, the length of the outlines are determined
|
||||||
|
"""
|
||||||
return self._length
|
return self._length
|
||||||
|
|
||||||
# Determine the length of the four lines to be drawn
|
|
||||||
@length.setter
|
@length.setter
|
||||||
def length(self, value):
|
def length(self, value):
|
||||||
self._length = value
|
self._length = value
|
||||||
|
@ -128,8 +174,9 @@ class AnimBox(QGraphicsObject):
|
||||||
self.x + remaining_length, self.y)
|
self.x + remaining_length, self.y)
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
# Reimplemented hoverEvents to detect the mouse and toggle the animation
|
|
||||||
def hoverEnterEvent(self, event):
|
def hoverEnterEvent(self, event):
|
||||||
|
"""Reimplemented hoverEnterEvent. Detect the mouse and toggle the animation
|
||||||
|
"""
|
||||||
if ~self.detected:
|
if ~self.detected:
|
||||||
self.hoverEnter.emit()
|
self.hoverEnter.emit()
|
||||||
self.detected = True
|
self.detected = True
|
||||||
|
@ -137,6 +184,8 @@ class AnimBox(QGraphicsObject):
|
||||||
super().hoverEnterEvent(event)
|
super().hoverEnterEvent(event)
|
||||||
|
|
||||||
def hoverLeaveEvent(self, event):
|
def hoverLeaveEvent(self, event):
|
||||||
|
"""Reimplemented hoverLeaveEvent. Detect the mouse leaving and reverse the animation
|
||||||
|
"""
|
||||||
if self.detected:
|
if self.detected:
|
||||||
self.hoverExit.emit()
|
self.hoverExit.emit()
|
||||||
self.detected = False
|
self.detected = False
|
||||||
|
@ -145,16 +194,37 @@ class AnimBox(QGraphicsObject):
|
||||||
|
|
||||||
|
|
||||||
class RingButton(AnimBox):
|
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)
|
buttonClicked = pyqtSignal(str)
|
||||||
|
|
||||||
# Initialisation
|
# Initialisation
|
||||||
def __init__(self, x, y, width, height, text, parent=None):
|
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)
|
super().__init__(x, y, width, height, parent=parent)
|
||||||
self.text = text
|
self.text = text
|
||||||
self.transparent = False
|
self.transparent = False
|
||||||
|
|
||||||
def set_transparent(self, state):
|
def set_transparent(self, state):
|
||||||
|
"""Make the button transparent
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
state: bool
|
||||||
|
True for transparent, False otherwise
|
||||||
|
"""
|
||||||
self.transparent = state
|
self.transparent = state
|
||||||
col = self.default_pen.color()
|
col = self.default_pen.color()
|
||||||
if state:
|
if state:
|
||||||
|
@ -166,6 +236,8 @@ class RingButton(AnimBox):
|
||||||
|
|
||||||
# Reimplemented paint
|
# Reimplemented paint
|
||||||
def paint(self, painter, style, widget=None):
|
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)
|
super().paint(painter, style, widget)
|
||||||
painter.setPen(self.default_pen)
|
painter.setPen(self.default_pen)
|
||||||
if self.transparent:
|
if self.transparent:
|
||||||
|
@ -175,25 +247,47 @@ class RingButton(AnimBox):
|
||||||
painter.drawText(self.boundingRect(), Qt.AlignCenter, self.text)
|
painter.drawText(self.boundingRect(), Qt.AlignCenter, self.text)
|
||||||
|
|
||||||
def mousePressEvent(self, event):
|
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.toggle_anim(False)
|
||||||
self.buttonClicked.emit(self.text)
|
self.buttonClicked.emit(self.text)
|
||||||
|
|
||||||
|
|
||||||
class MenuButton(AnimBox):
|
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)
|
buttonClicked = pyqtSignal(str)
|
||||||
|
|
||||||
# Initialisation
|
|
||||||
def __init__(self, x, y, width, height, text, parent=None):
|
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)
|
super().__init__(x, y, width, height, parent=parent)
|
||||||
self.text = text
|
self.text = text
|
||||||
self.animText = AnimatedText(text, parent=self)
|
self.animText = AnimatedText(text, parent=self)
|
||||||
|
|
||||||
def paint(self, painter, style, widget=None):
|
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)
|
super().paint(painter, style, widget)
|
||||||
painter.fillRect(self.btn_rect, Qt.black)
|
painter.fillRect(self.btn_rect, Qt.black)
|
||||||
|
|
||||||
def mousePressEvent(self, event):
|
def mousePressEvent(self, event):
|
||||||
|
"""Reimplemented from QGraphicsObject. Receive the click event,
|
||||||
|
then reverse its animation and emit buttonClicked signal
|
||||||
|
"""
|
||||||
self.toggle_anim(False)
|
self.toggle_anim(False)
|
||||||
self.buttonClicked.emit(self.text)
|
self.buttonClicked.emit(self.text)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue