class FaderWidget(QLabel):

    """Custom Placeholder Fading Widget for tabs on TabWidget."""

    def __init__(self, parent):
        """Init class."""
        super(FaderWidget, self).__init__(parent)
        self.timeline, self.opacity, self.old_pic = QTimeLine(), 1.0, None
        self.timeline.valueChanged.connect(self.animate)
        self.timeline.finished.connect(self.close)
        self.timeline.setDuration(750)  # 500 ~ 750 Ms is Ok, Not more.

    def paintEvent(self, event):
        """Overloaded paintEvent to set opacity and pic."""
        painter = QPainter(self)
        painter.setOpacity(self.opacity)
        if self.old_pic:
            painter.drawPixmap(0, 0, self.old_pic)

    def animate(self, value):
        """Animation of Opacity."""
        self.opacity = 1.0 - value
        return self.hide() if self.opacity < 0.1 else self.repaint()

    def fade(self, old_pic, old_geometry, move_to):
        """Fade from previous tab to new tab."""
        if self.isVisible():
            self.close()
        if self.timeline.state():
            self.timeline.stop()
        self.setGeometry(old_geometry)
        self.move(1, move_to)
        self.old_pic = old_pic
        self.timeline.start()
        self.show()
Beispiel #2
0
class CCountUp(QLabel):
    def __init__(self, *args, **kwargs):
        super(CCountUp, self).__init__(*args, **kwargs)
        self.isFloat = False  # 是否是小数
        font = self.font() or QFont()
        font.setBold(True)
        self.setFont(font)
        self.timeline = QTimeLine(6000, self)
        self.timeline.setEasingCurve(QEasingCurve.OutExpo)
        self.timeline.frameChanged.connect(self.onFrameChanged)

    def pause(self):
        """暂停
        """
        self.timeline.setPaused(True)

    def resume(self):
        """继续
        """
        self.timeline.resume()

    def isPaused(self):
        """是否暂停
        """
        return self.timeline.state() == QTimeLine.Paused

    def reset(self):
        """重置
        """
        self.timeline.stop()
        self.isFloat = False  # 是否是小数
        self.setText('0')

    def onFrameChanged(self, value):
        if self.isFloat:
            value = round(value / 100.0 + 0.00001, 2)
        value = str(format(value, ','))
        self.setText(value + '0' if value.endswith('.0') else value)

    def setDuration(self, duration):
        """设置动画持续时间
        :param duration:
        """
        self.timeline.setDuration(duration)

    def setNum(self, number):
        """设置数字
        :param number:        int or float
        """
        if isinstance(number, int):
            self.isFloat = False
            self.timeline.setFrameRange(0, number)
        elif isinstance(number, float):
            self.isFloat = True
            self.timeline.setFrameRange(0, number * 100)
        self.timeline.stop()
        self.setText('0')
        self.timeline.start()
Beispiel #3
0
class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(600, 600)

        self.label = QLabel('Hello PyQt5', self)
        self.label.move(-100, 100)

        self.timeline = QTimeLine(5000, self)
        self.timeline.setFrameRange(0, 700)
        self.timeline.frameChanged.connect(self.set_frame_func)
        self.timeline.stateChanged.connect(
            lambda: print(self.timeline.state()))  # 1
        self.timeline.setLoopCount(0)

        self.start_btn = QPushButton('Start', self)
        self.stop_btn = QPushButton('Stop', self)
        self.pause_btn = QPushButton('Pause', self)
        self.resume_btn = QPushButton('Resume', self)

        self.start_btn.clicked.connect(self.timeline.start)  # 2
        self.stop_btn.clicked.connect(self.timeline.stop)
        self.pause_btn.clicked.connect(lambda: self.timeline.setPaused(True))
        self.resume_btn.clicked.connect(self.timeline.resume)

        self.h_layout = QHBoxLayout()
        self.v_layout = QVBoxLayout()
        self.h_layout.addWidget(self.start_btn)
        self.h_layout.addWidget(self.stop_btn)
        self.h_layout.addWidget(self.pause_btn)
        self.h_layout.addWidget(self.resume_btn)
        self.v_layout.addStretch(1)
        self.v_layout.addLayout(self.h_layout)
        self.setLayout(self.v_layout)

    def set_frame_func(self, frame):
        self.label.move(-100 + frame, 100)
Beispiel #4
0
class CustomProxy(QGraphicsProxyWidget):
    def __init__(self, parent=None, wFlags=0):
        super(CustomProxy, self).__init__(parent, wFlags)

        self.popupShown = False
        self.currentPopup = None

        self.timeLine = QTimeLine(250, self)
        self.timeLine.valueChanged.connect(self.updateStep)
        self.timeLine.stateChanged.connect(self.stateChanged)

    def boundingRect(self):
        return QGraphicsProxyWidget.boundingRect(self).adjusted(0, 0, 10, 10)

    def paintWindowFrame(self, painter, option, widget):
        color = QColor(0, 0, 0, 64)

        r = self.windowFrameRect()
        right = QRectF(r.right(), r.top() + 10, 10, r.height() - 10)
        bottom = QRectF(r.left() + 10, r.bottom(), r.width(), 10)
        intersectsRight = right.intersects(option.exposedRect)
        intersectsBottom = bottom.intersects(option.exposedRect)
        if intersectsRight and intersectsBottom:
            path = QPainterPath()
            path.addRect(right)
            path.addRect(bottom)
            painter.setPen(Qt.NoPen)
            painter.setBrush(color)
            painter.drawPath(path)
        elif intersectsBottom:
            painter.fillRect(bottom, color)
        elif intersectsRight:
            painter.fillRect(right, color)

        super(CustomProxy, self).paintWindowFrame(painter, option, widget)

    def hoverEnterEvent(self, event):
        super(CustomProxy, self).hoverEnterEvent(event)

        self.scene().setActiveWindow(self)
        if self.timeLine.currentValue != 1:
            self.zoomIn()

    def hoverLeaveEvent(self, event):
        super(CustomProxy, self).hoverLeaveEvent(event)

        if not self.popupShown and (
                self.timeLine.direction() != QTimeLine.Backward
                or self.timeLine.currentValue() != 0):
            self.zoomOut()

    def sceneEventFilter(self, watched, event):
        if watched.isWindow() and (event.type() == QEvent.UngrabMouse
                                   or event.type() == QEvent.GrabMouse):
            self.popupShown = watched.isVisible()
            if not self.popupShown and not self.isUnderMouse():
                self.zoomOut()

        return super(CustomProxy, self).sceneEventFilter(watched, event)

    def itemChange(self, change, value):
        if change == self.ItemChildAddedChange or change == self.ItemChildRemovedChange:
            if change == self.ItemChildAddedChange:
                self.currentPopup = value
                self.currentPopup.setCacheMode(self.ItemCoordinateCache)
                if self.scene() is not None:
                    self.currentPopup.installSceneEventFilter(self)
            elif self.scene() is not None:
                self.currentPopup.removeSceneEventFilter(self)
                self.currentPopup = None
        elif self.currentPopup is not None and change == self.ItemSceneHasChanged:
            self.currentPopup.installSceneEventFilter(self)

        return super(CustomProxy, self).itemChange(change, value)

    def updateStep(self, step):
        r = self.boundingRect()
        self.setTransform(QTransform() \
                            .translate(r.width() / 2, r.height() / 2)\
                            .rotate(step * 30, Qt.XAxis)\
                            .rotate(step * 10, Qt.YAxis)\
                            .rotate(step * 5, Qt.ZAxis)\
                            .scale(1 + 1.5 * step, 1 + 1.5 * step)\
                            .translate(-r.width() / 2, -r.height() / 2))

    def stateChanged(self, state):
        if state == QTimeLine.Running:
            if self.timeLine.direction() == QTimeLine.Forward:
                self.setCacheMode(self.NoCache)
        elif state == QTimeLine.NotRunning:
            if self.timeLine.direction() == QTimeLine.Backward:
                self.setCacheMode(self.DeviceCoordinateCache)

    def zoomIn(self):
        if self.timeLine.direction() != QTimeLine.Forward:
            self.timeLine.setDirection(QTimeLine.Forward)
        if self.timeLine.state() == QTimeLine.NotRunning:
            self.timeLine.start()

    def zoomOut(self):
        if self.timeLine.direction() != QTimeLine.Backward:
            self.timeLine.setDirection(QTimeLine.Backward)
        if self.timeLine.state() == QTimeLine.NotRunning:
            self.timeLine.start()
class CustomProxy(QGraphicsProxyWidget):
    def __init__(self, parent=None, wFlags=0):
        super(CustomProxy, self).__init__(parent, wFlags)

        self.popupShown = False
        self.currentPopup = None

        self.timeLine = QTimeLine(250, self)
        self.timeLine.valueChanged.connect(self.updateStep)
        self.timeLine.stateChanged.connect(self.stateChanged)

    def boundingRect(self):
        return QGraphicsProxyWidget.boundingRect(self).adjusted(0, 0, 10, 10)

    def paintWindowFrame(self, painter, option, widget):
        color = QColor(0, 0, 0, 64)

        r = self.windowFrameRect()
        right = QRectF(r.right(), r.top()+10, 10, r.height()-10)
        bottom = QRectF(r.left()+10, r.bottom(), r.width(), 10)
        intersectsRight = right.intersects(option.exposedRect)
        intersectsBottom = bottom.intersects(option.exposedRect)
        if intersectsRight and intersectsBottom:
            path = QPainterPath()
            path.addRect(right)
            path.addRect(bottom)
            painter.setPen(Qt.NoPen)
            painter.setBrush(color)
            painter.drawPath(path)
        elif intersectsBottom:
            painter.fillRect(bottom, color)
        elif intersectsRight:
            painter.fillRect(right, color)

        super(CustomProxy, self).paintWindowFrame(painter, option, widget)

    def hoverEnterEvent(self, event):
        super(CustomProxy, self).hoverEnterEvent(event)

        self.scene().setActiveWindow(self)
        if self.timeLine.currentValue != 1:
            self.zoomIn()

    def hoverLeaveEvent(self, event):
        super(CustomProxy, self).hoverLeaveEvent(event)

        if not self.popupShown and (self.timeLine.direction() != QTimeLine.Backward or self.timeLine.currentValue() != 0):
            self.zoomOut()

    def sceneEventFilter(self, watched, event):
        if watched.isWindow() and (event.type() == QEvent.UngrabMouse or event.type() == QEvent.GrabMouse):
            self.popupShown = watched.isVisible()
            if not self.popupShown and not self.isUnderMouse():
                self.zoomOut()

        return super(CustomProxy, self).sceneEventFilter(watched, event)

    def itemChange(self, change, value):
        if change == self.ItemChildAddedChange or change == self.ItemChildRemovedChange :
            if change == self.ItemChildAddedChange:
                self.currentPopup = value
                self.currentPopup.setCacheMode(self.ItemCoordinateCache)
                if self.scene() is not None:
                    self.currentPopup.installSceneEventFilter(self)
            elif self.scene() is not None:
                self.currentPopup.removeSceneEventFilter(self)
                self.currentPopup = None
        elif self.currentPopup is not None and change == self.ItemSceneHasChanged:
                self.currentPopup.installSceneEventFilter(self)

        return super(CustomProxy, self).itemChange(change, value)

    def updateStep(self, step):
        r = self.boundingRect()
        self.setTransform(QTransform() \
                            .translate(r.width() / 2, r.height() / 2)\
                            .rotate(step * 30, Qt.XAxis)\
                            .rotate(step * 10, Qt.YAxis)\
                            .rotate(step * 5, Qt.ZAxis)\
                            .scale(1 + 1.5 * step, 1 + 1.5 * step)\
                            .translate(-r.width() / 2, -r.height() / 2))

    def stateChanged(self, state):
        if state == QTimeLine.Running:
            if self.timeLine.direction() == QTimeLine.Forward:
                self.setCacheMode(self.NoCache)
        elif state == QTimeLine.NotRunning:
            if self.timeLine.direction() == QTimeLine.Backward:
                self.setCacheMode(self.DeviceCoordinateCache)

    def zoomIn(self):
        if self.timeLine.direction() != QTimeLine.Forward:
            self.timeLine.setDirection(QTimeLine.Forward)
        if self.timeLine.state() == QTimeLine.NotRunning:
            self.timeLine.start()

    def zoomOut(self):
        if self.timeLine.direction() != QTimeLine.Backward:
            self.timeLine.setDirection(QTimeLine.Backward)
        if self.timeLine.state() == QTimeLine.NotRunning:
            self.timeLine.start()
class SideSlideDecorator(QWidget):
    m_slidePos: QPoint
    m_slideWidgetPixmap: QPixmap
    m_timeline: QTimeLine
    m_backgroundPixmap: QPixmap
    m_decorationColor: QColor

    clicked = pyqtSignal()

    def __init__(self, *args, **kwargs):
        super(SideSlideDecorator, self).__init__(*args, **kwargs)

        self.resize(self.maximumSize())

        self.m_backgroundPixmap = QPixmap()

        self.m_slidePos = QPoint()
        self.m_timeline = QTimeLine()
        self.m_timeline.setDuration(260)
        self.m_timeline.setUpdateInterval(40)
        self.m_timeline.setEasingCurve(QEasingCurve.OutQuad)
        self.m_timeline.setStartFrame(0)
        self.m_timeline.setEndFrame(10000)

        self.m_decorationColor = QColor(0, 0, 0, 0)

        def frameChanged(_value):
            self.m_decorationColor = QColor(0, 0, 0, _value / 100)
            self.update()

        self.m_timeline.frameChanged.connect(frameChanged)

    def grabSlideWidget(self, _slideWidget):
        self.m_slideWidgetPixmap = _slideWidget.grab()

    def grabParent(self):
        # self.m_backgroundPixmap = self.parentWidget().grab()
        pass

    def decorate(self, _dark):
        if self.m_timeline.state() == QTimeLine.Running:
            self.m_timeline.stop()

        self.m_timeline.setDirection(
            QTimeLine.Forward if _dark else QTimeLine.Backward)
        self.m_timeline.start()

    def slidePos(self):
        return self.m_slidePos

    def setSlidePos(self, _pos):
        if self.m_slidePos != _pos:
            self.m_slidePos = _pos
            self.update()

    def paintEvent(self, _event):
        painter = QPainter(self)
        painter.drawPixmap(0, 0, self.m_backgroundPixmap)
        painter.fillRect(self.rect(), self.m_decorationColor)
        painter.drawPixmap(self.m_slidePos, self.m_slideWidgetPixmap)

        super(SideSlideDecorator, self).paintEvent(_event)

    def mousePressEvent(self, _event):
        self.clicked.emit()

        super(SideSlideDecorator, self).mousePressEvent(_event)

    _slidePos = pyqtProperty(QPoint, fget=slidePos, fset=setSlidePos)
Beispiel #7
0
class E5AnimatedWidget(QWidget):
    """
    Class implementing an animated widget.
    """
    DirectionDown = 0
    DirectionUp = 1
    
    def __init__(self, direction=DirectionDown, duration=300, parent=None):
        """
        Constructor
        
        @param direction direction of the animation
        @type int (one of DirectionDown or DirectionUp)
        @param duration duration of the animation
        @type int
        @param parent reference to the parent widget
        @type QWidget
        """
        super(E5AnimatedWidget, self).__init__(parent)
        
        self.__direction = direction
        self.__stepHeight = 0.0
        self.__stepY = 0.0
        self.__startY = 0
        self.__widget = QWidget(self)
        
        self.__timeline = QTimeLine(duration)
        self.__timeline.setFrameRange(0, 100)
        self.__timeline.frameChanged.connect(self.__animateFrame)
        
        self.setMaximumHeight(0)
    
    def widget(self):
        """
        Public method to get a reference to the animated widget.
        
        @return reference to the animated widget
        @rtype QWidget
        """
        return self.__widget
    
    @pyqtSlot()
    def startAnimation(self):
        """
        Public slot to start the animation.
        """
        if self.__timeline.state() == QTimeLine.Running:
            return
        
        shown = 0
        hidden = 0
        
        if self.__direction == self.DirectionDown:
            shown = 0
            hidden = -self.__widget.height()
        
        self.__widget.move(QPoint(self.__widget.pos().x(), hidden))
        
        self.__stepY = (hidden - shown) / 100.0
        self.__startY = hidden
        self.__stepHeight = self.__widget.height() / 100.0
        
        self.__timeline.setDirection(QTimeLine.Forward)
        self.__timeline.start()
    
    @pyqtSlot(int)
    def __animateFrame(self, frame):
        """
        Private slot to animate the next frame.
        
        @param frame frame number
        @type int
        """
        self.setFixedHeight(frame * self.__stepHeight)
        self.__widget.move(self.pos().x(),
                           self.__startY - frame * self.__stepY)
    
    @pyqtSlot()
    def hide(self):
        """
        Public slot to hide the animated widget.
        """
        if self.__timeline.state() == QTimeLine.Running:
            return
        
        self.__timeline.setDirection(QTimeLine.Backward)
        self.__timeline.finished.connect(self.close)
        self.__timeline.start()
        
        p = self.parentWidget()
        if p is not None:
            p.setFocus()
    
    def resizeEvent(self, evt):
        """
        Protected method to handle a resize event.
        
        @param evt reference to the event object
        @type QResizeEvent
        """
        if evt.size().width() != self.__widget.width():
            self.__widget.resize(evt.size().width(), self.__widget.height())
        
        super(E5AnimatedWidget, self).resizeEvent(evt)
class E5AnimatedWidget(QWidget):
    """
    Class implementing an animated widget.
    """
    DirectionDown = 0
    DirectionUp = 1

    def __init__(self, direction=DirectionDown, duration=300, parent=None):
        """
        Constructor
        
        @param direction direction of the animation
        @type int (one of DirectionDown or DirectionUp)
        @param duration duration of the animation
        @type int
        @param parent reference to the parent widget
        @type QWidget
        """
        super(E5AnimatedWidget, self).__init__(parent)

        self.__direction = direction
        self.__stepHeight = 0.0
        self.__stepY = 0.0
        self.__startY = 0
        self.__widget = QWidget(self)

        self.__timeline = QTimeLine(duration)
        self.__timeline.setFrameRange(0, 100)
        self.__timeline.frameChanged.connect(self.__animateFrame)

        self.setMaximumHeight(0)

    def widget(self):
        """
        Public method to get a reference to the animated widget.
        
        @return reference to the animated widget
        @rtype QWidget
        """
        return self.__widget

    @pyqtSlot()
    def startAnimation(self):
        """
        Public slot to start the animation.
        """
        if self.__timeline.state() == QTimeLine.Running:
            return

        shown = 0
        hidden = 0

        if self.__direction == self.DirectionDown:
            shown = 0
            hidden = -self.__widget.height()

        self.__widget.move(QPoint(self.__widget.pos().x(), hidden))

        self.__stepY = (hidden - shown) / 100.0
        self.__startY = hidden
        self.__stepHeight = self.__widget.height() / 100.0

        self.__timeline.setDirection(QTimeLine.Forward)
        self.__timeline.start()

    @pyqtSlot(int)
    def __animateFrame(self, frame):
        """
        Private slot to animate the next frame.
        
        @param frame frame number
        @type int
        """
        self.setFixedHeight(frame * self.__stepHeight)
        self.__widget.move(self.pos().x(),
                           self.__startY - frame * self.__stepY)

    @pyqtSlot()
    def hide(self):
        """
        Public slot to hide the animated widget.
        """
        if self.__timeline.state() == QTimeLine.Running:
            return

        self.__timeline.setDirection(QTimeLine.Backward)
        self.__timeline.finished.connect(self.close)
        self.__timeline.start()

        p = self.parentWidget()
        if p is not None:
            p.setFocus()

    def resizeEvent(self, evt):
        """
        Protected method to handle a resize event.
        
        @param evt reference to the event object
        @type QResizeEvent
        """
        if evt.size().width() != self.__widget.width():
            self.__widget.resize(evt.size().width(), self.__widget.height())

        super(E5AnimatedWidget, self).resizeEvent(evt)