예제 #1
1
    def addMovementAnimation(self, animGroup):
#        print(">>MoveAnim")
        for phIdx in self.photoIdxsToMove:
            item = self.photosInGrid[phIdx]
            anim = QPropertyAnimation(item.pixmap, "pos")
            anim.setDuration(self.moveDuration - item.gridCol * self.moveModifier)
            anim.setEasingCurve(QEasingCurve.Linear)
            startCoords = self.getCellTLCoords(item.gridRow, item.gridCol)
            endCoords = self.getCellTLCoords(item.gridRow, item.gridCol + self.columnMovementDist)
            anim.setStartValue(startCoords)
            anim.setEndValue(endCoords)
            animGroup.addAnimation(anim)
예제 #2
0
class Tab(QObject):

    def __init__(self, parent):
        QObject.__init__(self, parent)
        self._toolbar = parent
        self.icon = None
        self.text = ""
        self.has_menu = False
        self.enabled = True
        self._fader = 0
        self._animator = QPropertyAnimation(self)
        self._animator.setPropertyName(b"fader")
        self._animator.setTargetObject(self)

    def fade_in(self):
        self._animator.stop()
        self._animator.setDuration(80)
        self._animator.setEndValue(1)
        self._animator.start()

    def fade_out(self):
        self._animator.stop()
        self._animator.setDuration(160)
        self._animator.setEndValue(0)
        self._animator.start()

    def _set_fader(self, value):
        self._fader = value
        self._toolbar.update()

    def _get_fader(self):
        return self._fader

    fader = pyqtProperty(float, fget=_get_fader, fset=_set_fader)
예제 #3
0
class MoveSymbol(QUndoCommand):
    ''' Undo/Redo command for moving symbols '''
    def __init__(self, symbol_id, old_pos, new_pos, animate=False):
        super(MoveSymbol, self).__init__()
        self.setText('Move symbol')
        self.symbol = symbol_id
        self.old_pos = old_pos
        self.new_pos = new_pos
        if animate:
            self.animation = QPropertyAnimation(self.symbol, "position")
            self.animation.setDuration(500)
            self.animation.setStartValue(self.old_pos)
            self.animation.setEndValue(self.new_pos)
            self.animation.setEasingCurve(QEasingCurve.OutCirc)

    def undo(self):
        ''' Undo a symbol move '''
        self.symbol.position = self.old_pos
        try:
            self.symbol.decisionParent.updateConnectionPointPosition()
        except AttributeError:
            pass

    def redo(self):
        ''' Apply a symbol move '''
        try:
            self.animation.start()
        except AttributeError:
            self.symbol.position = self.new_pos
        try:
            self.symbol.decisionParent.updateConnectionPointPosition()
        except AttributeError:
            pass
예제 #4
0
 def createPositionAnimation(self, item, duration):
     ani = QPropertyAnimation(item, b'pos', self)
     ani.setDuration(duration)
     ani.setStartValue(item.pos())
     width = self.squareWidth * 7
     ani.setEndValue(QPointF(width - item.x(),
                             width - item.y()))
     return ani
예제 #5
0
    def createAnimation(self, target, index):
        '''创建动画'''
        # 暂停动画一
        PauseAnimation1 = QPauseAnimation(target)
        PauseAnimation1.setDuration(150 * index)

        # 并行动画组一
        # #透明度动画一
        OpacityAnimation1 = QPropertyAnimation(target, b"opacity")
        OpacityAnimation1.setDuration(400)
        OpacityAnimation1.setStartValue(0)
        OpacityAnimation1.setEndValue(1)
        # #移动动画一
        MoveAnimation1 = _MoveAnimation(target, self.parent, self.easing)
        MoveAnimation1.setMoveType(_MoveAnimation.MOVE1)
        MoveAnimation1.setDuration(400)
        MoveAnimation1.setStartValue(QPoint(0, 0))
        MoveAnimation1.setEndValue(QPoint(self.parent.width() / 4.0, 0))
        # 添加到并行动画里面
        ParallelAnimation1 = QParallelAnimationGroup()
        ParallelAnimation1.addAnimation(OpacityAnimation1)
        ParallelAnimation1.addAnimation(MoveAnimation1)

        # 移动动画二
        MoveAnimation2 = _MoveAnimation(target, self.parent, self.easing)
        MoveAnimation2.setMoveType(_MoveAnimation.MOVE2)
        MoveAnimation2.setDuration(2000)
        MoveAnimation2.setEndValue(QPoint((self.parent.width() / 4.0) * 3.0, 0))

        # 并行动画组二
        # #透明度动画二
        OpacityAnimation2 = QPropertyAnimation(target, b"opacity")
        OpacityAnimation2.setDuration(400)
        OpacityAnimation2.setStartValue(1)
        OpacityAnimation2.setEndValue(0)
        # #移动动画三
        MoveAnimation3 = _MoveAnimation(target, self.parent, self.easing)
        MoveAnimation3.setMoveType(_MoveAnimation.MOVE3)
        MoveAnimation3.setDuration(400)
        MoveAnimation3.setEndValue(QPoint(self.parent.width(), 0))
        # 添加到并行动画里面
        ParallelAnimation2 = QParallelAnimationGroup()
        ParallelAnimation2.addAnimation(OpacityAnimation2)
        ParallelAnimation2.addAnimation(MoveAnimation3)

        # 暂停动画二
        PauseAnimation2 = QPauseAnimation(target)
        PauseAnimation2.setDuration(150 * (5 - index - 1))

        # 串行动画组
        self.setLoopCount(-1)    # 无限循环
        self.addAnimation(PauseAnimation1)
        self.addAnimation(ParallelAnimation1)
        self.addAnimation(MoveAnimation2)
        self.addAnimation(ParallelAnimation2)
        self.addAnimation(PauseAnimation2)
예제 #6
0
    def __init__(self):
        super(Robot, self).__init__()

        self.setFlag(self.ItemHasNoContents)

        self.torsoItem = RobotTorso(self)
        self.headItem = RobotHead(self.torsoItem)
        self.upperLeftArmItem = RobotLimb(self.torsoItem)
        self.lowerLeftArmItem = RobotLimb(self.upperLeftArmItem)
        self.upperRightArmItem = RobotLimb(self.torsoItem)
        self.lowerRightArmItem = RobotLimb(self.upperRightArmItem)
        self.upperRightLegItem = RobotLimb(self.torsoItem)
        self.lowerRightLegItem = RobotLimb(self.upperRightLegItem)
        self.upperLeftLegItem = RobotLimb(self.torsoItem)
        self.lowerLeftLegItem = RobotLimb(self.upperLeftLegItem)

        settings = (
            #    Item                       Position        Rotation  Scale
            #                                x     y    start    end
            (self.headItem, 0, -18, 20, -20, 1.1),
            (self.upperLeftArmItem, -15, -10, 190, 180, 0),
            (self.lowerLeftArmItem, 30, 0, 50, 10, 0),
            (self.upperRightArmItem, 15, -10, 300, 310, 0),
            (self.lowerRightArmItem, 30, 0, 0, -70, 0),
            (self.upperRightLegItem, 10, 32, 40, 120, 0),
            (self.lowerRightLegItem, 30, 0, 10, 50, 0),
            (self.upperLeftLegItem, -10, 32, 150, 80, 0),
            (self.lowerLeftLegItem, 30, 0, 70, 10, 0),
            (self.torsoItem, 0, 0, 5, -20, 0),
        )

        animation = QParallelAnimationGroup(self)
        for item, pos_x, pos_y, start_rot, end_rot, scale in settings:
            item.setPos(pos_x, pos_y)

            rot_animation = QPropertyAnimation(item, b"rotation")
            rot_animation.setStartValue(start_rot)
            rot_animation.setEndValue(end_rot)
            rot_animation.setEasingCurve(QEasingCurve.SineCurve)
            rot_animation.setDuration(2000)
            animation.addAnimation(rot_animation)

            if scale > 0:
                scale_animation = QPropertyAnimation(item, b"scale")
                scale_animation.setEndValue(scale)
                scale_animation.setEasingCurve(QEasingCurve.SineCurve)
                scale_animation.setDuration(2000)
                animation.addAnimation(scale_animation)

        animation.setLoopCount(-1)
        animation.start()
예제 #7
0
class CircleObstruction(QColorThemedGraphicsObject):
    """
    Useful for notifications, I...guess?
    """
    def get_thickness(self):
        return self._thickness
    def set_thickness(self,c):
        self._thickness = c
        self.update()
    thickness = pyqtProperty(float, get_thickness, set_thickness)
    def __init__(self, sz, thickness, parent=None):
        super(CircleObstruction, self).__init__(parent)
        self._sz = sz
        self._thickness = thickness
        self._color = Qt.blue
    def boundingRect(self):
        return QRectF(-self._thickness,
                      -self._thickness,
                      self._sz + 2*self._thickness,
                      self._sz + 2*self._thickness)

    def paint(self, painter, option, widget):
        # painter.setPen(QPen(self._color,
        #                     self._thickness))
        painter.setBrush(self._color)
        painter.setPen(Qt.NoPen)
        painter.drawEllipse(QRectF(
            self._sz/2.0 - self._thickness,
            self._sz/2.0 - self._thickness,
            2*self._thickness,
            2*self._thickness,
        ))
    def show_anim(self):
        self.anim = QPropertyAnimation(self, "thickness")
        self.anim.setDuration(2000)
        self.anim.setStartValue(self.get_thickness())
        self.anim.setEndValue(50.0)
        self.anim.setEasingCurve(QEasingCurve.OutElastic)
        self.anim.start()
    def hide_anim(self):
        self.anim = QPropertyAnimation(self, "thickness")
        self.anim.setDuration(500)
        self.anim.setStartValue(self.get_thickness())
        self.anim.setEndValue(0.0)
        self.anim.setEasingCurve(QEasingCurve.InBack)
        self.anim.start()
예제 #8
0
파일: notify.py 프로젝트: ykelvis/FeelUOwn
class NotifyWidget(QWidget):
    def __init__(self):
        super().__init__()

        self.layout = QVBoxLayout(self)

        self.sub_widget = _NotifySubWidget(self)
        self.layout.addWidget(self.sub_widget)
        self.layout.setContentsMargins(0, 0, 0, 0)

        self._exit_shortcut = QShortcut(QKeySequence(Qt.Key_Escape), self)
        self._exit_shortcut.activated.connect(self.close)

        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setAttribute(Qt.WA_MacAlwaysShowToolWindow)

        self.resize(width, height)
        self.move(QApplication.desktop().width() - self.width() - 20, 40)
        self.setLayout(self.layout)

        self._animation = QPropertyAnimation(self, b'windowOpacity')
        self._animation.setStartValue(0.8)
        self._animation.setKeyValueAt(0.4, 1)
        self._animation.setEndValue(0)
        self._animation.setDuration(5000)
        self._animation.finished.connect(self.close)

    def show(self):
        super().show()
        self._animation.start()

    def show_message(self, title, content, pixmap=None):
        if not self.isVisible():
            self.show()
        self._animation.stop()
        self._animation.setCurrentTime(0)
        self._animation.start()
        self.sub_widget.set_title(title)
        self.sub_widget.set_content(content)
        pixmap = pixmap if pixmap else QPixmap(WINDOW_ICON)
        self.sub_widget.set_pixmap(pixmap)

    def enterEvent(self, event):
        self._animation.setCurrentTime(0)
예제 #9
0
    def animate(self, item, property_name, duration, start_value, end_value):
        """Summary

        Args:
            item (TYPE): Description
            property_name (TYPE): Description
            duration (TYPE): Description
            start_value (TYPE): Description
            end_value (TYPE): Description
        """
        if item is not None:
            b_name = property_name.encode('ascii')
            anim = QPropertyAnimation(item.adapter, b_name)
            anim.setDuration(duration)
            anim.setStartValue(start_value)
            anim.setEndValue(end_value)
            anim.start()
            item.adapter.saveRef(property_name, anim)
예제 #10
0
    def addRemovalAnimation(self, animGroup):
#        print(">>RemoveAnim")
        for phIdx in self.photoIdxsToRemove:
            item = self.photosInGrid[phIdx]
            anim = QPropertyAnimation(item.pixmap, "scale")
            anim.setDuration(self.shrinkDuration)
            anim.setEasingCurve(QEasingCurve.Linear)
            anim.setStartValue(1.0)
            anim.setEndValue(0.0)
            animGroup.addAnimation(anim)
            anim = QPropertyAnimation(item.pixmap, "pos")
            anim.setDuration(self.shrinkDuration)
            anim.setEasingCurve(QEasingCurve.Linear)
            startCoords = self.getCellTLCoords(item.gridRow, item.gridCol)
            endCoords = QPointF(startCoords.x()+self.cellSize.width()*item.xFactor, startCoords.y() + item.pixmap.pixmapSize.height() / 2)
            anim.setStartValue(startCoords)
            anim.setEndValue(endCoords)
            animGroup.addAnimation(anim)
예제 #11
0
    def addInsertionAnimation(self, animGroup):
        # Animation for added
#        print(">>>InsAnim")
        for ph in self.picItemsToAdd:
            # Set pixmap start location
            newPixmap = ph[0].pixmap
            row = ph[1]
            col = ph[2]
            xFact = ph[0].xFactor
            endCoords = self.getCellTLCoords(row, col)
            startCoords = QPointF(endCoords.x()-self.cellSize.width()*xFact, endCoords.y())
            newPixmap.pixmap_item.setPos(startCoords)
            newPixmap.pixmap_item.setVisible(True)
            # Animate in
            anim = QPropertyAnimation(newPixmap, "pos")
            anim.setDuration(self.insertDuration)
            anim.setStartValue(startCoords)
            anim.setEasingCurve(QEasingCurve.Linear)
            anim.setEndValue(endCoords)
            animGroup.addAnimation(anim)
예제 #12
0
 def animate(self, item: QGraphicsItem,
                 property_name: str, duration: int,
                 start_value, end_value):
     """
     Args:
         item: Description
         property_name: Description
         duration: Description
         start_value (QVariant): Description
         end_value (QVariant): Description
     """
     b_name = property_name.encode('ascii')
     anim = item.adapter.getRef(property_name)
     if anim is None:
         anim = QPropertyAnimation(item.adapter, b_name)
         item.adapter.saveRef(property_name, anim)
     anim.setDuration(duration)
     anim.setStartValue(start_value)
     anim.setEndValue(end_value)
     anim.start()
예제 #13
0
class ChannelListItem(QWidget):
    """
    This class is responsible for managing the item in the list of channels.
    The list item supports a fade-in effect, which can be enabled with the should_fade parameter in the constructor.
    """

    def __init__(self, parent, channel, fade_delay=0, should_fade=False):
        super(QWidget, self).__init__(parent)

        uic.loadUi('qt_resources/channel_list_item.ui', self)

        self.channel_name.setText(channel["name"])
        self.channel_description_label.setText("Active 6 days ago • %d items" % channel["torrents"])
        self.channel_num_subs_label.setText(str(channel["votes"]))
        if channel["sub"]:
            self.channel_subscribe_button.setText("✓ subscribed")
        else:
            self.channel_subscribe_button.setText("subscribe")

        if should_fade:
            self.opacity_effect = QGraphicsOpacityEffect(self)
            self.opacity_effect.setOpacity(0)
            self.setGraphicsEffect(self.opacity_effect)

            self.timer = QTimer()
            self.timer.setInterval(fade_delay)
            self.timer.timeout.connect(self.fadeIn)
            self.timer.start()

    def fadeIn(self):
        self.anim = QPropertyAnimation(self.opacity_effect, 'opacity')
        self.anim.setDuration(800)
        self.anim.setStartValue(0)
        self.anim.setEndValue(1)
        self.anim.start()
        self.timer.stop()
예제 #14
0
    def __init__(self, size, parent=None):
        super(PadNavigator, self).__init__(parent)

        self.form = Ui_Form()

        splash = SplashItem()
        splash.setZValue(1)

        pad = FlippablePad(size)
        flipRotation = QGraphicsRotation(pad)
        xRotation = QGraphicsRotation(pad)
        yRotation = QGraphicsRotation(pad)
        flipRotation.setAxis(Qt.YAxis)
        xRotation.setAxis(Qt.YAxis)
        yRotation.setAxis(Qt.XAxis)
        pad.setTransformations([flipRotation, xRotation, yRotation])

        backItem = QGraphicsProxyWidget(pad)
        widget = QWidget()
        self.form.setupUi(widget)
        self.form.hostName.setFocus()
        backItem.setWidget(widget)
        backItem.setVisible(False)
        backItem.setFocus()
        backItem.setCacheMode(QGraphicsItem.ItemCoordinateCache)
        r = backItem.rect()
        backItem.setTransform(QTransform().rotate(180, Qt.YAxis).translate(-r.width()/2, -r.height()/2))

        selectionItem = RoundRectItem(QRectF(-60, -60, 120, 120),
                QColor(Qt.gray), pad)
        selectionItem.setZValue(0.5)

        smoothSplashMove = QPropertyAnimation(splash, b'y')
        smoothSplashOpacity = QPropertyAnimation(splash, b'opacity')
        smoothSplashMove.setEasingCurve(QEasingCurve.InQuad)
        smoothSplashMove.setDuration(250)
        smoothSplashOpacity.setDuration(250)

        smoothXSelection = QPropertyAnimation(selectionItem, b'x')
        smoothYSelection = QPropertyAnimation(selectionItem, b'y')
        smoothXRotation = QPropertyAnimation(xRotation, b'angle')
        smoothYRotation = QPropertyAnimation(yRotation, b'angle')
        smoothXSelection.setDuration(125)
        smoothYSelection.setDuration(125)
        smoothXRotation.setDuration(125)
        smoothYRotation.setDuration(125)
        smoothXSelection.setEasingCurve(QEasingCurve.InOutQuad)
        smoothYSelection.setEasingCurve(QEasingCurve.InOutQuad)
        smoothXRotation.setEasingCurve(QEasingCurve.InOutQuad)
        smoothYRotation.setEasingCurve(QEasingCurve.InOutQuad)

        smoothFlipRotation = QPropertyAnimation(flipRotation, b'angle')
        smoothFlipScale = QPropertyAnimation(pad, b'scale')
        smoothFlipXRotation = QPropertyAnimation(xRotation, b'angle')
        smoothFlipYRotation = QPropertyAnimation(yRotation, b'angle')
        flipAnimation = QParallelAnimationGroup(self)
        smoothFlipScale.setDuration(500)
        smoothFlipRotation.setDuration(500)
        smoothFlipXRotation.setDuration(500)
        smoothFlipYRotation.setDuration(500)
        smoothFlipScale.setEasingCurve(QEasingCurve.InOutQuad)
        smoothFlipRotation.setEasingCurve(QEasingCurve.InOutQuad)
        smoothFlipXRotation.setEasingCurve(QEasingCurve.InOutQuad)
        smoothFlipYRotation.setEasingCurve(QEasingCurve.InOutQuad)
        smoothFlipScale.setKeyValueAt(0, 1.0)
        smoothFlipScale.setKeyValueAt(0.5, 0.7)
        smoothFlipScale.setKeyValueAt(1, 1.0)
        flipAnimation.addAnimation(smoothFlipRotation)
        flipAnimation.addAnimation(smoothFlipScale)
        flipAnimation.addAnimation(smoothFlipXRotation)
        flipAnimation.addAnimation(smoothFlipYRotation)

        setVariablesSequence = QSequentialAnimationGroup()
        setFillAnimation = QPropertyAnimation(pad, b'fill')
        setBackItemVisibleAnimation = QPropertyAnimation(backItem, b'visible')
        setSelectionItemVisibleAnimation = QPropertyAnimation(selectionItem, b'visible')
        setFillAnimation.setDuration(0)
        setBackItemVisibleAnimation.setDuration(0)
        setSelectionItemVisibleAnimation.setDuration(0)
        setVariablesSequence.addPause(250)
        setVariablesSequence.addAnimation(setBackItemVisibleAnimation)
        setVariablesSequence.addAnimation(setSelectionItemVisibleAnimation)
        setVariablesSequence.addAnimation(setFillAnimation)
        flipAnimation.addAnimation(setVariablesSequence)

        stateMachine = QStateMachine(self)
        splashState = QState(stateMachine)
        frontState = QState(stateMachine)
        historyState = QHistoryState(frontState)
        backState = QState(stateMachine)

        frontState.assignProperty(pad, "fill", False)
        frontState.assignProperty(splash, "opacity", 0.0)
        frontState.assignProperty(backItem, "visible", False)
        frontState.assignProperty(flipRotation, "angle", 0.0)
        frontState.assignProperty(selectionItem, "visible", True)

        backState.assignProperty(pad, "fill", True)
        backState.assignProperty(backItem, "visible", True)
        backState.assignProperty(xRotation, "angle", 0.0)
        backState.assignProperty(yRotation, "angle", 0.0)
        backState.assignProperty(flipRotation, "angle", 180.0)
        backState.assignProperty(selectionItem, "visible", False)

        stateMachine.addDefaultAnimation(smoothXRotation)
        stateMachine.addDefaultAnimation(smoothYRotation)
        stateMachine.addDefaultAnimation(smoothXSelection)
        stateMachine.addDefaultAnimation(smoothYSelection)
        stateMachine.setInitialState(splashState)

        anyKeyTransition = QEventTransition(self, QEvent.KeyPress, splashState)
        anyKeyTransition.setTargetState(frontState)
        anyKeyTransition.addAnimation(smoothSplashMove)
        anyKeyTransition.addAnimation(smoothSplashOpacity)

        enterTransition = QKeyEventTransition(self, QEvent.KeyPress,
                Qt.Key_Enter, backState)
        returnTransition = QKeyEventTransition(self, QEvent.KeyPress,
                Qt.Key_Return, backState)
        backEnterTransition = QKeyEventTransition(self, QEvent.KeyPress,
                Qt.Key_Enter, frontState)
        backReturnTransition = QKeyEventTransition(self, QEvent.KeyPress,
                Qt.Key_Return, frontState)
        enterTransition.setTargetState(historyState)
        returnTransition.setTargetState(historyState)
        backEnterTransition.setTargetState(backState)
        backReturnTransition.setTargetState(backState)
        enterTransition.addAnimation(flipAnimation)
        returnTransition.addAnimation(flipAnimation)
        backEnterTransition.addAnimation(flipAnimation)
        backReturnTransition.addAnimation(flipAnimation)

        columns = size.width()
        rows = size.height()
        stateGrid = []
        for y in range(rows):
            stateGrid.append([QState(frontState) for _ in range(columns)])

        frontState.setInitialState(stateGrid[0][0])
        selectionItem.setPos(pad.iconAt(0, 0).pos())

        for y in range(rows):
            for x in range(columns):
                state = stateGrid[y][x]

                rightTransition = QKeyEventTransition(self, QEvent.KeyPress,
                        Qt.Key_Right, state)
                leftTransition = QKeyEventTransition(self, QEvent.KeyPress,
                        Qt.Key_Left, state)
                downTransition = QKeyEventTransition(self, QEvent.KeyPress,
                        Qt.Key_Down, state)
                upTransition = QKeyEventTransition(self, QEvent.KeyPress,
                        Qt.Key_Up, state)

                rightTransition.setTargetState(stateGrid[y][(x + 1) % columns])
                leftTransition.setTargetState(stateGrid[y][((x - 1) + columns) % columns])
                downTransition.setTargetState(stateGrid[(y + 1) % rows][x])
                upTransition.setTargetState(stateGrid[((y - 1) + rows) % rows][x])

                icon = pad.iconAt(x, y)
                state.assignProperty(xRotation, "angle", -icon.x() / 6.0)
                state.assignProperty(yRotation, "angle", icon.y() / 6.0)
                state.assignProperty(selectionItem, "x", icon.x())
                state.assignProperty(selectionItem, "y", icon.y())
                frontState.assignProperty(icon, "visible", True)
                backState.assignProperty(icon, "visible", False)

                setIconVisibleAnimation = QPropertyAnimation(icon, b'visible')
                setIconVisibleAnimation.setDuration(0)
                setVariablesSequence.addAnimation(setIconVisibleAnimation)

        scene = QGraphicsScene(self)
        scene.setBackgroundBrush(QBrush(QPixmap(":/images/blue_angle_swirl.jpg")))
        scene.setItemIndexMethod(QGraphicsScene.NoIndex)
        scene.addItem(pad)
        scene.setSceneRect(scene.itemsBoundingRect())
        self.setScene(scene)

        sbr = splash.boundingRect()
        splash.setPos(-sbr.width() / 2, scene.sceneRect().top() - 2)
        frontState.assignProperty(splash, "y", splash.y() - 100.0)
        scene.addItem(splash)

        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setMinimumSize(50, 50)
        self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
        self.setCacheMode(QGraphicsView.CacheBackground)
        self.setRenderHints(QPainter.Antialiasing |
                QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing)

        if QGLFormat.hasOpenGL():
            self.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers)))

        stateMachine.start()
예제 #15
0
class DialogAnimation(QDialog):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 窗口透明度动画类
        self.animation = QPropertyAnimation(self, b'windowOpacity')
        self.animation.setDuration(600)  # 持续时间1秒

    def doFadeShow(self):
        try:
            # 尝试先取消动画完成后关闭窗口的信号
            self.animation.finished.disconnect(self.close)
        except Exception as e:
            if str(e) != "disconnect() failed between 'finished' and 'close'":
                print(str(e))
        self.animation.stop()
        # 透明度范围从0逐渐增加到1
        self.animation.setStartValue(0)
        self.animation.setEndValue(1)
        self.animation.start()

    def doFadeClose(self):
        self.animation.stop()
        self.animation.finished.connect(self.close)  # 动画完成则关闭窗口
        # 透明度范围从1逐渐减少到0
        self.animation.setStartValue(1)
        self.animation.setEndValue(0)
        self.animation.start()

    def doShake(self):
        self.doShakeWindow(self)

    # 下面这个方法可以做成这样的封装给任何控件
    def doShakeWindow(self, target):
        """窗口抖动动画
        :param target:        目标控件
        """
        if hasattr(target, '_shake_animation'):
            # 如果已经有该对象则跳过
            return

        animation = QPropertyAnimation(target, b'pos', target)
        target._shake_animation = animation
        animation.finished.connect(lambda: delattr(target, '_shake_animation'))

        pos = target.pos()
        x, y = pos.x(), pos.y()

        animation.setDuration(100)  # 持续时间1秒
        animation.setLoopCount(2)
        animation.setKeyValueAt(0, QPoint(x, y))
        animation.setKeyValueAt(0.09, QPoint(x + 2, y - 2))
        animation.setKeyValueAt(0.18, QPoint(x + 4, y - 4))
        animation.setKeyValueAt(0.27, QPoint(x + 2, y - 6))
        animation.setKeyValueAt(0.36, QPoint(x + 0, y - 8))
        animation.setKeyValueAt(0.45, QPoint(x - 2, y - 10))
        animation.setKeyValueAt(0.54, QPoint(x - 4, y - 8))
        animation.setKeyValueAt(0.63, QPoint(x - 6, y - 6))
        animation.setKeyValueAt(0.72, QPoint(x - 8, y - 4))
        animation.setKeyValueAt(0.81, QPoint(x - 6, y - 2))
        animation.setKeyValueAt(0.90, QPoint(x - 4, y - 0))
        animation.setKeyValueAt(0.99, QPoint(x - 2, y + 2))
        animation.setEndValue(QPoint(x, y))

        animation.start(animation.DeleteWhenStopped)

    def exec_(self):
        # 执行淡入
        self.doFadeShow()
        super().exec_()
예제 #16
0
class Preferences(QDialog):
    # Signal to warn that the window is closed
    settingsClosed = pyqtSignal()

    def __init__(self, parent=None):
        super(Preferences, self).__init__(parent)

        # Main container
        # This contains a grid
        main_box = QVBoxLayout(self)
        main_box.setContentsMargins(200, 50, 200, 100)

        # The grid contains two containers
        # left container and right container
        grid = QGridLayout()

        # Left Container
        left_container = QVBoxLayout()
        left_container.setContentsMargins(0, 0, 0, 0)

        # General
        group_gral = QGroupBox(self.tr("General"))
        box_gral = QVBoxLayout(group_gral)
        # Updates
        btn_updates = QPushButton(self.tr("Check for updates"))
        box_gral.addWidget(btn_updates)
        # Language
        group_language = QGroupBox(self.tr("Language"))
        box = QVBoxLayout(group_language)
        # Find .qm files in language path
        available_langs = file_manager.get_files_from_folder(
            settings.LANGUAGE_PATH)

        languages = ["English"] + available_langs
        self._combo_lang = QComboBox()
        box.addWidget(self._combo_lang)
        self._combo_lang.addItems(languages)
        self._combo_lang.currentIndexChanged[int].connect(
            self._change_lang)
        if PSetting.LANGUAGE:
            self._combo_lang.setCurrentText(PSetting.LANGUAGE)
        box.addWidget(QLabel(self.tr("(Requires restart)")))

        # Add widgets
        left_container.addWidget(group_gral)
        left_container.addWidget(group_language)
        left_container.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding,
                                           QSizePolicy.Expanding))

        # Right Container
        right_container = QVBoxLayout()
        right_container.setContentsMargins(0, 0, 0, 0)

        # Editor
        editor_group = QGroupBox(self.tr("Editor Configurations"))
        box_editor = QHBoxLayout(editor_group)
        # Current line
        self._highlight_current_line = QCheckBox(
            self.tr("Highlight Current Line"))
        self._highlight_current_line.setChecked(
            PSetting.HIGHLIGHT_CURRENT_LINE)
        self._highlight_current_line.stateChanged[int].connect(
            self.__current_line_value_changed)
        box_editor.addWidget(self._highlight_current_line)
        # Matching paren
        self._matching_paren = QCheckBox(self.tr("Matching Parenthesis"))
        self._matching_paren.setChecked(
            PSetting.MATCHING_PARENTHESIS)
        self._matching_paren.stateChanged[int].connect(
            self.__set_enabled_matching_parenthesis)
        box_editor.addWidget(self._matching_paren)
        # Font group
        font_group = QGroupBox(self.tr("Font"))
        font_grid = QGridLayout(font_group)
        font_grid.addWidget(QLabel(self.tr("Family")), 0, 0)
        self._combo_font = QFontComboBox()
        self._combo_font.setCurrentFont(PSetting.FONT)
        font_grid.addWidget(self._combo_font, 0, 1)
        font_grid.addWidget(QLabel(self.tr("Point Size")), 1, 0)
        self._combo_font_size = QComboBox()
        fdb = QFontDatabase()
        combo_sizes = fdb.pointSizes(PSetting.FONT.family())
        current_size_index = combo_sizes.index(
            PSetting.FONT.pointSize())

        self._combo_font_size.addItems([str(f) for f in combo_sizes])
        self._combo_font_size.setCurrentIndex(current_size_index)
        font_grid.addWidget(self._combo_font_size, 1, 1)

        right_container.addWidget(editor_group)
        right_container.addWidget(font_group)
        right_container.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding,
                                            QSizePolicy.Expanding))

        # Add widgets
        grid.addLayout(left_container, 0, 0)
        grid.addLayout(right_container, 0, 1)
        main_box.addLayout(grid)

        # Button close and reset
        hbox = QHBoxLayout()
        hbox.setSpacing(20)
        hbox.addItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        btn_cancel = QPushButton(self.tr("Back"))
        hbox.addWidget(btn_cancel)
        btn_reset = QPushButton(self.tr("Reset Configurations"))
        hbox.addWidget(btn_reset)
        main_box.addLayout(hbox)

        # Overlay
        self.overlay = overlay_widget.OverlayWidget(self)
        self.overlay.hide()

        # Effect and animations
        self.effect = QGraphicsOpacityEffect()
        self.setGraphicsEffect(self.effect)
        duration, x = 180, 150  # Animation duration
        # Animation start
        # Opacity animation
        self.opacity_animation_s = QPropertyAnimation(self.effect, b"opacity")
        self.opacity_animation_s.setDuration(duration)
        self.opacity_animation_s.setStartValue(0.0)
        self.opacity_animation_s.setEndValue(1.0)
        # X animation
        self.x_animation_s = QPropertyAnimation(self, b"geometry")
        self.x_animation_s.setDuration(duration)
        self.x_animation_s.setStartValue(QRect(x, 0, parent.width(),
                                               parent.height()))
        self.x_animation_s.setEndValue(QRect(0, 0, parent.width(),
                                             parent.height()))
        # Animation end
        # Opacity animation
        self.opacity_animation_e = QPropertyAnimation(self.effect, b"opacity")
        self.opacity_animation_e.setDuration(duration)
        self.opacity_animation_e.setStartValue(1.0)
        self.opacity_animation_e.setEndValue(0.0)
        # X animation
        self.x_animation_e = QPropertyAnimation(self, b"geometry")
        self.x_animation_e.setDuration(duration)
        self.x_animation_e.setStartValue(QRect(0, 0, parent.width(),
                                               parent.height()))
        self.x_animation_e.setEndValue(QRect(-x, 0, parent.width(),
                                             parent.height()))

        # Group animation start
        self.group_animation_s = QParallelAnimationGroup()
        self.group_animation_s.addAnimation(self.opacity_animation_s)
        self.group_animation_s.addAnimation(self.x_animation_s)

        # Group animation end
        self.group_animation_e = QParallelAnimationGroup()
        self.group_animation_e.addAnimation(self.opacity_animation_e)
        self.group_animation_e.addAnimation(self.x_animation_e)

        # Connections
        self.group_animation_e.finished.connect(
            self._on_group_animation_finished)
        btn_cancel.clicked.connect(self.close)
        btn_reset.clicked.connect(self._reset_settings)
        btn_updates.clicked.connect(self._check_for_updates)
        # self.thread.finished.connect(self._on_thread_finished)
        self._combo_font.currentFontChanged.connect(
            self._change_font)
        self._combo_font_size.currentTextChanged.connect(
            self._change_font_size)

    def __current_line_value_changed(self, value):
        qs = QSettings(settings.SETTINGS_PATH, QSettings.IniFormat)
        qs.setValue('highlight_current_line', value)
        PSetting.HIGHLIGHT_CURRENT_LINE = value

    def __set_enabled_matching_parenthesis(self, value):
        qs = QSettings(settings.SETTINGS_PATH, QSettings.IniFormat)
        qs.setValue("matching_parenthesis", value)
        PSetting.MATCHING_PARENTHESIS = value

    def _change_font(self, font):
        # FIXME: un quilombo esto
        central = Pireal.get_service("central")
        mcontainer = central.get_active_db()
        if mcontainer is not None:
            query_widget = mcontainer.query_container.currentWidget()
            if query_widget is not None:
                weditor = query_widget.get_editor()
                if weditor is not None:
                    qs = QSettings(settings.SETTINGS_PATH, QSettings.IniFormat)
                    weditor.set_font(font)
                    qs.setValue("font", font)

    def _change_font_size(self, size):
        # FIXME: un quilombo esto
        font = self._combo_font.currentFont()
        font.setPointSize(int(size))
        central = Pireal.get_service("central")
        mcontainer = central.get_active_db()
        if mcontainer is not None:
            query_widget = mcontainer.query_container.currentWidget()
            if query_widget is not None:
                weditor = query_widget.get_editor()
                if weditor is not None:
                    qs = QSettings(settings.SETTINGS_PATH, QSettings.IniFormat)
                    weditor.set_font(font)
                    qs.setValue("font", font)

    def showEvent(self, event):
        super(Preferences, self).showEvent(event)
        self.group_animation_s.start()

    def resizeEvent(self, event):
        self.overlay.resize(self.size())
        event.accept()

    def done(self, result):
        self.res = result
        self.group_animation_e.start()

    def _on_group_animation_finished(self):
        super(Preferences, self).done(self.res)
        self.settingsClosed.emit()

    def _check_for_updates(self):
        # Thread
        self._thread = QThread()
        self._updater = updater.Updater()
        self._updater.moveToThread(self._thread)
        self._thread.started.connect(self._updater.check_updates)
        self._updater.finished.connect(self.__on_thread_update_finished)
        # Show overlay widget
        self.overlay.show()
        # Start thread
        self._thread.start()

    def __on_thread_update_finished(self):
        # Hide overlay widget
        self.overlay.hide()
        self._thread.quit()
        msg = QMessageBox(self)
        if not self._updater.error:
            if self._updater.version:
                version = self._updater.version
                msg.setWindowTitle(self.tr("New version available!"))
                msg.setText(self.tr("Check the web site to "
                                    "download <b>Pireal {}</b>".format(
                                        version)))
                download_btn = msg.addButton(self.tr("Download!"),
                                             QMessageBox.YesRole)
                msg.addButton(self.tr("Cancel"),
                              QMessageBox.RejectRole)
                msg.exec_()
                r = msg.clickedButton()
                if r == download_btn:
                    webbrowser.open_new(
                        "http://centaurialpha.github.io/pireal")
            else:
                msg.setWindowTitle(self.tr("Information"))
                msg.setText(self.tr("Last version installed"))
                msg.addButton(self.tr("Ok"),
                              QMessageBox.AcceptRole)
                msg.exec_()
        else:
            msg.critical(self, self.tr("Error"),
                         self.tr("Connection error"))

        self._thread.deleteLater()
        self._updater.deleteLater()

    def _reset_settings(self):
        """ Remove all settings """

        msg = QMessageBox(self)
        msg.setWindowTitle(self.tr("Reset Settings"))
        msg.setText(self.tr("Are you sure you want to clear all settings?"))
        msg.setIcon(QMessageBox.Question)
        msg.addButton(self.tr("No"), QMessageBox.NoRole)
        yes_btn = msg.addButton(self.tr("Yes"),
                                QMessageBox.YesRole)
        msg.exec_()
        r = msg.clickedButton()
        if r == yes_btn:
            QSettings(settings.SETTINGS_PATH, QSettings.IniFormat).clear()
            self.close()

    def _change_lang(self, index):
        lang = self._combo_lang.itemText(index)
        qs = QSettings(settings.SETTINGS_PATH, QSettings.IniFormat)
        qs.setValue('language', lang)
예제 #17
0
    view.setWindowTitle("Animated Tiles")
    view.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
    view.setBackgroundBrush(QBrush(bgPix))
    view.setCacheMode(QGraphicsView.CacheBackground)
    view.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
    view.show()

    states = QStateMachine()
    states.addState(rootState)
    states.setInitialState(rootState)
    rootState.setInitialState(centeredState)

    group = QParallelAnimationGroup()
    for i, item in enumerate(items):
        anim = QPropertyAnimation(item, b'pos')
        anim.setDuration(750 + i * 25)
        anim.setEasingCurve(QEasingCurve.InOutBack)
        group.addAnimation(anim)

    trans = rootState.addTransition(ellipseButton.pressed, ellipseState)
    trans.addAnimation(group)

    trans = rootState.addTransition(figure8Button.pressed, figure8State)
    trans.addAnimation(group)

    trans = rootState.addTransition(randomButton.pressed, randomState)
    trans.addAnimation(group)

    trans = rootState.addTransition(tiledButton.pressed, tiledState)
    trans.addAnimation(group)
예제 #18
0
class AdvancedAppWidget:
    _translate = QCoreApplication.translate
    template = 'AdvancedAppWidget'
    animation: QPropertyAnimation
    tags: QComboBox

    def __init__(self, parent, container: Container) -> None:
        self.container = container
        self.ui = AdvancedAppWidgetUi(parent, container)
        self.drawShortcuts()
        containers_service.listen(self.container, 'tag_index',
                                  self.listenTagChange)
        containers_service.listen(self.container,
                                  SHORTCUT_CONF_CHANGED_CHANNEL,
                                  self.redrawShortcuts)
        if not container.expanded:
            self.ui.setMaximumHeight(0)
        self.ui.resizeEvent = self.resize

    def onImageTagChange(self, full_tag_name):
        if not full_tag_name:
            return
        tag = full_tag_name.split(':')[1]
        previous_val = self.container.tag
        self.container.tag = tag
        self.container.save()
        auditing_service.audit_update(self.container,
                                      self.container.tableName(),
                                      self.container.id, "tag", previous_val,
                                      tag)

    def onAdvancedConfigurationClicked(self):
        app_config = AppConfig(None, self.container)
        app_config.show()

    def onCollapsed(self):
        self.container.expanded = False
        self.container.save()

    def onExpanded(self):
        self.container.expanded = True
        self.container.save()
        self.ui.setMaximumHeight(99999)

    def toggleWindow(self):
        self.animation = QPropertyAnimation(self.ui, b"maximumHeight")
        self.animation.setDuration(200)
        try:
            self.animation.finished.disconnect()
        except TypeError:
            pass
        if self.ui.maximumHeight() == 0:
            self.animation.setStartValue(0)
            self.animation.setEndValue(self.ui.layout.sizeHint().height())
            self.animation.finished.connect(self.onExpanded)
        else:
            self.animation.setStartValue(self.ui.layout.sizeHint().height())
            self.animation.setEndValue(0)
            self.animation.finished.connect(self.onCollapsed)
        self.animation.start()

    def findFileOrFolder(self, shotcut: PreferencesShortcut,
                         input_box: PathViewWidget):
        if shotcut.pref_type == 'File':
            fname = QFileDialog.getOpenFileName(self.ui, 'Open file')
            path = fname[0] if fname[0] else ''
        else:
            file = str(
                QFileDialog.getExistingDirectory(self.ui, "Select Directory"))
            path = file if file else ''
        if path:
            input_box.setPath(path, shotcut.pref_type.lower())
            input_box.resizePaths()
            self.setShortcutValue(shotcut, path)

    def drawShortcut(self, shortcut: PreferencesShortcut, row):
        label = QLabel(self.ui.widget)
        label.setText(self._translate(self.template, shortcut.label) + ':')
        label.setToolTip(shortcut.description)
        self.ui.grid_layout.addWidget(label, row, 0, 1, 1)
        if shortcut.pref_type in ['File', 'Folder']:
            input_box = PathViewWidget(self.ui.widget)
            input_box.setPath(shortcut.default_value,
                              shortcut.pref_type.lower())
            self.ui.grid_layout.addWidget(input_box, row, 1, 1, 2)
            finder = QPushButton(self.ui.widget)
            finder.setText(' ... ')
            finder.setFlat(True)
            finder.setStyleSheet(
                "border: 1px solid #999999; padding: 0px 4px; border-radius: 2px"
            )
            finder.setMaximumWidth(rt(25))
            finder.clicked.connect(
                lambda x: self.findFileOrFolder(shortcut, input_box))
            self.ui.grid_layout.addWidget(finder, row, 3, 1, 2)
        else:
            input_box = QLineEdit(self.ui.widget)
            input_box.setText(shortcut.default_value)
            input_box.textChanged.connect(
                lambda x: self.setShortcutValue(shortcut, x))
            input_box.setStyleSheet(
                'border: none; background-color: transparent')
            input_box.setReadOnly(shortcut.shortcut == 'Constant')
            self.ui.grid_layout.addWidget(input_box, row, 1, 1, 2)
            hidden_widget = QWidget(self.ui.widget)
            hidden_widget.setSizePolicy(BQSizePolicy(h_stretch=1))
            self.ui.grid_layout.addWidget(hidden_widget, row, 3, 1, 2)

    def drawTagShortcut(self, row):
        label = QLabel(self.ui.widget)
        self.ui.grid_layout.addWidget(label, row, 0, 1, 1)
        self.tags = QComboBox(self.ui.widget)
        self.tags.setSizePolicy(
            BQSizePolicy(h_stretch=4,
                         height=QSizePolicy.Fixed,
                         width=QSizePolicy.Fixed))
        self.ui.grid_layout.addWidget(self.tags, row, 1, 1, 2)
        hidden_widget = QWidget(self.ui.widget)
        hidden_widget.setSizePolicy(BQSizePolicy(h_stretch=1))
        self.ui.grid_layout.addWidget(hidden_widget, row, 3, 1, 2)

        for index, tag in enumerate(tags_service.getTags(self.container)):
            self.tags.addItem(self.container.image_name + ":" + tag.name)
            if tag.name == self.container.tag:
                self.tags.setCurrentIndex(index)
        self.tags.currentTextChanged.connect(self.onImageTagChange)
        label.setText(self._translate(self.template, "Image tag:"))

    def drawShortcuts(self):
        shortcuts = shortcut_service.getEnabledShortcuts(self.container)
        for index, shortcut in enumerate(shortcuts):
            self.drawShortcut(shortcut, index)
        self.drawTagShortcut(len(shortcuts))

    def cleanShortcuts(self):
        while self.ui.grid_layout.count():
            item = self.ui.grid_layout.takeAt(0)
            item.widget().deleteLater()

    def redrawShortcuts(self):
        self.cleanShortcuts()
        self.drawShortcuts()

    def listenTagChange(self, index):
        self.tags.setCurrentIndex(index)

    def setShortcutValue(self, shortcut: PreferencesShortcut, value):
        previous_val = shortcut.default_value
        shortcut.default_value = value
        shortcut.save()
        auditing_service.audit_update(self.container, shortcut.tableName(),
                                      shortcut.id, "default_value",
                                      previous_val, value)

    def resize(self, event: QResizeEvent):
        if self.tags:
            self.tags.setFixedWidth(event.size().width() * 2 / 3)
        QWidget.resizeEvent(self.ui, event)
예제 #19
0
class Attr(WizardWidget):

    drag_label = "Attribute <attr>"
    acceptable_tags = ["attr"]

    def __init__(self, parent=None):
        # This changes to true when this attribute is being viewed/edited
        self.active = False
        self.ef = 0

        self.nodata = None
        self.nodata_content = (False, None)  # nodata checked, last nodata node

        WizardWidget.__init__(self, parent=parent)

        # an in memory record of all  the contents that were selected
        self._previous_index = -1
        cbo = self.ui.comboBox
        self._domain_content = dict.fromkeys(range(cbo.count()), None)

        self.parent_ui = parent
        self.series = None
        self.ui.nodata_section.hide()
        self.highlighter = Highlighter(self.ui.fgdc_attrdef.document())

        self.nodata_matches = [
            "#N/A",
            "#N/A N/A",
            "#NA",
            "-1.#IND",
            "-1.#QNAN",
            "-NaN",
            "-nan",
            "1.#IND",
            "1.#QNAN",
            "N/A",
            "NA",
            "NULL",
            "NaN",
            "n/a",
            "nan",
            "null",
            -9999,
            "-9999",
            "",
            "Nan",
            "<< empty cell >>",
        ]

    def build_ui(self):
        """
        Build and modify this widget's GUI
        Returns
        -------
        None
        """
        self.ui = UI_attr.Ui_attribute_widget()
        self.ui.setupUi(self)

        # self.ui.fgdc_attrdef.installEventFilter(self)
        self.ui.fgdc_attrdef.setMouseTracking(True)
        self.ui.fgdc_attrdefs.installEventFilter(self)
        self.ui.attrdomv_contents.installEventFilter(self)
        self.ui.place_holder.installEventFilter(self)

        self.setup_dragdrop(self)
        self.ui.comboBox.currentIndexChanged.connect(self.change_domain)
        self.ui.fgdc_attr.mousePressEvent = self.mousePressEvent
        self.ui.fgdc_attrlabl.mousePressEvent = self.attrlabl_press
        self.ui.fgdc_attrdef.mousePressEvent = self.attrdef_press
        self.ui.fgdc_attrdefs.mousePressEvent = self.attrdefs_press
        self.ui.comboBox.mousePressEvent = self.combo_press
        self.ui.rbtn_nodata_yes.toggled.connect(self.include_nodata_change)

        self.domain = None
        self.ui.nodata_content.hide()
        self.ui.rbtn_nodata_no.setChecked(True)
        self.ui.comboBox.setCurrentIndex(3)

        self.ui.fgdc_attrdefs.setText(default_def_source)

    def include_nodata_change(self, b):
        """
            The user has changed the nodata present selection

            Parameters
            ----------
            b: qt event

            Returns
            -------
            None
            """
        if b:
            self.ui.nodata_section.show()
        else:
            self.ui.nodata_section.hide()

    def mousePressEvent(self, event):
        self.activate()

    def attrlabl_press(self, event):
        self.activate()
        return QLineEdit.mousePressEvent(self.ui.fgdc_attrlabl, event)

    def attrdef_press(self, event):
        self.activate()
        return QPlainTextEdit.mousePressEvent(self.ui.fgdc_attrdef, event)

    def attrdefs_press(self, event):
        self.activate()
        return QLineEdit.mousePressEvent(self.ui.fgdc_attrdefs, event)

    def combo_press(self, event):
        self.activate()
        return QComboBox.mousePressEvent(self.ui.comboBox, event)

    def clear_domain(self):
        for child in self.ui.attrdomv_contents.children():
            if isinstance(child, QWidget):
                child.deleteLater()

    def clear_nodata(self):
        try:
            self.nodata_edom.deleteLater()
        except:
            pass

    def set_series(self, series):
        """
        store a series with this attri
        Parameters
        ----------
        series : pandas series

        Returns
        -------
        None
        """
        self.series = series

    def guess_domain(self):
        """
        return the index of the domain the associated series is thought to
        best match.

        if there are less than twenty unique items in the series the guess
        is enumerated
        if it's numeric the guess is range.
        else it's unrepresentable

        Returns
        -------
        int : index of the domain the associated series is
            thought to best match
        """
        # given a series of data take a guess as to which
        # domain type is appropriate

        if self.series is not None:
            if self.nodata is not None:
                clean_series = data_io.clean_nodata(self.series, self.nodata)
            else:
                clean_series = self.series

            uniques = clean_series.unique()
            if np.issubdtype(clean_series.dtype, np.number):
                return 1  # range
            elif len(uniques) < 20:
                return 0  # enumerated
            else:
                return 3  # unrepresentable

        # without a series to introspect we're going to default to udom
        return 3  # unrepresentable

    def store_current_content(self):
        """
        Save the current contents (xml format) into our domain contents dict

        Returns
        -------
        None
        """
        if self.domain is not None and not sip.isdeleted(self.domain):
            cur_xml = self.domain.to_xml()
            if cur_xml.tag == "udom":
                self._domain_content[3] = cur_xml
            elif cur_xml.tag == "codesetd":
                self._domain_content[2] = cur_xml
            elif cur_xml.tag == "rdom":
                self._domain_content[1] = cur_xml
            elif cur_xml.tag == "attr":
                self._domain_content[0] = cur_xml

        if self.ui.rbtn_nodata_yes.isChecked() and not sip.isdeleted(self.nodata_edom):
            self.nodata_content = (True, self.nodata_edom.to_xml())
        else:
            self.nodata_content = (False, None)

    def populate_domain_content(self, which="guess"):
        """
        Fill out this widget with the content from it's associated series

        Parameters
        ----------
        which : str, optional, one of 'guess' or the index to force
            if guess introspect the series associated with this attribute
            and make a best guess as to which domain to use.

        Returns
        -------
        None
        """
        self.clear_domain()

        if which == "guess":
            self.sniff_nodata()
            index = self.guess_domain()
        else:
            index = which

        self.ui.comboBox.setCurrentIndex(index)

        if index == 0:
            self.domain = edom_list.EdomList(parent=self)
        elif index == 1:
            self.domain = rdom.Rdom(parent=self)
        elif index == 2:
            self.domain = codesetd.Codesetd(parent=self)
        else:
            self.domain = udom.Udom(parent=self)

        if self._domain_content[index] is not None:
            # This domain has been used before, display previous content
            self.domain.from_xml(self._domain_content[index])
        elif self.series is not None and index == 0:
            clean_series = data_io.clean_nodata(self.series, self.nodata)
            uniques = clean_series.unique()

            if len(uniques) > 100:
                msg = "There are more than 100 unique values in this field."
                msg += "\n This tool cannot smoothly display that many " "entries. "
                msg += (
                    "\nTypically an enumerated domain is not used with "
                    "that many unique entries."
                )
                msg += "\n\nOnly the first one hundred are displayed below!"
                msg += (
                    "\nYou will likely want to change the domain to one "
                    "of the other options."
                )
                QMessageBox.warning(self, "Too many unique entries", msg)
                self.domain.populate_from_list(uniques[:101])
            else:
                self.domain.populate_from_list(uniques)
        elif self.series is not None and index == 1:
            clean_series = data_io.clean_nodata(self.series, self.nodata)
            try:
                self.domain.ui.fgdc_rdommin.setText(str(clean_series.min()))
            except:
                self.domain.ui.fgdc_rdommin.setText("")
            try:
                self.domain.ui.fgdc_rdommax.setText(str(clean_series.max()))
            except:
                self.domain.ui.fgdc_rdommax.setText("")

            if not np.issubdtype(clean_series.dtype, np.number):
                msg = (
                    "Caution! The contents of this column are stored in the"
                    ' data source as "text".  The use of a range domain '
                    "type on text columns might give unexpected results, "
                    "especially for columns that contain date information."
                )
                msgbox = QMessageBox(
                    QMessageBox.Warning, "Range domain on text field", msg
                )
                utils.set_window_icon(msgbox)
                msgbox.exec_()
        self.ui.attrdomv_contents.layout().addWidget(self.domain)

    def change_domain(self):
        """
        When changing the domain we must first store the current contents
        in our internal contents dictionary before loading the next.

        Returns
        -------
        None
        """
        if self.active:
            self.store_current_content()
            self.clear_domain()

            self.populate_domain_content(self.ui.comboBox.currentIndex())

    def supersize_me(self):
        """
        Expand this attribute and display it's contents

        Returns
        -------
        None
        """
        if not self.active:
            self.active = True
            self.animation = QPropertyAnimation(self, b"minimumSize")
            self.animation.setDuration(200)
            self.animation.setEndValue(QSize(345, self.height()))
            self.animation.start()
            self.ui.attrdomv_contents.show()
            self.ui.place_holder.hide()
            cbo = self.ui.comboBox
            self.populate_domain_content(cbo.currentIndex())

            self.ui.nodata_content.show()
            self.nodata_edom = edom.Edom()
            self.ui.rbtn_nodata_yes.setChecked(self.nodata_content[0])
            if self.nodata_content[1] is not None:
                self.nodata_edom.from_xml(self.nodata_content[1])

            self.nodata_edom.ui.fgdc_edomv.textChanged.connect(self.nodata_changed)
            self.ui.nodata_section.layout().addWidget(self.nodata_edom)

    def regularsize_me(self):
        """
        Collapse this attribute and hide it's content

        Returns
        -------
        None
        """
        if self.active:
            self.store_current_content()
            self.animation = QPropertyAnimation(self, b"minimumSize")
            self.animation.setDuration(200)
            self.animation.setEndValue(QSize(100, self.height()))
            self.animation.start()
            self.ui.nodata_content.hide()
            self.clear_domain()
            self.clear_nodata()
            self.ui.place_holder.show()

        self.active = False

    def activate(self):
        """
        When an attribute is activated minimize all the other attributes
        in the parent attribute list

        Returns
        -------
        None
        """
        if self.active:
            # we're already big so do nothing
            pass
        else:
            if self.parent_ui is not None:
                self.parent_ui.minimize_children()
            self.supersize_me()

    def nodata_changed(self):
        """remove """
        self.nodata = self.nodata_edom.ui.fgdc_edomv.text()
        if self.nodata == "<< empty cell >>":
            self.nodata = ""
        self.clean_domain_nodata()

    def clean_domain_nodata(self):
        if self.domain is not None and not sip.isdeleted(self.domain):
            cur_xml = self.domain.to_xml()
            if cur_xml.tag == "rdom":
                self._domain_content[1] = cur_xml
            elif cur_xml.tag == "attr":
                edoms = self.domain.edoms
                self._domain_content[0] = cur_xml

    def sniff_nodata(self):
        uniques = self.series.unique()

        self.nodata = None
        for nd in self.nodata_matches:
            if nd in list(uniques):
                self.nodata = nd

        if self.nodata is None:
            self.nodata_content = (False, self.nodata_content[1])
        else:
            temp_edom = edom.Edom()
            if self.nodata == "":
                temp_edom.ui.fgdc_edomv.setText("<< empty cell >>")
            else:
                temp_edom.ui.fgdc_edomv.setText(str(self.nodata))

            temp_edom.ui.fgdc_edomvd.setPlainText("No Data")
            self.nodata_content = (True, temp_edom.to_xml())
            temp_edom.deleteLater()

    def contextMenuEvent(self, event):

        self.in_context = True
        clicked_widget = self.childAt(event.pos())

        menu = QMenu(self)
        copy_action = menu.addAction(QIcon("copy.png"), "&Copy")
        copy_action.setStatusTip("Copy to the Clipboard")

        paste_action = menu.addAction(QIcon("paste.png"), "&Paste")
        paste_action.setStatusTip("Paste from the Clipboard")

        menu.addSeparator()
        insert_before = menu.addAction(QIcon("paste.png"), "Insert before")
        insert_before.setStatusTip(
            "insert an empty attribute (column) " "before this one"
        )

        insert_after = menu.addAction(QIcon("paste.png"), "Insert After")
        insert_after.setStatusTip(
            "insert an empty attribute (column) after" " this one"
        )

        delete_action = menu.addAction(QIcon("delete.png"), "&Delete")
        delete_action.setStatusTip("Delete this atttribute (column)")

        if hasattr(clicked_widget, "help_text") and clicked_widget.help_text:
            menu.addSeparator()
            help_action = menu.addAction("Help")
        else:
            help_action = None

        menu.addSeparator()
        clear_action = menu.addAction("Clear content")

        action = menu.exec_(self.mapToGlobal(event.pos()))

        if action == copy_action:
            if clicked_widget is None:
                pass
            elif clicked_widget.objectName() == "idinfo_button":
                self.idinfo.copy_mime()
            elif clicked_widget.objectName() == "dataquality_button":
                self.dataqual.copy_mime()
            elif clicked_widget.objectName() == "eainfo_button":
                self.eainfo.copy_mime()
            elif clicked_widget.objectName() == "distinfo_button":
                self.distinfo.copy_mime()
            elif clicked_widget.objectName() == "metainfo_button":
                self.metainfo.copy_mime()
            else:
                self.copy_mime()
        elif action == paste_action:
            self.paste_mime()
        elif action == clear_action:
            if clicked_widget is None:
                self.clear_widget()
            elif clicked_widget.objectName() == "idinfo_button":
                self.idinfo.clear_widget()
            elif clicked_widget.objectName() == "dataquality_button":
                self.dataqual.clear_widget()
            elif clicked_widget.objectName() == "eainfo_button":
                self.eainfo.clear_widget()
            elif clicked_widget.objectName() == "distinfo_button":
                self.distinfo.clear_widget()
            elif clicked_widget.objectName() == "metainfo_button":
                self.metainfo.clear_widget()
            else:
                self.clear_widget()
        elif action == insert_before:
            self.parent_ui.insert_before(self)
        elif action == insert_after:
            self.parent_ui.insert_after(self)
        elif action == delete_action:
            self.parent_ui.delete_attr(self)
        elif help_action is not None and action == help_action:
            msg = QMessageBox(self)
            # msg.setTextFormat(Qt.RichText)
            msg.setText(clicked_widget.help_text)
            msg.setWindowTitle("Help")
            msg.show()
        self.in_context = False

    def to_xml(self):
        """
        return an XML element with the contents of this widget,
        augmented with any original content not displayed on the widget
        if applicable.

        Returns
        -------
        XML Element
        """
        cur_index = self.ui.comboBox.currentIndex()

        if self.active:
            self.store_current_content()
            domain = self.domain.to_xml()
        elif self._domain_content[cur_index] is not None:
            domain = self._domain_content[cur_index]
        else:
            self.populate_domain_content(cur_index)
            domain = self.domain.to_xml()

        if self.ui.comboBox.currentIndex() == 0:
            attr = xml_utils.XMLNode(domain)
            attr.clear_children(tag="attrlabl")
            attr.clear_children(tag="attrdef")
            attr.clear_children(tag="attrdefs")
            attr = attr.to_xml()
        else:
            attr = xml_utils.xml_node("attr")
            attrdomv = xml_utils.xml_node("attrdomv", parent_node=attr)
            attrdomv.append(domain)

        attrlabl = xml_utils.xml_node(
            "attrlabl", text=self.ui.fgdc_attrlabl.text(), parent_node=attr, index=0
        )
        attrdef = xml_utils.xml_node(
            "attrdef",
            text=self.ui.fgdc_attrdef.toPlainText(),
            parent_node=attr,
            index=1,
        )
        attrdefs = xml_utils.xml_node(
            "attrdefs", text=self.ui.fgdc_attrdefs.text(), parent_node=attr, index=2
        )

        if self.nodata_content[0]:
            attrdomv = xml_utils.xml_node("attrdomv", parent_node=attr, index=3)
            attrdomv.append(self.nodata_content[1])


        return attr

    def from_xml(self, attr):
        """
        Populate widget with a representation of the passed XML element

        Parameters
        ----------
        attr : XML Element

        Returns
        -------
        None
        """
        try:
            self.clear_widget()
            if attr.tag == "attr":

                utils.populate_widget(self, attr)
                attr_node = xml_utils.XMLNode(attr)
                attrdomvs = attr_node.xpath("attrdomv", as_list=True)
                attr_domains = [a.children[0].tag for a in attrdomvs]

                # pull out the first no data attribute domain
                for attrdomv in attrdomvs:
                    if attrdomv.children[0].tag == "edom" and (
                        attrdomv.children[0].children[0].text in self.nodata_matches
                        or attrdomv.children[0].children[1].text.lower()
                        in ["nodata", "no data"]
                        or (attr_domains.count("edom") == 1)
                        and len(attr_domains) > 1
                    ):
                        self.ui.rbtn_nodata_yes.setChecked(True)
                        self.nodata_content = (1, attrdomv.children[0].to_xml())
                        attrdomvs.remove(attrdomv)
                        attr_domains.remove("edom")
                        try:
                            edomv = attr.xpath(
                                "attrdomv/edom/edomv[text()='{}']".format(
                                    attrdomv.children[0].children[0].text
                                )
                            )[0]
                            nd_attrdomv = edomv.getparent().getparent()
                            nd_attrdomv.getparent().remove(nd_attrdomv)
                        except:
                            pass
                        break

                if len(set(attr_domains)) > 1:
                    # multiple domain types present in this attr
                    msg = "Multiple domain types found in the attribute/column '{}'."
                    msg += "\ni.e. more than one of Enumerated, Range, "
                    msg += "Codeset, and Unrepresentable was used to "
                    msg += "was used to describe a single column.\n\n"
                    msg += "While this is valid in the FGDC schema the "
                    msg += "MetadataWizard is not designed to handle this."
                    msg += "\n\nOnly the first of these domains will be displayed "
                    msg += "and retained in the output saved from this tool."
                    msg += "\n\nIf having this structure is import please use"
                    msg += " a different tool for editing this section."
                    msg = msg.format(self.ui.fgdc_attrlabl.text())
                    msgbox = QMessageBox(
                        QMessageBox.Warning, "Too many domain types", msg
                    )
                    utils.set_window_icon(msgbox)
                    msgbox.exec_()

                if len(attrdomvs) == 0:
                    self.ui.comboBox.setCurrentIndex(3)
                elif attr_domains[0] == "edom":
                    self.ui.comboBox.setCurrentIndex(0)
                    self._domain_content[0] = attr
                elif attr_domains[0] == "udom":
                    self.ui.comboBox.setCurrentIndex(3)
                    self._domain_content[3] = attr.xpath("attrdomv/udom")[0]
                elif attr_domains[0] == "rdom":
                    self.ui.comboBox.setCurrentIndex(1)
                    self._domain_content[1] = attr.xpath("attrdomv/rdom")[0]
                elif attr_domains[0] == "codesetd":
                    self.ui.comboBox.setCurrentIndex(2)
                    self._domain_content[2] = attr.xpath("attrdomv/codesetd")[0]
                else:
                    self.ui.comboBox.setCurrentIndex(3)
            else:
                print("The tag is not attr")
        except KeyError:
            pass
class ToolDialogFrame:

    def __init__(self, containers: QFrame, page_containers_grid_layout: QGridLayout, gui_concentrate_handler):
        super(ToolDialogFrame, self).__init__()
        self.containers = containers
        self.gui_concentrate_handler = gui_concentrate_handler
        self.page_containers_grid_layout: QGridLayout = page_containers_grid_layout

        self.frame_tools = QFrame(self.containers)
        self.frame_tools.resize(68, 78)
        self.frame_tools.setStyleSheet(ToolDialogFrameStyles.all_frame_style)
        self.frame_tools.setFrameShape(QFrame.StyledPanel)
        self.frame_tools.setFrameShadow(QFrame.Raised)
        self.frame_tools.setObjectName("frame_tools")

        self.frame_concat_to_frame_tools = QFrame(self.containers)
        self.frame_concat_to_frame_tools.resize(500, 168)
        self.frame_concat_to_frame_tools.setStyleSheet(ToolDialogFrameStyles.all_frame_style)
        self.frame_concat_to_frame_tools.setFrameShape(QFrame.StyledPanel)
        self.frame_concat_to_frame_tools.setFrameShadow(QFrame.Raised)
        self.frame_concat_to_frame_tools.setObjectName("frame_concat_to_frame_tools")

        self.ease_out = QEasingCurve(QEasingCurve.OutQuad)
        self.ease_in = QEasingCurve(QEasingCurve.InQuad)

    def setup_ui(self, page_containers: QFrame):
        self.lbl_tools = QLabel(self.frame_tools)
        self.lbl_tools.setText("Tools")
        self.lbl_tools.setGeometry(QRect(0, 27, 68, 21))
        self.lbl_tools.setStyleSheet(ToolDialogFrameStyles.lbl_frames_style)
        self.lbl_tools.setAlignment(Qt.AlignCenter)
        self.lbl_tools.setObjectName("lbl_tools")

        self.lbl_ellipse_tools = QLabel(self.frame_tools)
        self.lbl_ellipse_tools.setGeometry(QRect(0, 43, 68, 21))
        self.lbl_ellipse_tools.setStyleSheet(ToolDialogFrameStyles.transparent_color_style)
        self.lbl_ellipse_tools.setPixmap(QPixmap(AppPaths.GUI_ASSETS_ICONS_PATH + "/main_window/ellipse_logo.svg"))
        self.lbl_ellipse_tools.setAlignment(Qt.AlignCenter)
        self.lbl_ellipse_tools.setObjectName("lbl_ellipse_tools")

        self.lbl_close_frame_tools = QLabel(self.frame_concat_to_frame_tools)
        self.lbl_close_frame_tools.setGeometry(QRect(5, 5, 21, 21))
        self.lbl_close_frame_tools.setCursor(QCursor(Qt.PointingHandCursor))
        self.lbl_close_frame_tools.setPixmap(QPixmap(AppPaths.GUI_ASSETS_ICONS_PATH + "/main_window/close_logo.svg"))
        self.lbl_close_frame_tools.setObjectName("lbl_close_frame_tools")

        self.card_forensic = QLabel(self.frame_concat_to_frame_tools)
        self.card_forensic.setText("Forensic")
        self.card_forensic.setGeometry(QRect(25, 25, 71, 46))
        self.card_forensic.setCursor(QCursor(Qt.PointingHandCursor))
        self.card_forensic.setStyleSheet(ToolDialogFrameStyles.cards_in_frame_style)
        self.card_forensic.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        self.card_forensic.setObjectName("[TOOL]-[FORENSIC]-Forensic Tools")

        self.pic_forensic = QLabel(self.frame_concat_to_frame_tools)
        self.pic_forensic.setGeometry(QRect(40, 10, 41, 31))
        self.pic_forensic.setCursor(QCursor(Qt.PointingHandCursor))
        self.pic_forensic.setStyleSheet(ToolDialogFrameStyles.transparent_color_style)
        self.pic_forensic.setPixmap(QPixmap(AppPaths.GUI_ASSETS_ICONS_PATH + "/main_window/forensic_logo.svg"))
        self.pic_forensic.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        self.pic_forensic.setObjectName("pic_forensic")

        self.card_lot = QLabel(self.frame_concat_to_frame_tools)
        self.card_lot.setText("lot")
        self.card_lot.setGeometry(QRect(112, 25, 71, 46))
        self.card_lot.setCursor(QCursor(Qt.PointingHandCursor))
        self.card_lot.setStyleSheet(ToolDialogFrameStyles.cards_in_frame_style)
        self.card_lot.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        self.card_lot.setObjectName("[TOOL]-[IOT]-IOT Tools")

        self.pic_lot_logo = QLabel(self.frame_concat_to_frame_tools)
        self.pic_lot_logo.setGeometry(QRect(126, 10, 41, 31))
        self.pic_lot_logo.setCursor(QCursor(Qt.PointingHandCursor))
        self.pic_lot_logo.setStyleSheet(ToolDialogFrameStyles.transparent_color_style)
        self.pic_lot_logo.setPixmap(QPixmap(AppPaths.GUI_ASSETS_ICONS_PATH + "/main_window/lot_logo.svg"))
        self.pic_lot_logo.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        self.pic_lot_logo.setObjectName("pic_lot_logo")

        self.card_network = QLabel(self.frame_concat_to_frame_tools)
        self.card_network.setGeometry(QRect(286, 25, 71, 46))
        self.card_network.setText("Network")
        self.card_network.setCursor(QCursor(Qt.PointingHandCursor))
        self.card_network.setStyleSheet(ToolDialogFrameStyles.cards_in_frame_style)
        self.card_network.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        self.card_network.setObjectName("[TOOL]-[NETWORK]-Network Tools")

        self.pic_network_logo = QLabel(self.frame_concat_to_frame_tools)
        self.pic_network_logo.setGeometry(QRect(300, 10, 41, 31))
        self.pic_network_logo.setCursor(QCursor(Qt.PointingHandCursor))
        self.pic_network_logo.setStyleSheet(ToolDialogFrameStyles.transparent_color_style)
        self.pic_network_logo.setPixmap(QPixmap(AppPaths.GUI_ASSETS_ICONS_PATH + "/main_window/network_logo.svg"))
        self.pic_network_logo.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        self.pic_network_logo.setObjectName("pic_network_logo")

        self.card_dev_ops = QLabel(self.frame_concat_to_frame_tools)
        self.card_dev_ops.setText("DevOps")
        self.card_dev_ops.setGeometry(QRect(199, 25, 71, 46))
        self.card_dev_ops.setCursor(QCursor(Qt.PointingHandCursor))
        self.card_dev_ops.setStyleSheet(ToolDialogFrameStyles.cards_in_frame_style)
        self.card_dev_ops.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        self.card_dev_ops.setObjectName("[TOOL]-[DEVOPS]-DevOps Tools")

        self.pic_dev_ops_logo = QLabel(self.frame_concat_to_frame_tools)
        self.pic_dev_ops_logo.setGeometry(QRect(215, 10, 41, 31))
        self.pic_dev_ops_logo.setCursor(QCursor(Qt.PointingHandCursor))
        self.pic_dev_ops_logo.setStyleSheet(ToolDialogFrameStyles.transparent_color_style)
        self.pic_dev_ops_logo.setPixmap(QPixmap(AppPaths.GUI_ASSETS_ICONS_PATH + "/main_window/dev_ops_logo.svg"))
        self.pic_dev_ops_logo.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        self.pic_dev_ops_logo.setObjectName("pic_dev_ops_logo")

        self.card_monitoring = QLabel(self.frame_concat_to_frame_tools)
        self.card_monitoring.setText("Monitoring")
        self.card_monitoring.setGeometry(QRect(373, 105, 71, 46))
        self.card_monitoring.setCursor(QCursor(Qt.PointingHandCursor))
        self.card_monitoring.setStyleSheet(ToolDialogFrameStyles.cards_in_frame_style)
        self.card_monitoring.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        self.card_monitoring.setObjectName("[TOOL]-[MONITORING]-Monitoring Tools")

        self.pic_monitoring_logo = QLabel(self.frame_concat_to_frame_tools)
        self.pic_monitoring_logo.setGeometry(QRect(388, 90, 41, 31))
        self.pic_monitoring_logo.setCursor(QCursor(Qt.PointingHandCursor))
        self.pic_monitoring_logo.setStyleSheet(ToolDialogFrameStyles.transparent_color_style)
        self.pic_monitoring_logo.setPixmap(QPixmap(AppPaths.GUI_ASSETS_ICONS_PATH + "/main_window/monitoring_logo.svg"))
        self.pic_monitoring_logo.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        self.pic_monitoring_logo.setObjectName("pic_monitoring_logo")

        self.card_web = QLabel(self.frame_concat_to_frame_tools)
        self.card_web.setText("Web")
        self.card_web.setGeometry(QRect(373, 25, 71, 46))
        self.card_web.setCursor(QCursor(Qt.PointingHandCursor))
        self.card_web.setStyleSheet(ToolDialogFrameStyles.cards_in_frame_style)
        self.card_web.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        self.card_web.setObjectName("[TOOL]-[WEB]-Web Tools")

        self.pic_web_logo = QLabel(self.frame_concat_to_frame_tools)
        self.pic_web_logo.setGeometry(QRect(388, 10, 41, 31))
        self.pic_web_logo.setCursor(QCursor(Qt.PointingHandCursor))
        self.pic_web_logo.setStyleSheet(ToolDialogFrameStyles.transparent_color_style)
        self.pic_web_logo.setPixmap(QPixmap(AppPaths.GUI_ASSETS_ICONS_PATH + "/main_window/web_logo.svg"))
        self.pic_web_logo.setAlignment(Qt.AlignBottom | Qt.AlignHCenter)
        self.pic_web_logo.setObjectName("pic_web_logo")

        self.set_events(page_containers)

    def set_events(self, page_containers: QFrame):
        """this method for

        Arguments:
            page_containers {QFrame} -- [description]
        """
        UtilsClick.clickable(self.lbl_close_frame_tools).connect(lambda: self.set_visibility_effect(True, False, True))

        UtilsClick.clickable(self.card_dev_ops).connect(partial(
            self.item_clicked, page_containers=page_containers,
            object_name=self.card_dev_ops.objectName()
        ))
        UtilsClick.clickable(self.pic_dev_ops_logo).connect(partial(
            self.item_clicked, page_containers=page_containers,
            object_name=self.card_dev_ops.objectName()
        ))

        UtilsClick.clickable(self.card_web).connect(partial(
            self.item_clicked, page_containers=page_containers,
            object_name=self.card_web.objectName()
        ))
        UtilsClick.clickable(self.pic_web_logo).connect(partial(
            self.item_clicked, page_containers=page_containers,
            object_name=self.card_web.objectName()
        ))

        UtilsClick.clickable(self.card_lot).connect(partial(
            self.item_clicked, page_containers=page_containers,
            object_name=self.card_lot.objectName()
        ))
        UtilsClick.clickable(self.pic_lot_logo).connect(partial(
            self.item_clicked, page_containers=page_containers,
            object_name=self.card_lot.objectName()
        ))

        UtilsClick.clickable(self.card_forensic).connect(partial(
            self.item_clicked, page_containers=page_containers,
            object_name=self.card_forensic.objectName()
        ))
        UtilsClick.clickable(self.pic_forensic).connect(partial(
            self.item_clicked, page_containers=page_containers,
            object_name=self.card_forensic.objectName()
        ))

        UtilsClick.clickable(self.card_monitoring).connect(partial(
            self.item_clicked, page_containers=page_containers,
            object_name=self.card_monitoring.objectName()
        ))
        UtilsClick.clickable(self.pic_monitoring_logo).connect(partial(
            self.item_clicked, page_containers=page_containers,
            object_name=self.card_monitoring.objectName()
        ))

        UtilsClick.clickable(self.card_network).connect(partial(
            self.item_clicked, page_containers=page_containers,
            object_name=self.card_network.objectName()
        ))
        UtilsClick.clickable(self.pic_network_logo).connect(partial(
            self.item_clicked, page_containers=page_containers,
            object_name=self.card_network.objectName()
        ))

    def set_visibility_effect(self, visibility: bool, is_anime: bool, is_close: bool = False):
        """this method for set visibility  frame tools

        Arguments:
            visibility {bool} -- [this argument show status visibility frame ]
            is_anime {bool} -- [this argument show anime effect]

        Keyword Arguments:
            is_close {bool} -- [this argument when you want close frame] (default: {False})
        """
        x_location_frame_tools: int = int(self.containers.width() - 81)

        x_location_frame_tools_concat: int = int(x_location_frame_tools + 10)

        if visibility and is_anime:
            # start animation
            self.do_anim_frame_tools(
                self.frame_tools, QRect(x_location_frame_tools, 280, 68, 78),
                QRect(x_location_frame_tools, 360, 68, 78)
            )

            self.do_anim_concat_frame_tools(
                self.frame_concat_to_frame_tools, QRect(x_location_frame_tools_concat-161, 280, 161, 78),
                QRect(x_location_frame_tools_concat - self.frame_concat_to_frame_tools.width(), 360, 500, 168)
            )

        if is_close:
            # click close button
            self.do_anim_frame_tools(
                self.frame_tools, QRect(x_location_frame_tools, 360, 68, 78),
                QRect(x_location_frame_tools + self.containers.width(), 360, 68, 78)
            )

            self.do_anim_concat_frame_tools(
                self.frame_concat_to_frame_tools, QRect(x_location_frame_tools_concat, 360, 500, 78),
                QRect(x_location_frame_tools_concat + self.containers.width(), 360, 500, 168)
            )

        self.frame_tools.setVisible(visibility)
        self.frame_concat_to_frame_tools.setVisible(visibility)

        del x_location_frame_tools, x_location_frame_tools_concat

    def do_anim_frame_tools(self, obj: QFrame, start_location: QRect, end_location: QRect):
        """ this method for do animation frame tools

            Arguments:
                obj {QFrame} -- [object must be do animation effect]
                start_location {QRect} -- [start location for anime]
                end_location {QRect} -- [end location for anime]
        """
        self.anim = QPropertyAnimation(obj, b"geometry")
        self.anim.setStartValue(start_location)
        self.anim.setEndValue(end_location)
        self.anim.setDuration(200)
        self.anim.setEasingCurve(self.ease_out)
        self.anim.start(QPropertyAnimation.DeleteWhenStopped)

    def do_anim_concat_frame_tools(self, obj: QFrame, start_location: QRect, end_location: QRect):
        """ this method for do animation frame concat to frame tools tools

            Arguments:
                obj {QFrame} -- [object must be do animation effect]
                start_location {QRect} -- [start location for anime]
                end_location {QRect} -- [end location for anime]
        """

        self.anim_2 = QPropertyAnimation(obj, b"geometry")
        self.anim_2.setStartValue(start_location)
        self.anim_2.setEndValue(end_location)
        self.anim_2.setDuration(200)
        self.anim_2.setEasingCurve(self.ease_out)
        self.anim_2.start(QPropertyAnimation.DeleteWhenStopped)

    def item_clicked(self, page_containers: QFrame, object_name: str):
        """ this method when call client push devops item

            Arguments:
                page_containers {QFrame} -- [devops layout in this layer]
        """
        # Delete Children in Parent

        from commons.constants.gui_class_names import GUIClassNames
        self.gui_concentrate_handler.notify(message={
            "data": {
                "value": object_name
            },
            "params": None,
            "command": {
                "name": "[CHANGE_NAME]"
            }
        }, to=GUIClassNames.TOP_NAVIGATION_BAR_CONTAINERS)

        # delete all pervious widget that created on page_containers_grid_layout
        from ...central_page_maker.central_page_maker import CentralPageMaker
        from utils.widget_helper import WidgetHelper
        page_containers.setVisible(False)
        widget_helper = WidgetHelper()
        widget_helper.delete_all_widget(self.page_containers_grid_layout)
        del widget_helper

        self.page_containers_grid_layout.addWidget(CentralPageMaker().
            setup_ui(
            containers=page_containers, page_name=object_name
        ), 0, 1, 1, 1)
        page_containers.setVisible(True)

        self.set_visibility_effect(True, False, True)
예제 #21
0
class Expander(QWidget):
    expanded = pyqtSignal(object)
    clicked = pyqtSignal()

    def __init__(self,
                 header,
                 normal_icon="",
                 hovered_icon="",
                 selected_icon=""):
        QWidget.__init__(self)
        self.is_expanded = False
        self.text = header
        self.label_normal_color = self.palette().link().color().name()
        self.label_hovered_color = self.palette().highlight().color().name()
        self.label_selected_color = self.palette().highlightedText().color(
        ).name()
        self.normal_color = self.palette().base().color().name()
        self.selected_color = self.palette().highlight().color()
        self.hovered_color = self.palette().alternateBase().color()

        self.setCursor(Qt.PointingHandCursor)

        if normal_icon:
            self.normal_icon = QImage(normal_icon)
        if hovered_icon:
            self.hovered_icon = QImage(hovered_icon)
        if selected_icon:
            self.selected_icon = QImage(selected_icon)

        self.setAttribute(Qt.WA_Hover, True)

        self.color = self.normal_color
        self.setAutoFillBackground(True)

        vbox = QVBoxLayout()
        hbox = QHBoxLayout()
        self.icon = QLabel()
        self.icon.setPixmap(QPixmap.fromImage(self.normal_icon))
        self.hyper = QLabel()
        self.hyper.setText("<a style=\"color: " + self.label_normal_color +
                           " text-decoration: none\" href=\"#\">" + self.text +
                           "</a>")
        hbox.addWidget(self.icon)
        hbox.addSpacing(5)
        hbox.addWidget(self.hyper)
        hbox.addStretch()
        hbox.setContentsMargins(8, 8, 8, 8)
        vbox.addLayout(hbox)
        self.content = QWidget()
        self.content.setStyleSheet("background-color: " +
                                   self.palette().base().color().name())
        self.content.setMaximumHeight(0)

        vbox.addWidget(self.content)
        vbox.setContentsMargins(0, 0, 0, 0)
        self.setLayout(vbox)

        self.hyper.linkActivated.connect(self.buttonClicked)

        self.anim = QParallelAnimationGroup()
        self.height_anim = QPropertyAnimation(self.content,
                                              "maximumHeight".encode("utf-8"))
        self.color_anim = QPropertyAnimation(self, "color".encode("utf-8"))
        self.height_anim.setDuration(200)
        self.color_anim.setDuration(200)
        self.anim.addAnimation(self.height_anim)
        self.anim.addAnimation(self.color_anim)

    def setExpanded(self, value):
        if value == self.is_expanded:
            return

        if value:
            self.is_expanded = True
            pal = self.palette()
            pal.setColor(QPalette.Background, self.selected_color)
            self.setPalette(pal)
            self.icon.setPixmap(QPixmap.fromImage(self.selected_icon))
            self.hyper.setText("<a style=\"color: " +
                               self.label_selected_color +
                               "; text-decoration: none;\" href=\"#\">" +
                               self.text + "</a>")
        else:
            self.is_expanded = False
            pal = self.palette()
            pal.setColor(QPalette.Background, QColor(self.normal_color))
            self.setPalette(pal)
            self.icon.setPixmap(QPixmap.fromImage(self.normal_icon))
            self.hyper.setText("<a style=\"color: " + self.label_normal_color +
                               "; text-decoration: none;\" href=\"#\">" +
                               self.text + "</a>")

        if self.is_expanded:
            self.expandContent()
        else:
            self.collapseContent()
        self.expanded.emit(self.is_expanded)

    def addLayout(self, layout):
        self.content.setLayout(layout)

    @pyqtProperty('QColor')
    def color(self):
        return Qt.black

    @color.setter
    def color(self, color):
        pal = self.palette()
        pal.setColor(QPalette.Background, QColor(color))
        self.setPalette(pal)

    def mouseReleaseEvent(self, me):
        self.setExpanded(not self.is_expanded)
        if self.is_expanded:
            self.clicked.emit()

    def expandContent(self):
        if self.content.layout():
            self.height_anim.setEndValue(
                self.content.layout().sizeHint().height())
        else:
            self.height_anim.setEndValue(0)
        self.height_anim.setStartValue(0)
        self.color_anim.setStartValue(self.normal_color)
        self.color_anim.setEndValue(self.selected_color)
        self.anim.start()

    def collapseContent(self):
        if self.content.layout():
            self.height_anim.setStartValue(
                self.content.layout().sizeHint().height())
        else:
            self.height_anim.setStartValue(0)
        self.height_anim.setEndValue(0)
        self.color_anim.setStartValue(self.selected_color)
        self.color_anim.setEndValue(self.normal_color)
        self.anim.start()

    def buttonClicked(self):
        self.setExpanded(not self.is_expanded)
        if self.is_expanded:
            self.clicked.emit()

    def enterEvent(self, event):
        if not self.is_expanded:
            pal = self.palette()
            pal.setColor(QPalette.Background, QColor(self.hovered_color))
            self.setPalette(pal)
            self.icon.setPixmap(QPixmap.fromImage(self.hovered_icon))
            self.hyper.setText("<a style=\"color: " +
                               self.label_hovered_color +
                               "; text-decoration: none;\" href=\"#\">" +
                               self.text + "</a>")
        QWidget.enterEvent(self, event)

    def leaveEvent(self, event):
        if not self.is_expanded:
            pal = self.palette()
            pal.setColor(QPalette.Background, QColor(self.normal_color))
            self.setPalette(pal)
            self.icon.setPixmap(QPixmap.fromImage(self.normal_icon))
            self.hyper.setText("<a style=\"color: " + self.label_normal_color +
                               "; text-decoration: none;\" href=\"#\">" +
                               self.text + "</a>")
        QWidget.leaveEvent(self, event)
예제 #22
0
class Screen(QWidget):
    card_w = 200
    card_h = 250
    card_start_x = SCREEN_X / 2 - card_w / 2
    card_start_y = SCREEN_Y / 2 - card_h / 2
    card_pause_x = SCREEN_X / 2 - card_w / 2
    card_pause_y = 0.4275 * SCREEN_Y - card_h / 2
    card_pause2_x = SCREEN_X / 2 - card_w / 2
    card_pause2_y = 0.4225 * SCREEN_Y - card_h / 2
    card_pause3_x = SCREEN_X / 2 - card_w / 2
    card_pause3_y = 0.4175 * SCREEN_Y - card_h / 2
    card_end_x = SCREEN_X / 2 - card_w / 2
    card_end_y = SCREEN_Y / 6 - card_h / 2
    speed = 1000

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.initButtons()

        self.printerback = QLabel(self)
        self.printerback.setStyleSheet(
            "QLabel {border-image: url(./images/printer-back.png) 0 0 0 0 stretch stretch}"
        )
        self.printerback.setGeometry(
            QRect(SCREEN_X / 2 - SCREEN_X / 4.2,
                  SCREEN_Y / 2 - SCREEN_Y / 2.625, SCREEN_X / 2.1,
                  SCREEN_Y / 1.3125))
        self.label = PrintCard(self, self.card_start_x, self.card_start_y,
                               self.card_w, self.card_h)
        self.label.setText(self.chooseWord())
        self.printerfront = QLabel(self)
        self.printerfront.setStyleSheet(
            "QLabel {border-image: url(./images/printer-front.png) 0 0 0 0 stretch stretch}"
        )
        self.printerfront.setGeometry(
            QRect(SCREEN_X / 2 - SCREEN_X / 4.2,
                  SCREEN_Y / 2 - SCREEN_Y / 2.625, SCREEN_X / 2.1,
                  SCREEN_Y / 1.3125))

        self.gameover = QLabel(self)
        self.gameover.setVisible(False)
        self.gameover.setText("Game Over!")
        self.gameover.setStyleSheet("font-size: 30pt")
        self.gameover.setGeometry(
            QRect(SCREEN_X / 6 - SCREEN_X / 16.8, SCREEN_Y / 2, SCREEN_X / 8.4,
                  SCREEN_Y / 25))

        self.anim = QPropertyAnimation(self.label, b"geometry")
        self.anim.setDuration(self.speed)
        self.anim.setStartValue(
            QRect(self.label.x(), self.label.y(), self.label.card_w,
                  self.label.card_h))
        self.anim.setEndValue(
            QRect(self.card_pause_x, self.card_pause_y, self.label.card_w,
                  self.label.card_h))

        self.anim2 = QPropertyAnimation(self.label, b"geometry")
        self.anim2.setDuration(200)
        self.anim2.setEndValue(
            QRect(self.card_pause2_x, self.card_pause2_y, self.label.card_w,
                  self.label.card_h))

        self.anim3 = QPropertyAnimation(self.label, b"geometry")
        self.anim3.setDuration(200)
        self.anim3.setEndValue(
            QRect(self.card_pause3_x, self.card_pause3_y, self.label.card_w,
                  self.label.card_h))

        self.animFinish = QPropertyAnimation(self.label, b"geometry")
        self.animFinish.setDuration(self.speed)
        self.animFinish.setEndValue(
            QRect(self.card_end_x, self.card_end_y, self.label.card_w,
                  self.label.card_h))

        self.startbutton.clicked.connect(self.startButtonClicked)
        self.randombutton.clicked.connect(self.randomButtonClicked)
        self.printbutton.clicked.connect(self.printButtonClicked)
        self.print2button.clicked.connect(self.print2ButtonClicked)
        self.print3button.clicked.connect(self.print3ButtonClicked)
        self.finishprintbutton.clicked.connect(self.finishprintButtonClicked)
        self.reprintbutton.clicked.connect(self.reprintButtonClicked)
        self.nextbutton.clicked.connect(self.nextButtonClicked)
        self.restartbutton.clicked.connect(self.restartButtonClicked)
        self.exitbutton.clicked.connect(self.exit)
        self.animFinish.finished.connect(self.endAnimation)

        self.setWindowTitle("Printer")
        self.setGeometry(0, 0, SCREEN_X, SCREEN_Y)
        self.show()

    def initButtons(self):
        self.startbutton = PrinterButton("Start",
                                         self,
                                         width=SCREEN_X / 8.4,
                                         height=SCREEN_Y / 25,
                                         xPos=SCREEN_X / 6 - SCREEN_X / 16.8,
                                         yPos=SCREEN_Y / 2,
                                         font_size="20pt",
                                         background_color="#77eb34",
                                         background_color_pressed="#449615",
                                         border_radius="8px")

        self.randombutton = PrinterButton("Randomize Words",
                                          self,
                                          width=SCREEN_X / 8.4,
                                          height=SCREEN_Y / 25,
                                          xPos=SCREEN_X / 6 - SCREEN_X / 16.8,
                                          yPos=SCREEN_Y / 2 - SCREEN_Y / 25 -
                                          15,
                                          font_size="20pt",
                                          background_color="#f49eff",
                                          background_color_pressed="#a843cc",
                                          border_radius="8px")

        self.printbutton = PrinterButton("Print",
                                         self,
                                         visible=False,
                                         width=SCREEN_X / 8.4,
                                         height=SCREEN_Y / 25,
                                         xPos=SCREEN_X / 6 - SCREEN_X / 16.8,
                                         yPos=SCREEN_Y / 2,
                                         font_size="20pt",
                                         background_color="#77eb34",
                                         background_color_pressed="#449615",
                                         border_radius="8px")

        self.print2button = PrinterButton("Print More",
                                          self,
                                          visible=False,
                                          width=SCREEN_X / 8.4,
                                          height=SCREEN_Y / 25,
                                          xPos=SCREEN_X / 6 - SCREEN_X / 16.8,
                                          yPos=SCREEN_Y / 2 + SCREEN_Y / 25 +
                                          15,
                                          font_size="20pt",
                                          background_color="#77eb34",
                                          background_color_pressed="#449615",
                                          border_radius="8px")

        self.print3button = PrinterButton("Print More",
                                          self,
                                          visible=False,
                                          width=SCREEN_X / 8.4,
                                          height=SCREEN_Y / 25,
                                          xPos=SCREEN_X / 6 - SCREEN_X / 16.8,
                                          yPos=SCREEN_Y / 2 + SCREEN_Y / 25 +
                                          15,
                                          font_size="20pt",
                                          background_color="#77eb34",
                                          background_color_pressed="#449615",
                                          border_radius="8px")

        self.finishprintbutton = PrinterButton(
            "Finish Printing",
            self,
            visible=False,
            width=SCREEN_X / 8.4,
            height=SCREEN_Y / 25,
            xPos=SCREEN_X / 6 - SCREEN_X / 16.8,
            yPos=SCREEN_Y / 2,
            font_size="20pt",
            background_color="#ff9717",
            background_color_pressed="#8f4f00",
            border_radius="8px")

        self.reprintbutton = PrinterButton("Print Again",
                                           self,
                                           visible=False,
                                           width=SCREEN_X / 8.4,
                                           height=SCREEN_Y / 25,
                                           xPos=SCREEN_X / 6 - SCREEN_X / 16.8,
                                           yPos=SCREEN_Y / 2 + SCREEN_Y / 25 +
                                           15,
                                           font_size="20pt",
                                           background_color="#77eb34",
                                           background_color_pressed="#449615",
                                           border_radius="8px")

        self.nextbutton = PrinterButton("Next Page",
                                        self,
                                        visible=False,
                                        width=SCREEN_X / 8.4,
                                        height=SCREEN_Y / 25,
                                        xPos=SCREEN_X / 6 - SCREEN_X / 16.8,
                                        yPos=SCREEN_Y / 2,
                                        font_size="20pt",
                                        background_color="#f49eff",
                                        background_color_pressed="#a843cc",
                                        border_radius="8px")

        self.restartbutton = PrinterButton("Restart",
                                           self,
                                           visible=False,
                                           width=SCREEN_X / 8.4,
                                           height=SCREEN_Y / 25,
                                           xPos=SCREEN_X / 6 - SCREEN_X / 16.8,
                                           yPos=SCREEN_Y / 2 - SCREEN_Y / 25 -
                                           15,
                                           font_size="20pt",
                                           background_color="#30f5ff",
                                           background_color_pressed="17a6ff",
                                           border_radius="8px")

        self.exitbutton = PrinterButton("Exit",
                                        self,
                                        width=SCREEN_X / 8.4,
                                        height=SCREEN_Y / 25,
                                        xPos=SCREEN_X / 6 - SCREEN_X / 16.8,
                                        yPos=8 * SCREEN_Y / 10 - SCREEN_Y / 50,
                                        font_size="20pt",
                                        background_color="#fc3003",
                                        background_color_pressed="a11216",
                                        border_radius="8px")

    def startButtonClicked(self):
        self.startbutton.setVisible(False)
        self.randombutton.setVisible(False)
        self.printbutton.setVisible(True)
        self.restartbutton.setVisible(True)

    def randomButtonClicked(self):
        global WORDS
        WORDS = read_words.shuffle(WORDS)
        self.restartButtonClicked()

    def printButtonClicked(self):
        self.anim.start()
        self.printbutton.setVisible(False)
        self.print2button.setVisible(True)
        self.finishprintbutton.setVisible(True)

    def print2ButtonClicked(self):
        if self.anim.state() == 2:
            return
        self.anim2.setStartValue(
            QRect(self.label.x(), self.label.y(), self.label.card_w,
                  self.label.card_h))
        self.anim2.start()
        self.print2button.setVisible(False)
        self.print3button.setVisible(True)

    def print3ButtonClicked(self):
        if self.anim2.state() == 2:
            return
        self.anim3.setStartValue(
            QRect(self.label.x(), self.label.y(), self.label.card_w,
                  self.label.card_h))
        self.anim3.start()
        self.print3button.setVisible(False)

    def finishprintButtonClicked(self):
        if (self.anim.state() == 2 or self.anim2.state() == 2
                or self.anim3.state() == 2):
            return
        self.animFinish.setStartValue(
            QRect(self.label.x(), self.label.y(), self.label.card_w,
                  self.label.card_h))
        self.animFinish.start()
        self.printbutton.setVisible(False)
        self.print2button.setVisible(False)
        self.print3button.setVisible(False)
        self.finishprintbutton.setVisible(False)
        self.nextbutton.setVisible(True)
        self.reprintbutton.setVisible(True)

    def reprintButtonClicked(self):
        if self.animFinish.state() == 2:
            return
        global INDEX
        INDEX -= 1
        self.nextButtonClicked()

    def nextButtonClicked(self):
        if self.animFinish.state() == 2:
            return
        if INDEX >= len(WORDS):
            self.restartbutton.setVisible(True)
            self.reprintbutton.setVisible(False)
            self.nextbutton.setVisible(False)
            self.gameover.setVisible(True)
            return
        self.resetUI()

    def restartButtonClicked(self):
        if self.anim.state() == 2:
            return
        global INDEX
        INDEX = 0
        self.resetUI(main_menu=True)

    def endAnimation(self):
        self.printbutton.setVisible(False)
        self.finishprintbutton.setVisible(False)
        self.nextbutton.setVisible(True)
        self.reprintbutton.setVisible(True)

    def chooseWord(self):
        global INDEX
        word = WORDS[INDEX]
        INDEX += 1
        return word

    def resetUI(self, main_menu=False):
        if main_menu:
            self.startbutton.setVisible(True)
            self.randombutton.setVisible(True)
            self.printbutton.setVisible(False)
            self.restartbutton.setVisible(False)
        else:
            self.startbutton.setVisible(False)
            self.randombutton.setVisible(False)
            self.printbutton.setVisible(True)
            self.restartbutton.setVisible(True)
        self.gameover.setVisible(False)
        self.anim.setCurrentTime(0)
        self.animFinish.setCurrentTime(0)
        self.reprintbutton.setVisible(False)
        self.nextbutton.setVisible(False)
        self.label.setText(self.chooseWord())
        self.label.move(self.card_start_x, self.card_start_y)

    def exit(self):
        sys.exit(0)
예제 #23
0
class CoffeeFundWindow(QWidget):
    signal_back = pyqtSignal()
    signal_coffee = pyqtSignal()
    signal_account = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__()

        self.cards = {}  # type: Dict[GuiCards, QWidget]
        """
            Python's GC will clean up QPropertyAnimations as soon as it leaves the button handler,
             therefore they will appear not to work. Use members to store the animations.
            see http://stackoverflow.com/a/6953965
        """
        self.slide_in_animation = None
        self.slide_out_animation = None
        self.animation_group = None
        self.setObjectName("coffeeFundWindow")

        """
            Store the position and size of visible/hidden cards for the animation sequences
        """
        self.hidden_geometry = None
        self.visible_geometry = None

        layout = QStackedLayout()
        layout.setStackingMode(QStackedLayout.StackAll)

        card_remove = RemoveCard()
        self.cards[GuiCards.RemoveCard] = card_remove
        layout.addWidget(card_remove)

        card_choose_action = ChooseActionCard()
        self.cards[GuiCards.ChooseAction] = card_choose_action
        layout.addWidget(card_choose_action)

        card_account = AccountCard()
        self.cards[GuiCards.AccountInfo] = card_account
        layout.addWidget(card_account)

        # keep this as last initialized card, the last card will be shown on startup!
        card_start = StartCard()
        self.cards[GuiCards.Start] = card_start
        layout.addWidget(card_start)

        self.setLayout(layout)
        self.setWindowTitle("Kaffeekasse")

        layout.setCurrentWidget(card_start)
        self.active_card = None

        card_choose_action.button_account.clicked.connect(self.signal_account)
        card_choose_action.button_coffee.clicked.connect(self.signal_coffee)
        card_account.button_back.clicked.connect(self.signal_back)

    def set_card_hidden(self, card: QWidget):
        card.setGeometry(self.hidden_geometry)

    def show_start(self):
        self.show_card(GuiCards.Start)

    def show_account(self, name, value):
        self.cards[GuiCards.AccountInfo].set_user_name(name)
        self.cards[GuiCards.AccountInfo].set_balance(value)
        self.show_card(GuiCards.AccountInfo)

    def show_choose_action(self, name: str):
        self.cards[GuiCards.ChooseAction].set_user_name(name)
        self.show_card(GuiCards.ChooseAction)

    def show_remove(self):
        self.show_card(GuiCards.RemoveCard)

    def show_card(self, card_id: GuiCards):
        if self.active_card is None:
            self.active_card = self.cards[GuiCards.Start]

        if self.active_card == self.cards[card_id]:
            return

        if self.visible_geometry is None or self.hidden_geometry is None:
            self.visible_geometry = self.active_card.geometry()  # type: QRect
            self.hidden_geometry = QRect(self.visible_geometry.x(), self.visible_geometry.height() * 1.5,
                                         self.visible_geometry.width(), self.visible_geometry.height())
        for key in self.cards.keys():
            if key != self.active_card:
                self.set_card_hidden(self.cards[key])

        card_to_show = self.cards[card_id]
        self.start_card_switch(card_to_show)
        self.active_card = self.cards[card_id]
        self.layout().setCurrentWidget(self.active_card)

    def start_card_switch(self, card_to_show):
        self.slide_out_animation = QPropertyAnimation(self.active_card, "geometry")
        self.slide_out_animation.setDuration(ANIMATION_DURATION)
        self.slide_out_animation.setEasingCurve(QEasingCurve.OutCubic)
        self.slide_out_animation.setStartValue(self.visible_geometry)
        self.slide_out_animation.setEndValue(self.hidden_geometry)
        self.set_card_hidden(card_to_show)
        self.slide_in_animation = QPropertyAnimation(card_to_show, "geometry")
        self.slide_in_animation.setDuration(ANIMATION_DURATION)
        self.slide_in_animation.setEasingCurve(QEasingCurve.InCubic)
        self.slide_in_animation.setStartValue(self.hidden_geometry)
        self.slide_in_animation.setEndValue(self.visible_geometry)
        self.animation_group = QParallelAnimationGroup()
        self.animation_group.addAnimation(self.slide_out_animation)
        self.animation_group.addAnimation(self.slide_in_animation)
        self.animation_group.start()
예제 #24
0
class MiniMap(QPlainTextEdit):

    def __init__(self, parent):
        super(MiniMap, self).__init__(parent)
        self.setWordWrapMode(QTextOption.NoWrap)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setReadOnly(True)
        self.setCenterOnScroll(True)
        self.setMouseTracking(True)
        self.viewport().setCursor(Qt.PointingHandCursor)
        self.setTextInteractionFlags(Qt.NoTextInteraction)

        self._parent = parent
        self.highlighter = None
        self.lines_count = 0

        if ACTIVATE_OPACITY:
            self.goe = QGraphicsOpacityEffect()
            self.setGraphicsEffect(self.goe)
            self.goe.setOpacity(settings.MINIMAP_MIN_OPACITY)
            self.animation = QPropertyAnimation(self.goe, b"opacity")

        self.slider = SliderArea(self)
        self.slider.show()

    def __calculate_max(self):
        line_height = self._parent.cursorRect().height()
        if line_height > 0:
            self.lines_count = self._parent.viewport().height() / line_height
        self.slider.update_position()
        self.update_visible_area()

    def set_code(self, source):
        self.setPlainText(source)
        self.__calculate_max()

    def adjust_to_parent(self):
        self.setFixedHeight(self._parent.height())
        self.setFixedWidth(self._parent.width() * settings.SIZE_PROPORTION)
        x = self._parent.width() - self.width()
        self.move(x, 0)
        fontsize = int(self.width() / settings.MARGIN_LINE)
        if fontsize < 1:
            fontsize = 1
        font = self.document().defaultFont()
        font.setPointSize(fontsize)
        self.setFont(font)
        self.__calculate_max()

    def update_visible_area(self):
        if not self.slider.pressed:
            line_number = self._parent.firstVisibleBlock().blockNumber()
            block = self.document().findBlockByLineNumber(line_number)
            cursor = self.textCursor()
            cursor.setPosition(block.position())
            rect = self.cursorRect(cursor)
            self.setTextCursor(cursor)
            self.slider.move_slider(rect.y())

    def enterEvent(self, event):
        if ACTIVATE_OPACITY:
            self.animation.setDuration(300)
            self.animation.setStartValue(settings.MINIMAP_MIN_OPACITY)
            self.animation.setEndValue(settings.MINIMAP_MAX_OPACITY)
            self.animation.start()

    def leaveEvent(self, event):
        if ACTIVATE_OPACITY:
            self.animation.setDuration(300)
            self.animation.setStartValue(settings.MINIMAP_MAX_OPACITY)
            self.animation.setEndValue(settings.MINIMAP_MIN_OPACITY)
            self.animation.start()

    def mousePressEvent(self, event):
        super(MiniMap, self).mousePressEvent(event)
        cursor = self.cursorForPosition(event.pos())
        self._parent.jump_to_line(cursor.blockNumber())

    def resizeEvent(self, event):
        super(MiniMap, self).resizeEvent(event)
        self.slider.update_position()

    def scroll_area(self, pos_parent, pos_slider):
        pos_parent.setY(pos_parent.y() - pos_slider.y())
        cursor = self.cursorForPosition(pos_parent)
        self._parent.verticalScrollBar().setValue(cursor.blockNumber())

    def wheelEvent(self, event):
        super(MiniMap, self).wheelEvent(event)
        self._parent.wheelEvent(event)
예제 #25
0
파일: invites.py 프로젝트: rigmar/IDArling
class Invite(QWidget):
    """
    An invite is a small notification being displayed in the bottom right
    corner of the window. It fades in and out, and is used to invite an user
    to jump to a certain location. Some other uses might be added later.
    """
    def __init__(self, plugin, parent=None):
        super(Invite, self).__init__(parent)
        self._plugin = plugin
        self._time = 0

        self.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool
                            | Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_ShowWithoutActivating)
        self.setAttribute(Qt.WA_TranslucentBackground)

        self._icon = QLabel()
        self._icon.setAutoFillBackground(False)
        self._icon.setAttribute(Qt.WA_TranslucentBackground)

        self._text = QLabel()
        self._text.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

        self._layout = QHBoxLayout()
        self._layout.addWidget(self._text)
        self.setLayout(self._layout)

        # Fade in and out animation
        self._popup_opacity = 0.0
        self._animation = QPropertyAnimation()
        self._animation.setTargetObject(self)
        self._animation.setPropertyName(b"popup_opacity")
        self._animation.finished.connect(self.hide)

        # Timer used to auto-close the window
        self._timer = QTimer()
        self._timer.timeout.connect(self.hide_animation)
        self._callback = None
        self._triggered = False

    @property
    def time(self):
        return self._time

    @time.setter
    def time(self, time):
        self._time = time

    @property
    def text(self):
        return self._text.text()

    @text.setter
    def text(self, text):
        self._text.setText(text)
        self.adjustSize()

    @property
    def icon(self):
        return self._icon.pixmap()

    @icon.setter
    def icon(self, pixmap):
        # Resize the given pixmap
        pixmap_height = self._text.sizeHint().height()
        self._icon.setPixmap(
            pixmap.scaled(
                pixmap_height,
                pixmap_height,
                Qt.KeepAspectRatio,
                Qt.SmoothTransformation,
            ))
        self._layout.insertWidget(0, self._icon)

    @property
    def callback(self):
        return self._callback

    @callback.setter
    def callback(self, callback):
        self._callback = callback

    @property
    def triggered(self):
        return self._triggered

    @triggered.setter
    def triggered(self, triggered):
        self._triggered = triggered

    def paintEvent(self, event):  # noqa: N802
        """We override the painting event to draw the invite ourselves."""
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        rect = QRect(self.rect())

        # Draw the border
        painter.setBrush(QBrush(QColor(122, 122, 122)))
        painter.setPen(Qt.NoPen)
        painter.drawRect(rect)

        rect.setX(rect.x() + 1)
        rect.setY(rect.y() + 1)
        rect.setWidth(rect.width() - 1)
        rect.setHeight(rect.height() - 1)

        # Draw the background
        painter.setBrush(QBrush(QColor(255, 255, 225)))
        painter.setPen(Qt.NoPen)
        painter.drawRect(rect)

    def mouseReleaseEvent(self, event):  # noqa: N802
        """
        This function is called when the user clicks the invite. It triggers
        the callback function is it has been specified, and hides the invite.
        """
        if self._callback:
            self._callback()
        self._triggered = True
        self._popup_opacity = 0.0
        self.hide()

    def show(self):
        """Shows the invite to user. It triggers a fade in effect."""
        self._plugin.logger.debug("Showing invite %s" % self.text)
        self.setWindowOpacity(0.0)

        self._animation.setDuration(500)
        self._animation.setStartValue(0.0)
        self._animation.setEndValue(1.0)

        # Map the notification to the bottom right corner
        pos = QPoint(self.parent().width() - 25, self.parent().height() - 50)
        pos = self.parent().mapToGlobal(pos)

        self.setGeometry(
            pos.x() - self.width(),
            pos.y() - self.height(),
            self.width(),
            self.height(),
        )
        super(Invite, self).show()

        self._animation.start()
        self._timer.start(3500)

    def hide(self):
        """Hides the invite only if it is fully transparent."""
        if self._popup_opacity == 0.0:
            self._plugin.interface.widget.refresh()
            super(Invite, self).hide()

    def hide_animation(self):
        """Hides the invite. It triggers the fade out animation."""
        self._timer.stop()
        self._animation.setDuration(500)
        self._animation.setStartValue(1.0)
        self._animation.setEndValue(0.0)
        self._animation.start()

    @pyqtProperty(float)
    def popup_opacity(self):
        return self._popup_opacity

    @popup_opacity.setter
    def popup_opacity(self, opacity):
        self._popup_opacity = opacity
        self.setWindowOpacity(opacity)
예제 #26
0
class QSlideSwitchPrivate(QObject):

    def __init__(self, q):
        QObject.__init__(self)

        self._position = 0
        self._sliderShape = QRectF()
        self._gradient = QLinearGradient()
        self._gradient.setSpread(QGradient.PadSpread)
        self._qPointer = q

        self.animation = QPropertyAnimation(self, b"position")
        self.animation.setTargetObject(self)
        # self.animation.setPropertyName()
        self.animation.setStartValue(0)
        self.animation.setEndValue(1)
        self.animation.setDuration(300)
        self.animation.setEasingCurve(QEasingCurve.InOutExpo)

    def __del__(self):
        del self.animation

    @pyqtProperty(float)
    def position(self):
        return self._position

    @position.setter
    def position(self, value):
        self._position = value
        self._qPointer.repaint()

    def drawSlider(self, painter):
        margin = 3
        r = self._qPointer.rect().adjusted(0, 0, -1, -1)
        dx = (r.width() - self._sliderShape.width()) * self._position
        sliderRect = self._sliderShape.translated(dx, 0)
        painter.setPen(Qt.NoPen)

        # basic settings
        shadow = self._qPointer.palette().color(QPalette.Dark)
        light = self._qPointer.palette().color(QPalette.Light)
        button = self._qPointer.palette().color(QPalette.Button)

        # draw background
        # draw outer background
        self._gradient.setColorAt(0, shadow.darker(130))
        self._gradient.setColorAt(1, light.darker(130))
        self._gradient.setStart(0, r.height())
        self._gradient.setFinalStop(0, 0)
        painter.setBrush(self._gradient)
        painter.drawRoundedRect(r, 15, 15)

        # draw background
        # draw inner background
        self._gradient.setColorAt(0, shadow.darker(140))
        self._gradient.setColorAt(1, light.darker(160))
        self._gradient.setStart(0, 0)
        self._gradient.setFinalStop(0, r.height())
        painter.setBrush(self._gradient)
        painter.drawRoundedRect(r.adjusted(margin, margin, -margin, -margin), 15, 15)

        # draw slider
        self._gradient.setColorAt(0, button.darker(130))
        self._gradient.setColorAt(1, button)

        # draw outer slider
        self._gradient.setStart(0, r.height())
        self._gradient.setFinalStop(0, 0)
        painter.setBrush(self._gradient)
        painter.drawRoundedRect(sliderRect.adjusted(margin, margin, -margin, -margin), 10, 15)

        # draw inner slider
        self._gradient.setStart(0, 0)
        self._gradient.setFinalStop(0, r.height())
        painter.setBrush(self._gradient)
        painter.drawRoundedRect(sliderRect.adjusted(2.5 * margin, 2.5 * margin, -2.5 * margin, - 2.5 * margin), 5, 15)

        # draw text
        if self.animation.state() == QPropertyAnimation.Running:
            return  # don't draw any text while animation is running

        font = self._qPointer.font()
        self._gradient.setColorAt(0, light)
        self._gradient.setColorAt(1, shadow)
        self._gradient.setStart(0, r.height() / 2.0 + font.pointSizeF())
        self._gradient.setFinalStop(0, r.height() / 2.0 - font.pointSizeF())
        painter.setFont(font)
        painter.setPen(QPen(QBrush(self._gradient), 0))

        if self._qPointer.isChecked():
            painter.drawText(0, 0, r.width() / 2, r.height() - 1, Qt.AlignCenter, "ON")
        else:
            painter.drawText(r.width() / 2, 0, r.width() / 2, r.height() - 1, Qt.AlignCenter, "OFF")

    def updateSliderRect(self, size):
        self._sliderShape.setWidth(size.width() / 2.0)
        self._sliderShape.setHeight(size.height() - 1.0)

    @pyqtSlot(bool, name='animate')
    def animate(self, checked):
        self.animation.setDirection(QPropertyAnimation.Forward if checked else QPropertyAnimation.Backward)
        self.animation.start()
예제 #27
0
class RecoveryKeyExporter(QObject):

    done = pyqtSignal(str)

    def __init__(self, parent=None):
        super(RecoveryKeyExporter, self).__init__(parent)
        self.parent = parent
        self.filepath = None
        self.progress = None
        self.animation = None
        self.crypter = None
        self.crypter_thread = None
        self.ciphertext = None

    def _on_encryption_failed(self, message):
        self.crypter_thread.quit()
        error(self.parent, "Error encrypting data", message)
        self.crypter_thread.wait()

    def _on_encryption_succeeded(self, ciphertext):
        self.crypter_thread.quit()
        if self.filepath:
            with open(self.filepath, 'wb') as f:
                f.write(ciphertext)
            self.done.emit(self.filepath)
            self.filepath = None
        else:
            self.ciphertext = ciphertext
        self.crypter_thread.wait()

    def _export_encrypted_recovery(self, gateway, password):
        settings = gateway.get_settings(include_rootcap=True)
        if gateway.use_tor:
            settings['hide-ip'] = True
        data = json.dumps(settings)
        self.progress = QProgressDialog("Encrypting...", None, 0, 100)
        self.progress.show()
        self.animation = QPropertyAnimation(self.progress, b'value')
        self.animation.setDuration(6000)  # XXX
        self.animation.setStartValue(0)
        self.animation.setEndValue(99)
        self.animation.start()
        self.crypter = Crypter(data.encode(), password.encode())
        self.crypter_thread = QThread()
        self.crypter.moveToThread(self.crypter_thread)
        self.crypter.succeeded.connect(self.animation.stop)
        self.crypter.succeeded.connect(self.progress.close)
        self.crypter.succeeded.connect(self._on_encryption_succeeded)
        self.crypter.failed.connect(self.animation.stop)
        self.crypter.failed.connect(self.progress.close)
        self.crypter.failed.connect(self._on_encryption_failed)
        self.crypter_thread.started.connect(self.crypter.encrypt)
        self.crypter_thread.start()
        dest, _ = QFileDialog.getSaveFileName(
            self.parent, "Select a destination",
            os.path.join(os.path.expanduser('~'),
                         gateway.name + ' Recovery Key.json.encrypted'))
        if not dest:
            return
        if self.ciphertext:
            with open(dest, 'wb') as f:
                f.write(self.ciphertext)
            self.done.emit(dest)
            self.ciphertext = None
        else:
            self.filepath = dest

    def _export_plaintext_recovery(self, gateway):
        dest, _ = QFileDialog.getSaveFileName(
            self.parent, "Select a destination",
            os.path.join(os.path.expanduser('~'),
                         gateway.name + ' Recovery Key.json'))
        if not dest:
            return
        try:
            gateway.export(dest, include_rootcap=True)
        except Exception as e:  # pylint: disable=broad-except
            error(self.parent, "Error exporting Recovery Key", str(e))
            return
        self.done.emit(dest)

    def do_export(self, gateway):
        password, ok = PasswordDialog.get_password(
            self.parent, "Encryption passphrase (optional):",
            "A long passphrase will help keep your files safe in the event "
            "that your Recovery Key is ever compromised.")
        if ok and password:
            self._export_encrypted_recovery(gateway, password)
        elif ok:
            self._export_plaintext_recovery(gateway)
예제 #28
0
class RecoveryKeyImporter(QObject):

    done = pyqtSignal(dict)

    def __init__(self, parent=None):
        super(RecoveryKeyImporter, self).__init__()
        self.parent = parent
        self.filepath = None
        self.progress = None
        self.animation = None
        self.crypter = None
        self.crypter_thread = None

    def _on_decryption_failed(self, msg):
        logging.error("%s", msg)
        self.crypter_thread.quit()
        if msg == "Decryption failed. Ciphertext failed verification":
            msg = "The provided passphrase was incorrect. Please try again."
        reply = QMessageBox.critical(self.parent, "Decryption Error", msg,
                                     QMessageBox.Abort | QMessageBox.Retry)
        self.crypter_thread.wait()
        if reply == QMessageBox.Retry:
            self._load_from_file(self.filepath)

    def _on_decryption_succeeded(self, plaintext):
        logging.debug("Decryption of %s succeeded", self.filepath)
        self.crypter_thread.quit()
        try:
            settings = json.loads(plaintext.decode('utf-8'))
        except (UnicodeDecodeError, json.decoder.JSONDecodeError) as e:
            error(self, type(e).__name__, str(e))
            return
        self.done.emit(settings)
        self.crypter_thread.wait()

    def _decrypt_content(self, data, password):
        logging.debug("Trying to decrypt %s...", self.filepath)
        self.progress = QProgressDialog(
            "Trying to decrypt {}...".format(os.path.basename(self.filepath)),
            None, 0, 100)
        self.progress.show()
        self.animation = QPropertyAnimation(self.progress, b'value')
        self.animation.setDuration(6000)  # XXX
        self.animation.setStartValue(0)
        self.animation.setEndValue(99)
        self.animation.start()
        self.crypter = Crypter(data, password.encode())
        self.crypter_thread = QThread()
        self.crypter.moveToThread(self.crypter_thread)
        self.crypter.succeeded.connect(self.animation.stop)
        self.crypter.succeeded.connect(self.progress.close)
        self.crypter.succeeded.connect(self._on_decryption_succeeded)
        self.crypter.failed.connect(self.animation.stop)
        self.crypter.failed.connect(self.progress.close)
        self.crypter.failed.connect(self._on_decryption_failed)
        self.crypter_thread.started.connect(self.crypter.decrypt)
        self.crypter_thread.start()

    def _parse_content(self, content):
        try:
            settings = json.loads(content.decode('utf-8'))
        except (UnicodeDecodeError, json.decoder.JSONDecodeError):
            logging.debug("JSON decoding failed; %s is likely encrypted",
                          self.filepath)
            password, ok = PasswordDialog.get_password(
                self.parent,
                "Decryption passphrase (required):",
                "This Recovery Key is protected by a passphrase. Enter the "
                "correct passphrase to decrypt it.",
                show_stats=False)
            if ok:
                self._decrypt_content(content, password)
            return
        self.done.emit(settings)

    def _load_from_file(self, path):
        logging.debug("Loading %s...", self.filepath)
        try:
            with open(path, 'rb') as f:
                content = f.read()
        except Exception as e:  # pylint: disable=broad-except
            error(self, type(e).__name__, str(e))
            return
        self._parse_content(content)

    def _select_file(self):
        dialog = QFileDialog(self.parent, "Select a Recovery Key")
        dialog.setDirectory(os.path.expanduser('~'))
        dialog.setFileMode(QFileDialog.ExistingFile)
        if dialog.exec_():
            return dialog.selectedFiles()[0]
        return None

    def do_import(self, filepath=None):
        if not filepath:
            filepath = self._select_file()
        self.filepath = filepath
        if self.filepath:
            self._load_from_file(self.filepath)
예제 #29
0
class NS_Animate(object):
    def __init__(self, scene, x_max, y_max, back_color):

        scene = QGraphicsScene(0, 0, x_max, y_max)
        scene.setBackgroundBrush(back_color)

        color = [Qt.green, Qt.lightGray, Qt.darkYellow, QtGui.QColor.fromRgb(255, 85, 0)]
        self.anim_butt = [ QGraphicsRectWidget(color[j]) for j in range(4) ]
        for j in range(4):
            scene.addItem(self.anim_butt[j])

        self.window = QGraphicsView(scene)
        self.window.setFrameStyle(0)
        self.window.setAlignment(Qt.AlignLeft | Qt.AlignTop)
        self.window.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.window.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        self.machine = QStateMachine()

        self.group = QState()
        self.timer = QTimer()
        self.timer.setInterval(1250)
        self.timer.setSingleShot(True)
        self.group.entered.connect(self.timer.start)

        # set states positions
        anim_state_rects = [ [QRect(x_max*xp/6, y_max*yp/4, 8, 8) for xp in range(4)] for yp in range(4) ]
        self.states = [ self.createGeometryState(
                                self.anim_butt[0], anim_state_rects[0][j], self.anim_butt[1], anim_state_rects[1][j],
                                self.anim_butt[2], anim_state_rects[2][j], self.anim_butt[3], anim_state_rects[3][j],
                                self.group
                            ) for j in range(4) ]

        self.group.setInitialState(self.states[0])


        self.animationGroup = QParallelAnimationGroup()
        self.anim = QPropertyAnimation(self.anim_butt[3], 'geometry')
        self.anim.setDuration(1250)
        self.anim.setEasingCurve(QEasingCurve.InBack)
        self.animationGroup.addAnimation(self.anim)

        self.subGroup = QSequentialAnimationGroup(self.animationGroup)
        self.subGroup.addPause(100)
        self.anim = QPropertyAnimation(self.anim_butt[2], 'geometry')
        self.anim.setDuration(1000)
        self.anim.setEasingCurve(QEasingCurve.OutElastic)
        self.subGroup.addAnimation(self.anim)

        self.subGroup = QSequentialAnimationGroup(self.animationGroup)
        self.subGroup.addPause(500)
        self.anim = QPropertyAnimation(self.anim_butt[1], 'geometry')
        self.anim.setDuration(500)
        self.anim.setEasingCurve(QEasingCurve.OutElastic)
        self.subGroup.addAnimation(self.anim)

        self.subGroup = QSequentialAnimationGroup(self.animationGroup)
        self.subGroup.addPause(750)
        self.anim = QPropertyAnimation(self.anim_butt[0], 'geometry')
        self.anim.setDuration(250)
        self.anim.setEasingCurve(QEasingCurve.OutElastic)
        self.subGroup.addAnimation(self.anim)

        self.stateSwitcher = StateSwitcher(self.machine)
        self.group.addTransition(self.timer.timeout, self.stateSwitcher)
        for j in range(4):
            self.stateSwitcher.addState(self.states[j], self.animationGroup)

        self.machine.addState(self.group)
        self.machine.setInitialState(self.group)
        self.machine.start()

    #
    def createGeometryState(self, w1, rect1, w2, rect2, w3, rect3, w4, rect4, parent):
        result = QState(parent)

        result.assignProperty(w1, 'geometry', rect1)
        result.assignProperty(w1, 'geometry', rect1)
        result.assignProperty(w2, 'geometry', rect2)
        result.assignProperty(w3, 'geometry', rect3)
        result.assignProperty(w4, 'geometry', rect4)

        return result
예제 #30
0
class WindowWithTitleBar(QFrame):
    def __init__(self, mainwidget, parent=0):
        super(WindowWithTitleBar, self).__init__()
        self.setObjectName('WindowWithTitleBar')
        self.m_titlebar = Titlebar(self)
        self.initWidgetsAndPack(mainwidget, self.m_titlebar)
        self.initStretch()
        self.initTipLabel(mainwidget)

    def initTipLabel(self, parent):
        """
        消息提示标签
        :param parent:
        :return:
        """
        self.tipLabel = QLabel(parent)
        self.tipLabel.setFixedSize(200, 40)
        self.tipLabel.setAlignment(Qt.AlignCenter)
        self.tipLabel.setWordWrap(True)
        self.tipLabel.setGeometry(self.width() / 2 - self.tipLabel.width() / 2,
                                  self.tipLabel.y(), self.tipLabel.width(),
                                  self.tipLabel.height())
        self.tipLabel.hide()

    def showTip(self, text, color='#20c3ff'):
        if self.tipLabel is not None:
            self.tipLabel.show()
            self.tipLabel.setStyleSheet(
                "QLabel{background: %s;border:3px; color: #FFFFFF; border-radius: 5px}"
                % color)
            self.tipLabel.setText(text)
            eff = QGraphicsOpacityEffect(self)
            self.tipLabel.setGraphicsEffect(eff)
            self.animate = QPropertyAnimation(eff, "opacity")
            self.animate.setDuration(2000)
            self.animate.setStartValue(0.8)
            self.animate.setEndValue(0)
            self.animate.setEasingCurve(QEasingCurve.InCubic)
            self.animate.finished.connect(lambda: self.tipLabel.hide())
            self.animate.start()

    def initWidgetsAndPack(self, mainwidget, titlebar):
        """
        将主体Widget和titleBar拼装起来
        :param mainwidget:
        :param titlebar:
        :return:
        """
        self.mainwidget = mainwidget
        self.resize(mainwidget.width(),
                    mainwidget.height() + Titlebar.TITLEBAR_HEIGHT)
        self.setWindowFlags(Qt.FramelessWindowHint | self.windowFlags())
        self.installEventFilter(titlebar)
        # 布局: titlbar在上主窗体在下
        pLayout = QVBoxLayout(self)
        pLayout.addWidget(titlebar)
        pLayout.addWidget(mainwidget)
        pLayout.setSpacing(0)  # 排列的几个widget为0间隔
        pLayout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(pLayout)

    def initStretch(self):
        """
        初始化拉伸功能
        :return:
        """
        self.setSupportStretch(True)
        self.m_isWindowMax = False
        self.m_stretchRectState = NO_SELECT
        self.m_isMousePressed = False
        self.setMinimumSize(
            self.mainwidget.minimumWidth(),
            self.mainwidget.minimumHeight() + Titlebar.TITLEBAR_HEIGHT)

    def getTitbar(self):
        return self.m_titlebar

    def setMinimumSize(self, width, height):
        """
        设置拉伸的最小Size
        :param width:
        :param height:
        :return:
        """
        self.m_windowMinWidth = width
        self.m_windowMinHeight = height
        super(WindowWithTitleBar, self).setMinimumSize(width, height)

    def setWindowRadius(self, n_px):
        """
        圆边
        :param n_px: 弧度
        :return:
        """
        objBitmap = QBitmap(self.size())
        painter = QPainter(objBitmap)
        painter.setBrush(QColor(0, 0, 0))
        painter.drawRoundedRect(self.rect(), n_px, n_px)
        self.setMask(objBitmap)

    def setBackgroundBorderColor(self, bgdcolor, bordercolor):
        self.setStyleSheet(
            "WindowWithTitleBar{background:%s;border:3px solid %s}" %
            (bgdcolor, bordercolor))

    def closeEvent(self, *args, **kwargs):
        self.mainwidget.close()

    def showEvent(self, event):
        self.calculateCurrentStrechRect()
        return super().showEvent(event)

    def calculateCurrentStrechRect(self):
        # 四个角Rect
        self.m_leftTopRect = QRect(0, 0, STRETCH_RECT_WIDTH,
                                   STRETCH_RECT_HEIGHT)
        self.m_leftBottomRect = QRect(0,
                                      self.height() - STRETCH_RECT_HEIGHT,
                                      STRETCH_RECT_WIDTH, STRETCH_RECT_WIDTH)
        self.m_rightTopRect = QRect(self.width() - STRETCH_RECT_WIDTH, 0,
                                    STRETCH_RECT_WIDTH, STRETCH_RECT_HEIGHT)
        self.m_rightBottomRect = QRect(self.width() - STRETCH_RECT_WIDTH,
                                       self.height() - STRETCH_RECT_HEIGHT,
                                       STRETCH_RECT_WIDTH, STRETCH_RECT_HEIGHT)
        # 四条边Rect
        self.m_topBorderRect = QRect(STRETCH_RECT_WIDTH, 0,
                                     self.width() - STRETCH_RECT_WIDTH * 2,
                                     STRETCH_RECT_HEIGHT)
        self.m_rightBorderRect = QRect(self.width() - STRETCH_RECT_WIDTH,
                                       STRETCH_RECT_HEIGHT, STRETCH_RECT_WIDTH,
                                       self.height() - STRETCH_RECT_HEIGHT * 2)
        self.m_bottomBorderRect = QRect(STRETCH_RECT_WIDTH,
                                        self.height() - STRETCH_RECT_HEIGHT,
                                        self.width() - STRETCH_RECT_WIDTH * 2,
                                        STRETCH_RECT_HEIGHT)
        self.m_leftBorderRect = QRect(0, STRETCH_RECT_HEIGHT,
                                      STRETCH_RECT_WIDTH,
                                      self.height() - STRETCH_RECT_HEIGHT * 2)

    def getCurrentStretchState(self, cursorPos):
        """
        根据鼠标的位置获取StretchState
        :param cursorPos:
        :return:
        """
        if self.m_leftTopRect.contains(cursorPos):
            stretchState = LEFT_TOP_RECT
        elif self.m_rightTopRect.contains(cursorPos):
            stretchState = RIGHT_TOP_RECT
        elif self.m_rightBottomRect.contains(cursorPos):
            stretchState = RIGHT_BOTTOM_RECT
        elif self.m_leftBottomRect.contains(cursorPos):
            stretchState = LEFT_BOTTOM_RECT
        elif self.m_topBorderRect.contains(cursorPos):
            stretchState = TOP_BORDER
        elif self.m_rightBorderRect.contains(cursorPos):
            stretchState = RIGHT_BORDER
        elif self.m_bottomBorderRect.contains(cursorPos):
            stretchState = BOTTOM_BORDER
        elif self.m_leftBorderRect.contains(cursorPos):
            stretchState = LEFT_BORDER
        else:
            stretchState = NO_SELECT
        return stretchState

    def updateMouseStyle(self, stretchState):
        """
        根据stretchState刷新鼠标的样式
        :param stretchState:
        :return:
        """
        if stretchState == NO_SELECT:
            self.setCursor(Qt.ArrowCursor)
        elif stretchState == LEFT_TOP_RECT:
            self.setCursor(Qt.SizeFDiagCursor)
        elif stretchState == RIGHT_BOTTOM_RECT:
            self.setCursor(Qt.SizeFDiagCursor)
        elif stretchState == TOP_BORDER:
            self.setCursor(Qt.SizeVerCursor)
        elif stretchState == BOTTOM_BORDER:
            self.setCursor(Qt.SizeVerCursor)
        elif stretchState == RIGHT_TOP_RECT:
            self.setCursor(Qt.SizeBDiagCursor)
        elif stretchState == LEFT_BOTTOM_RECT:
            self.setCursor(Qt.SizeBDiagCursor)
        elif stretchState == LEFT_BORDER:
            self.setCursor(Qt.SizeHorCursor)
        elif stretchState == RIGHT_BORDER:
            self.setCursor(Qt.SizeHorCursor)
        else:
            self.setCursor(Qt.ArrowCursor)

    def mouseMoveEvent(self, event):
        """
        重写mouseMoveEvent事件,用于获取当前鼠标的位置,将位置传递给getCurrentStretchState方法,
        得到当前鼠标的状态,然后调用updateMouseStyle对鼠标的样式进行更新
        :param event:
        :return:
        """
        # 如果窗口最大化是不能拉伸的
        # 也不用更新鼠标样式
        if (self.m_isWindowMax):
            return super().mouseMoveEvent(event)
        # 如果当前鼠标未按下,则根据当前鼠标的位置更新鼠标的状态及样式
        if not self.m_isMousePressed:
            cursorPos = event.pos()
            # 根据当前鼠标的位置显示不同的样式
            self.m_stretchRectState = self.getCurrentStretchState(cursorPos)
            self.updateMouseStyle(self.m_stretchRectState)
        # 如果当前鼠标左键已经按下,则记录下第二个点的位置,并更新窗口的大小
        else:
            self.m_endPoint = self.mapToGlobal(event.pos())
            self.updateWindowSize()
        return super().mouseMoveEvent(event)

    def mousePressEvent(self, event):
        # 当前鼠标进入了以上指定的8个区域,并且是左键按下时才开始进行窗口拉伸
        if (self.m_stretchRectState != NO_SELECT
                and event.button() == Qt.LeftButton):
            self.m_isMousePressed = True
            # 记录下当前鼠标位置,为后面计算拉伸位置
            self.m_startPoint = self.mapToGlobal(event.pos())
            # 保存下拉伸前的窗口位置及大小
            self.m_windowRectBeforeStretch = QRect(self.geometry().x(),
                                                   self.geometry().y(),
                                                   self.geometry().width(),
                                                   self.geometry().height())
        return super().mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        """
        鼠标松开后意味之窗口拉伸结束,置标志位,并且重新计算用于拉伸的8个区域Rect
        :param event:
        :return:
        """
        self.m_isMousePressed = False
        self.calculateCurrentStrechRect()
        return super().mouseReleaseEvent(event)

    def updateWindowSize(self):
        """
        拉伸窗口过程中,根据记录的坐标更新窗口大小
        :return:
        """
        windowRect = QRect(self.m_windowRectBeforeStretch.x(),
                           self.m_windowRectBeforeStretch.y(),
                           self.m_windowRectBeforeStretch.width(),
                           self.m_windowRectBeforeStretch.height())
        delValue_X = self.m_startPoint.x() - self.m_endPoint.x()
        delValue_Y = self.m_startPoint.y() - self.m_endPoint.y()
        if self.m_stretchRectState == LEFT_BORDER:
            topLeftPoint = windowRect.topLeft()
            topLeftPoint.setX(topLeftPoint.x() - delValue_X)
            windowRect.setTopLeft(topLeftPoint)
        elif self.m_stretchRectState == RIGHT_BORDER:
            bottomRightPoint = windowRect.bottomRight()
            bottomRightPoint.setX(bottomRightPoint.x() - delValue_X)
            windowRect.setBottomRight(bottomRightPoint)
        elif self.m_stretchRectState == TOP_BORDER:
            topLeftPoint = windowRect.topLeft()
            topLeftPoint.setY(topLeftPoint.y() - delValue_Y)
            windowRect.setTopLeft(topLeftPoint)
        elif self.m_stretchRectState == BOTTOM_BORDER:
            bottomRightPoint = windowRect.bottomRight()
            bottomRightPoint.setY(bottomRightPoint.y() - delValue_Y)
            windowRect.setBottomRight(bottomRightPoint)
        elif self.m_stretchRectState == LEFT_TOP_RECT:
            topLeftPoint = windowRect.topLeft()
            topLeftPoint.setX(topLeftPoint.x() - delValue_X)
            topLeftPoint.setY(topLeftPoint.y() - delValue_Y)
            windowRect.setTopLeft(topLeftPoint)
        elif self.m_stretchRectState == RIGHT_TOP_RECT:
            topRightPoint = windowRect.topRight()
            topRightPoint.setX(topRightPoint.x() - delValue_X)
            topRightPoint.setY(topRightPoint.y() - delValue_Y)
            windowRect.setTopRight(topRightPoint)
        elif self.m_stretchRectState == RIGHT_BOTTOM_RECT:
            bottomRightPoint = windowRect.bottomRight()
            bottomRightPoint.setX(bottomRightPoint.x() - delValue_X)
            bottomRightPoint.setY(bottomRightPoint.y() - delValue_Y)
            windowRect.setBottomRight(bottomRightPoint)
        elif self.m_stretchRectState == LEFT_BOTTOM_RECT:
            bottomLeftPoint = windowRect.bottomLeft()
            bottomLeftPoint.setX(bottomLeftPoint.x() - delValue_X)
            bottomLeftPoint.setY(bottomLeftPoint.y() - delValue_Y)
            windowRect.setBottomLeft(bottomLeftPoint)
        # 避免宽或高为零窗口显示有误,这里给窗口设置最小拉伸高度、宽度
        if windowRect.width() < self.m_windowMinWidth:
            windowRect.setLeft(self.geometry().left())
            windowRect.setWidth(self.m_windowMinWidth)
        if windowRect.height() < self.m_windowMinHeight:
            windowRect.setTop(self.geometry().top())
            windowRect.setHeight(self.m_windowMinHeight)
        self.setGeometry(windowRect)

    def setSupportStretch(self, isSupportStretch):
        """
        设置当前窗口是否支持拉伸
        :param isSupportStretch:
        :return:
        """
        # 因为需要在鼠标未按下的情况下通过mouseMoveEvent事件捕捉鼠标位置,所以需要设置setMouseTracking为True(如果窗口支持拉伸)
        self.m_isSupportStretch = isSupportStretch
        self.setMouseTracking(isSupportStretch)
        # 这里对子控件也进行了设置,是因为如果不对子控件设置,当鼠标移动到子控件上时,不会发送mouseMoveEvent事件,也就获取不到当前鼠标位置,无法判断鼠标状态及显示样式了。
        widgetList = self.findChildren(QWidget)
        for widget in widgetList:
            widget.setMouseTracking(isSupportStretch)
        if (self.m_titlebar is not None):
            # titleBar同理,也需要对自己及子控件进行调用setMouseTracking进行设置,见上方注释
            # self.titleBar.setSupportStretch(isSupportStretch)
            pass

    def getSupportStretch(self):
        """
        返回当前窗口是否支持拉伸
        :return:
        """
        return self.m_isSupportStretch

    def setMaxEnable(self, isEnable):
        """
        最大化开闭
        :param isEnable
        """
        self.m_titlebar.setMaximumEnable(isEnable)
예제 #31
0
class SongInfoCard(QWidget):
    """ 歌曲信息卡 """
    def __init__(self, songInfo: dict = None, parent=None):
        super().__init__(parent)
        self.resize(320, 55)
        # 创建小部件
        self.songNameLabel = QLabel(self)
        self.songerNameLabel = QLabel(self)
        self.opacityEffect = QGraphicsOpacityEffect(self)
        self.ani = QPropertyAnimation(self.opacityEffect, b"opacity")
        # 初始化
        self.__initWidget()
        # 设置窗口信息
        self.updateCard(songInfo)

    def __initWidget(self):
        """ 初始化小部件 """
        self.setFixedHeight(55)
        self.opacityEffect.setOpacity(1)
        self.setGraphicsEffect(self.opacityEffect)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.songNameLabel.setProperty("name", "smallestModeSongNameLabel")
        self.songerNameLabel.setProperty("name", "smallestModeSongerNameLabel")

    def __setSongInfo(self, songInfo: dict):
        """ 设置标签信息 """
        if not songInfo:
            songInfo = {}
        self.songName = songInfo.get("songName", "未知歌曲")  # type:str
        self.songerName = songInfo.get("songer", "未知歌手")  # type:str
        self.songNameLabel.setText(self.songName)
        self.songerNameLabel.setText(self.songerName)

    def updateCard(self, songInfo: dict):
        """ 更新窗口 """
        self.__setSongInfo(songInfo)
        self.__adjustLabel()

    def __adjustLabel(self):
        """ 根据当前窗口的宽度设置标签文本和位置 """
        fontMetrics = QFontMetrics(QFont("Microsoft YaHei", 12, 75))
        # 字符串的最大宽度
        maxWidth = self.width() - 30
        songNameWidth, songerNameWidth = 0, 0
        # 调整歌名
        for index, char in enumerate(self.songName):
            if songNameWidth + fontMetrics.width(char) > maxWidth:
                self.songNameLabel.setText(self.songName[:index])
                break
            songNameWidth += fontMetrics.width(char)
        self.songNameLabel.setFixedWidth(songNameWidth)
        # 调整歌手名
        fontMetrics = QFontMetrics(QFont("Microsoft YaHei", 11))
        for index, char in enumerate(self.songerName):
            if songerNameWidth + fontMetrics.width(char) > maxWidth:
                self.songerNameLabel.setText(self.songerName[:index])
                break
            songerNameWidth += fontMetrics.width(char)
        self.songerNameLabel.setFixedWidth(songerNameWidth)
        # 调整标签位置
        self.songNameLabel.move(int(self.width() / 2 - songNameWidth / 2), 0)
        self.songerNameLabel.move(int(self.width() / 2 - songerNameWidth / 2),
                                  30)

    def resizeEvent(self, e):
        """ 改变窗口大小时调整标签 """
        super().resizeEvent(e)
        self.__adjustLabel()

    def aniHide(self):
        """ 淡出 """
        self.ani.setStartValue(1)
        self.ani.setEndValue(0)
        self.ani.setDuration(150)
        self.ani.finished.connect(self.__hideAniSlot)
        self.ani.start()

    def aniShow(self):
        """ 淡入 """
        super().show()
        self.ani.setStartValue(0)
        self.ani.setEndValue(1)
        self.ani.setDuration(150)
        self.ani.start()

    def __hideAniSlot(self):
        """ 淡出动画完成的槽函数 """
        self.ani.disconnect()
        super().hide()
예제 #32
0
class NumberItem(SudokuItem):

    adj = 5
    valid_input = True

    def __init__(self, parent, row, col, num, rect: QRectF, disabled=False):
        super().__init__(parent=parent)
        self.rect = rect.adjusted(self.adj, self.adj, -self.adj, -self.adj)
        self.disabled = disabled
        self.row = row
        self.col = col

        # Create a link to the sudoku game instance.
        self.game = self.parent.parent.game

        if num == 0:
            self.num = ''
        else:
            self.num = num

        self.animations()

        if not self.disabled:
            self.setFlags(QGraphicsItem.ItemIsFocusable
                          | QGraphicsItem.ItemIsSelectable)
        self.setAcceptHoverEvents(True)
        self.setCacheMode(QGraphicsItem.DeviceCoordinateCache)
        self.setTransformOriginPoint(self.rect.center())

    def paint(self, painter, option, widget):
        # Change font color when user input is false.
        # Default pen color is set to black.
        black_pen = QPen(Qt.black, 1)
        red_pen = QPen(Qt.red, 1)

        painter.setPen(black_pen)

        brush = QBrush(Qt.NoBrush)
        if self.disabled:
            brush = QBrush(QColor(200, 200, 200), Qt.SolidPattern)
        if self.isSelected():
            width = self.rect.width() * 1.1
            height = self.rect.height() * 1.1
            x = self.rect.x() - ((width - self.rect.width()) / 2)
            y = self.rect.y() - ((height - self.rect.height()) / 2)
            rect = QRectF(x, y, width, height)
            brush = QBrush(QColor(160, 200, 255), Qt.SolidPattern)
        else:
            rect = self.rect

        painter.setBrush(brush)
        painter.setFont(QFont('Helvetica', 14, 50))
        painter.setRenderHint(QPainter.Antialiasing)
        painter.drawEllipse(rect)

        if self.parent.parent.show_errors and not self.valid_input:
            painter.setPen(red_pen)

        painter.drawText(rect, Qt.AlignCenter, f'{self.num}')

    def boundingRect(self):
        return self.rect.adjusted(-self.adj, -self.adj, self.adj, self.adj)

    def hoverEnterEvent(self, e):
        if not self.disabled:
            self.setCursor(Qt.IBeamCursor)
            self.start_animations(QAbstractAnimation.Forward)

    def hoverMoveEvent(self, e):
        pass

    def hoverLeaveEvent(self, e):
        if not self.disabled:
            self.setCursor(Qt.ArrowCursor)
            self.start_animations(QAbstractAnimation.Backward)

    def mousePressEvent(self, e):
        # Clear any item that may be selected that belongs to the same parent.
        # Also, remove the focus from that item.
        for item in self.parent.childItems():
            item.setSelected(False)
            item.setFocus(False)
        # Set the current item as selected, and give it focus.
        self.setSelected(True)
        self.setFocus(True)

    def keyPressEvent(self, e):
        print()
        # Only act on the item that currently has keyboard focus.
        if self.hasFocus():
            # On backspace or delete, remove the current number from spot.
            if e.key() == 16777219 or e.key() == 16777223:
                self.num = ''
                self.game.board[self.row][self.col] = 0
            elif e.key() >= 49 and e.key() <= 57:
                # If the number already exists in spot, do nothing.
                if str(e.key() - 48) == self.num:
                    return

                # Otherwise, set the number to the key that was pressed.
                self.num = str(e.key() - 48)

                board_copy = deepcopy(self.game.board)
                board_copy[self.row][self.col] = int(self.num)

                # Check to make sure that there are no overlaps in columns, and rows, and the board is solveable.
                if self.game.check_input(int(self.num), self.row, self.col,
                                         self.game.board):
                    self.valid_input = True
                else:
                    self.valid_input = False

                self.game.board[self.row][self.col] = int(self.num)

            self.update()

            if self.parent.parent.game.check_game_over():
                self.parent.parent.game_over.emit()

    def animations(self):
        scale_value = 1.1
        self.scale_anim = QPropertyAnimation(self, b'scale')
        self.scale_anim.setDuration(100)
        self.scale_anim.setStartValue(1)
        self.scale_anim.setEndValue(scale_value)

    def start_animations(self, direction: QAbstractAnimation):
        self.scale_anim.setDirection(direction)
        self.scale_anim.start()
예제 #33
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        loadUi('MainWindowUi.ui', self)
        fontID = QFontDatabase.addApplicationFont("HelveticaNeue.ttf")
        self.isMirrorAwake = False
        self.clockThread = ClockThread()
        self.currentWxThread = CurrentWeatherThread()
        self.forecastWxThread = WxForecastThread()
        self.quoteThread = QuoteThread()
        self.trafficThread = TrafficThread()
        self.notificationThread = NotificationThread()
        self.notificationEffect = QGraphicsOpacityEffect()
        self.notificationAnimation = QPropertyAnimation(
            self.notificationEffect, b"opacity")
        self.mainFourEffect = QGraphicsOpacityEffect()
        self.notificationLabel.setGraphicsEffect(self.notificationEffect)
        self.mainFourFrame.setGraphicsEffect(self.mainFourEffect)
        self.showMainTimer = QTimer()
        self.notificationEffect.setOpacity(0)
        self.mainFourEffect.setOpacity(0)

        self.connectSignals()

    def keyPressEvent(self, event):
        # Did the user press the Escape key?
        if event.key(
        ) == Qt.Key_Escape:  # QtCore.Qt.Key_Escape is a value that equates to what the operating system passes to python from the keyboard when the escape key is pressed.
            # Yes: Close the window
            self.close()
        elif event.key() == Qt.Key_F1:
            if self.isMirrorAwake:
                self.shouldMirrorWake(False)
            else:
                self.shouldMirrorWake(True)
        elif event.key() == Qt.Key_F2:
            item = QListWidgetItem(self.calendarListView)
            item_widget = CalendarItemWidget("Test", "Date", "End", "Start")
            item.setSizeHint(item_widget.size())
            self.calendarListView.addItem(item)
            self.calendarListView.setItemWidget(item, item_widget)

    def connectSignals(self):
        # Notifications
        self.notificationThread.sendNotificationTextSignal.connect(
            self.setNotificationText)
        self.notificationThread.showNotificationPanelSignal.connect(
            self.hideShowNotificationPanel)

        # Clock
        self.clockThread.sendDateSignal.connect(self.setDateText)
        self.clockThread.sendTimeSignal.connect(self.setTimeText)
        self.clockThread.sendSecondsSignal.connect(self.setSecondsText)
        self.clockThread.sendAmPmSignal.connect(self.setAmPmText)

        # Current Weather
        self.currentWxThread.sendWxTempSignal.connect(self.setCurrentWxTemp)
        self.currentWxThread.sendWxConditionsSignal.connect(
            self.setCurrentWxConditions)
        self.currentWxThread.sendWxWindsSignal.connect(self.setCurrentWxWinds)
        self.currentWxThread.sendWxGraphicSignal.connect(
            self.setCurrentWxImage)

        # Forecast Weather
        self.forecastWxThread.sendWxForecastForecast.connect(
            self.setWxForecastItems)

        # Quote
        self.quoteThread.sendQuoteQuote.connect(self.setQuoteQuote)
        self.quoteThread.sendQuoteAuthor.connect(self.setAuthorLabel)

        # Traffic
        self.trafficThread.sendDestinationTextSignal.connect(
            self.setDestinationText)
        self.trafficThread.sendDepartureTimeTextSignal.connect(
            self.setDepartureTimeText)
        self.trafficThread.sendArrivalTimeTextSignal.connect(
            self.setArrivalTimeText)

    def startThreads(self):
        # Notifications
        self.notificationThread.setRunning(True)
        self.notificationThread.start()

        # Clock
        self.clockThread.setRunning(True)
        self.clockThread.start()

        # Current Weather
        self.currentWxThread.setRunning(True)
        self.currentWxThread.start()

        # Forecast Weather
        self.forecastWxThread.setRunning(True)
        self.forecastWxThread.start()

        # Quote
        self.quoteThread.setRunning(True)
        self.quoteThread.start()

        # Traffic
        self.trafficThread.setRunning(True)
        self.trafficThread.start()

    def stopThreads(self):
        # Notifications
        # self.notificationThread.setRunning(False)
        # self.notificationThread.quit()

        # Clock
        self.clockThread.setRunning(False)
        self.clockThread.quit()

        # Current Weather
        self.currentWxThread.setRunning(False)
        self.currentWxThread.quit()

        # Forecast Weather
        self.forecastWxThread.setRunning(False)
        self.forecastWxThread.quit()

        # Quote
        self.quoteThread.setRunning(False)
        self.quoteThread.quit()

        # Traffic
        self.trafficThread.setRunning(False)
        self.trafficThread.quit()

    # Slot functions used only by this object
    # Notifications
    def setNotificationText(self, notificationText):
        try:
            self.notificationLabel.setText(notificationText)
        except Exception as e:
            print(e)

    def hideShowNotificationPanel(self, showNotificationPanel):
        try:
            if showNotificationPanel:
                startValue = 0
                endValue = 1
            else:
                startValue = 1
                endValue = 0

            self.notificationLabel.setGraphicsEffect(self.notificationEffect)
            self.notificationAnimation.setDuration(2000)
            self.notificationAnimation.setStartValue(startValue)
            self.notificationAnimation.setEndValue(endValue)
            self.notificationAnimation.start()

        except Exception as e:
            print(e)

    # Clock
    def setDateText(self, dateText):
        self.dateLabel.setText(dateText)

    def setTimeText(self, timeText):
        self.timeLabel.setText(timeText)

    def setSecondsText(self, secondsText):
        self.timeSecondsLabel.setText(secondsText)

    def setAmPmText(self, amPmText):
        self.timeAmPmLabel.setText(amPmText)

    # Current Weather
    def setCurrentWxTemp(self, tempText):
        self.wxTempLabel.setText(tempText)

    def setCurrentWxConditions(self, conditionsText):
        self.wxLabel.setText(conditionsText)

    def setCurrentWxWinds(self, windsText):
        self.windLabel.setText(windsText)

    def setCurrentWxImage(self, wxImage):
        self.currentWxImage.setPixmap(wxImage)

    # Forecast Weather
    def setWxForecastItems(self, forecasts):

        for forecast in forecasts:
            item = QListWidgetItem(self.wxForecastListView)
            item_widget = WxForecastItemWidget(forecast.day, forecast.icon,
                                               forecast.high, forecast.low)
            item.setSizeHint(item_widget.size())
            self.wxForecastListView.addItem(item)
            self.wxForecastListView.setItemWidget(item, item_widget)

    # Quote
    def setQuoteQuote(self, quote):
        self.quoteLabel.setText(quote)

    def setAuthorLabel(self, author):
        self.authorLabel.setText(author)

    # Traffic
    def setDestinationText(self, destination):
        self.trafficDestinationLabel.setText(destination)

    def setDepartureTimeText(self, departureTime):
        self.trafficDepartureTimeLabel.setText(departureTime)

    def setArrivalTimeText(self, arrivalTime):
        self.trafficArrivalTimeLabel.setText(arrivalTime)

    # Mirror Functions

    def shouldMirrorWake(self, shouldWake):
        self.isMirrorAwake = shouldWake
        if shouldWake:
            self.startThreads()
            self.showMirror()
        else:
            self.stopThreads()
            self.hideMirror()

    def showMirror(self):
        self.notificationThread.showNotification("Welcome back, beautiful!", 5)

        self.showMainTimer.timeout.connect(
            self.showHideMirrorAfterNotification)
        self.showMainTimer.start(5000)

    def hideMirror(self):
        self.notificationThread.showNotification("Goodbye...", 5)

        self.showMainTimer.timeout.connect(
            self.showHideMirrorAfterNotification)
        self.showMainTimer.start(5000)

    def showHideMirrorAfterNotification(self):
        try:
            self.showMainTimer.stop()
            if self.isMirrorAwake:
                startValue = 0
                endValue = 1
            else:
                startValue = 1
                endValue = 0

            self.mainFourEffect = QGraphicsOpacityEffect()
            self.mainFourFrame.setGraphicsEffect(self.mainFourEffect)
            self.showHideMirrorAnimation = QPropertyAnimation(
                self.mainFourEffect, b"opacity")
            self.showHideMirrorAnimation.setDuration(2000)
            self.showHideMirrorAnimation.setStartValue(startValue)
            self.showHideMirrorAnimation.setEndValue(endValue)
            self.showHideMirrorAnimation.start()

        except Exception as e:
            print(e)
예제 #34
0
class PushButton(QPushButton):
    clicked = pyqtSignal(str)

    MIN_VALOR = 1
    MAX_VALOR = 101
    VALOR = MAX_VALOR + MIN_VALOR

    def __init__(self, parent=None):
        super(PushButton, self).__init__(parent)
        self.parent = parent

        self.pressing = False
        self.inicio = QPoint()
        self.mover = QPoint()
        self.habilitado = False
        self.arrastrado = False

        self.actualizarEstado()
        self.actualizarPosicion()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.ultimo = True
            self.inicio = event.pos()
            self.pressing = True
            self.actualizarEstado()

    def actualizarEstado(self):
        # Si la posicion x del boton mas la mitad de su ancho
        # es menor que la mitad del ancho del widget padre,
        # entonces esta apagado (NO)
        if (self.x() + (self.width() / 2)) < PushButton.VALOR / 2:
            self.habilitado = False

        # Si la posicion x del boton mas la mitad de su ancho
        # es mayor que la mitad del ancho del widget padre,
        # entonces esta encendido (SI)
        if (self.x() + (self.width() / 2)) > PushButton.VALOR / 2:
            self.habilitado = True

        if self.habilitado:
            self.setText("SI")
            color = QColor(206, 61, 59)
        elif not self.habilitado:
            self.setText("NO")
            color = QColor(147, 183, 89)

        colorFrame = self.palette()
        colorFrame.setColor(QPalette.Background, color)
        self.parent.setPalette(colorFrame)

    def mouseMoveEvent(self, event):
        if self.pressing:
            self.mover = self.mapToParent(event.pos() - self.inicio)
            self.mover.setY(1)
            self.move(self.mover)

            self.arrastrado = True
            self.restringirMovimiento()
            self.actualizarEstado()

    def actualizarPosicion(self):
        self.mover.setY(1)

        if self.habilitado:
            self.mover.setX(PushButton.MAX_VALOR - self.width())
        else:
            self.mover.setX(PushButton.MIN_VALOR)

        self.animacion = QPropertyAnimation(self, b"pos")
        self.animacion.setDuration(150)
        self.animacion.setEndValue(self.mover)
        self.animacion.finished.connect(self.emitirEstado)
        self.animacion.start(QAbstractAnimation.DeleteWhenStopped)

    def restringirMovimiento(self):
        self.mover.setY(1)

        # Restringir lado izquierdo
        if self.x() < PushButton.MIN_VALOR:
            self.mover.setX(PushButton.MIN_VALOR)
            self.move(self.mover)
            return

        # Restringir lado derecho
        if (self.x() + self.width()) > PushButton.MAX_VALOR:
            self.mover.setX(PushButton.MAX_VALOR - self.width())
            self.move(self.mover)
            return

    def mouseReleaseEvent(self, event):
        if self.pressing:
            self.pressing = False
            self.actualizarEstado()
            self.actualizarPosicion()

            if not self.arrastrado and self.ultimo:
                # QApplication.instance().doubleClickInterval()
                QTimer.singleShot(100, self.performSingleClickAction)
            else:
                self.arrastrado = False

    def mouseDoubleClickEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.ultimo = False

    def performSingleClickAction(self):
        if self.ultimo:
            self.mover.setY(1)

            if self.habilitado:
                self.mover.setX(PushButton.MIN_VALOR)
            else:
                self.mover.setX(PushButton.MAX_VALOR - self.width())

            self.animacion = QPropertyAnimation(self, b"pos")
            self.animacion.setDuration(150)
            self.animacion.setEndValue(self.mover)
            self.animacion.valueChanged.connect(self.actualizarEstado)
            self.animacion.finished.connect(self.emitirEstado)
            self.animacion.start(QAbstractAnimation.DeleteWhenStopped)

    def emitirEstado(self):
        self.clicked.emit(self.text())
예제 #35
0
    view.setWindowTitle("Animated Tiles")
    view.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
    view.setBackgroundBrush(QBrush(bgPix))
    view.setCacheMode(QGraphicsView.CacheBackground)
    view.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
    view.show()

    states = QStateMachine()
    states.addState(rootState)
    states.setInitialState(rootState)
    rootState.setInitialState(centeredState)

    group = QParallelAnimationGroup()
    for i, item in enumerate(items):
        anim = QPropertyAnimation(item, b'pos')
        anim.setDuration(750 + i * 25)
        anim.setEasingCurve(QEasingCurve.InOutBack)
        group.addAnimation(anim)

    trans = rootState.addTransition(ellipseButton.pressed, ellipseState)
    trans.addAnimation(group)

    trans = rootState.addTransition(figure8Button.pressed, figure8State)
    trans.addAnimation(group)

    trans = rootState.addTransition(randomButton.pressed, randomState)
    trans.addAnimation(group)

    trans = rootState.addTransition(tiledButton.pressed, tiledState)
    trans.addAnimation(group)
예제 #36
0
class MatplotTinderUI(QWidget, UI):

    def __init__(self, parent=None):
        super().__init__(parent)

        matplot_widget = FigureCanvas(Figure())
        self._ax = matplot_widget.figure.subplots()

        self._scene = QGraphicsScene()
        self.matplot_graphics_widget = self._scene.addWidget(matplot_widget)
        self.matplot_graphics_widget.setParent(self)


        self.red_brush = QBrush(Qt.SolidPattern)
        self.red_brush.setColor(QColor(255, 0, 0, 50))

        self.pen = QPen()
        self.pen.setColor(QColor(0, 0, 0, 0))


        self._scene.addEllipse(0, self.height()/2, self.height()/2, self.height(), QPen(Qt.NoPen), self.red_brush)




        self._view = QGraphicsView(self._scene)
        self._view.setGeometry(250, 250, 500, 500)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._view)
        self.setLayout(layout)

        id = QGestureRecognizer.registerRecognizer(PanGestureRecognizer())
        self.grabGesture(id)

    def show_image(self, img, cmap=Defaults.cmap, interpolation='gaussian'):
        self._ax.clear()
        self._ax.axis('off')
        self._ax.imshow(img.data, cmap=cmap, interpolation=interpolation)
        self._ax.figure.canvas.draw()

    def connect_multi_classification_listener(self, action):
        pass

    def connect_single_classification_listener(self, action):
        pass

    def connect_skip_classification_listener(self, action):
        self.skip = action

    def event(self, event):
        if event.type() == QEvent.Gesture and event.gesture(Qt.PanGesture):
            self.pan_triggered(event.gesture(Qt.PanGesture))
        else:
            super().event(event)
        return True

    def pan_triggered(self, pan_gesture):
        delta = pan_gesture.delta()
        self.matplot_graphics_widget.setPos(self.matplot_graphics_widget.x() + delta.x(), self.matplot_graphics_widget.y() + delta.y())
        if pan_gesture.state() == Qt.GestureFinished:
            # self._check_if_classified()
            self.reset()

    def mouseDoubleClickEvent(self, a0):
        # self.reset()
        print('mouseclick')
        self.skip()

    def reset(self):
        self.animation = QPropertyAnimation(self.matplot_graphics_widget, b'pos')
        self.animation.setStartValue(self.matplot_graphics_widget.pos())
        self.animation.setEndValue(QPointF(100, 100))
        self.animation.setDuration(100)
        self.animation.start()

    def paintEvent(self, event):
        self.matplot_graphics_widget.setRotation(self.get_rotation())
        self.update()

    def get_rotation(self):
        pic = [self.matplot_graphics_widget.x(), -self.matplot_graphics_widget.y()]
        pivot = [0, -500]
        v1 = np.subtract(pic, pivot)
        v2 = np.subtract([0, 0], pivot)
        a = np.arccos(np.divide(np.abs(np.dot(v1, v2)), (np.linalg.norm(v1) * np.linalg.norm(v2))))
        if self.matplot_graphics_widget.x() < 0:
            return -a * 10
        return a * 10
예제 #37
0
class FlipWidget(QWidget):

    Left = 0  # 从右往左
    Right = 1  # 从左往右
    Scale = 3  # 图片缩放比例
    finished = pyqtSignal()

    def __init__(self, *args, **kwargs):
        super(FlipWidget, self).__init__(*args, **kwargs)
        # 无边框无任务栏
        self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint
                            | Qt.SubWindow)
        # 背景透明
        self.setAttribute(Qt.WA_TranslucentBackground, True)
        # 翻转角度
        self._angle = 0
        # 属性动画针对自定义属性`angle`
        self._animation = QPropertyAnimation(self, b'angle', self)
        self._animation.setDuration(550)
        self._animation.setEasingCurve(QEasingCurve.OutInQuad)
        self._animation.finished.connect(self.finished.emit)

    @pyqtProperty(int)
    def angle(self):
        return self._angle

    @angle.setter
    def angle(self, angle):
        self._angle = angle
        self.update()

    def updateImages(self, direction, image1, image2):
        """设置两张切换图
        :param direction:        方向
        :param image1:           图片1
        :param image2:           图片2
        """
        self.image1 = image1
        self.image2 = image2
        self.show()
        self._angle = 0
        # 根据方向设置动画的初始和结束值
        if direction == self.Right:
            self._animation.setStartValue(1)
            self._animation.setEndValue(-180)
        elif direction == self.Left:
            self._animation.setStartValue(1)
            self._animation.setEndValue(180)
        self._animation.start()

    def paintEvent(self, event):
        super(FlipWidget, self).paintEvent(event)

        if hasattr(self, 'image1') and hasattr(self,
                                               'image2') and self.isVisible():

            painter = QPainter(self)
            painter.setRenderHint(QPainter.Antialiasing, True)
            painter.setRenderHint(QPainter.SmoothPixmapTransform, True)

            # 变换
            transform = QTransform()
            # 把圆心设置为矩形中心
            transform.translate(self.width() / 2, self.height() / 2)

            if self._angle >= -90 and self._angle <= 90:
                # 当翻转角度在90范围内显示第一张图,且从大图缩放到小图的过程
                painter.save()
                # 设置翻转角度
                transform.rotate(self._angle, Qt.YAxis)
                painter.setTransform(transform)
                # 缩放图片高度
                width = self.image1.width() / 2
                height = int(self.image1.height() *
                             (1 - abs(self._angle / self.Scale) / 100))
                image = self.image1.scaled(self.image1.width(), height,
                                           Qt.IgnoreAspectRatio,
                                           Qt.SmoothTransformation)
                painter.drawPixmap(QPointF(-width, -height / 2), image)
                painter.restore()
            else:
                # 当翻转角度在90范围内显示第二张图,且从小图缩放到原图的过程
                painter.save()
                if self._angle > 0:
                    angle = 180 + self._angle
                else:
                    angle = self._angle - 180
                # 设置翻转角度, 注意这里角度有差异
                transform.rotate(angle, Qt.YAxis)
                painter.setTransform(transform)
                # 缩放图片高度
                width = self.image2.width() / 2
                height = int(self.image2.height() *
                             (1 - ((360 - abs(angle)) / self.Scale / 100)))
                image = self.image2.scaled(self.image2.width(), height,
                                           Qt.IgnoreAspectRatio,
                                           Qt.SmoothTransformation)
                painter.drawPixmap(QPointF(-width, -height / 2), image)
                painter.restore()
예제 #38
0
class AlternatePositionAnimation(object):
    """
    This class handles alternate position animation on widgets.
    It permits to move from a position to another and vice versa.
    """
    def __init__(self, parent):
        try:
            super(AlternatePositionAnimation, self).__init__(parent)
        except TypeError:
            super(AlternatePositionAnimation, self).__init__()

        # Get the caller widget to apply fade effect
        self.widget = vars()['self']

        self.show_animation = QPropertyAnimation(self.widget, b'pos')
        self.hide_animation = QPropertyAnimation(self.widget, b'pos')

        self.show_animation.setDuration(200)
        self.show_animation.setEasingCurve(QEasingCurve.Linear)

        self.hide_animation.setDuration(200)
        self.hide_animation.setEasingCurve(QEasingCurve.Linear)

        self.show_animation.finished.connect(self.show_finished_animation)
        self.hide_animation.finished.connect(self.hide_finished_animation)

    def set_animation_start_values(self):
        """
        Set different animation values.

        :param start: position when starting animation.
        :param end: position when finishing animation.
        :return:
        """
        beg_pos = self.window().width() - self.width() - 2
        end_pos = self.window().width() + self.width()
        print(beg_pos, end_pos, self.window(), self.width())
        start = QPoint(end_pos, 0)
        end = QPoint(beg_pos, 0)
        if not start or not end:
            return

        self.show_animation.setStartValue(QPoint(end_pos, 0))
        self.show_animation.setEndValue(QPoint(beg_pos, 0))

    def start_show(self):
        """
        Start the showing animation.

        :return:
        """

        self.set_animation_start_values()
        self.show_animation.start()

    def set_animation_hide_values(self):
        """
        Set different animation values.

        :param start: position when starting animation.
        :param end: position when finishing animation.
        :return:
        """
        beg_pos = self.window().width() - self.width() - 2
        end_pos = self.window().width() + self.width()
        print('hide', beg_pos, end_pos, self.window(), self.width())
        start = QPoint(end_pos, 0)
        end = QPoint(beg_pos, 0)
        if not start or not end:
            return

        self.hide_animation.setStartValue(QPoint(beg_pos, 0))
        self.hide_animation.setEndValue(QPoint(end_pos, 0))

    def start_hide(self):
        """
        Start the hiding animation.

        :return:
        """
        self.set_animation_hide_values()
        self.hide_animation.start()

    def show_finished_animation(self):
        """
        Function called when show animation is over.

        :return:
        """
        pass

    def hide_finished_animation(self):
        """
        Function called when hide animation is over.

        :return:
        """
        pass
예제 #39
0
class messageWidgetImpl(QWidget, Ui_messageWidget):
    # 初始化
    def __init__(self, timeout=6000, parent=None):
        super(messageWidgetImpl, self).__init__(parent)
        self.setupUi(self)
        log = logger()
        self.message = log.getlogger('gui')
        self._timeout = timeout
        self._init()

    def _init(self):
        # 是否正在显示标志
        self.isShowing = True
        # 超时
        self._hasFocus = False
        # 桌面对象
        self._desktop = QApplication.desktop()
        current_monitor = self._desktop.screenNumber(self)
        self._desktopGem = self._desktop.availableGeometry(current_monitor)
        # 窗口初始开始位置
        self._startPos = QPoint(
            self._desktopGem.x() + self._desktopGem.width() - self.width() - 5,
            self._desktopGem.y() + self._desktopGem.height())
        # 窗口弹出结束位置
        self._endPos = QPoint(
            self._desktopGem.x() + self._desktopGem.width() - self.width() - 5,
            self._desktopGem.y() + self._desktopGem.height() - self.height() -
            5)
        # 初始化位置到右下角
        self.move(self._startPos)
        # 动画
        self.animation = QPropertyAnimation(self, b"pos")
        self.animation.finished.connect(self.onAnimationEnd)
        self.animation.setDuration(2000)  # 2s
        # 弹回定时器
        self._timer = QTimer(self, timeout=self.closeAnimation)
        self.closeButton.clicked.connect(self.closeNow)

    def show(self, content=''):
        self._timer.stop()  # 停止定时器
        self.hide()
        self.move(self._startPos)
        self.setContent(content)
        super(messageWidgetImpl, self).show()
        return self

    #显示动画
    def showAnimation(self):
        self.message.debug('showAnimation')
        self.isShowing = True
        self.animation.stop()
        self.animation.setStartValue(self.pos())
        self.animation.setEndValue(self._endPos)
        self.animation.start()
        self._timer.start(self._timeout)

    # 关闭动画
    def closeAnimation(self):
        self.message.debug('closeAnimation')
        # 关闭动画
        if self.hasFocus():
            # 如果弹出后倒计时5秒后还有焦点存在则失去焦点后需要主动触发关闭
            self._hasFocus = True
            return  # 如果有焦点则不关闭
        self.isShowing = False
        self.animation.stop()
        self.animation.setStartValue(self.pos())
        self.animation.setEndValue(self._startPos)
        self.animation.start()

    # 动画结束
    def onAnimationEnd(self):
        if not self.isShowing:
            self.message.debug("onAnimationEnd close()")
            self.close()
            self.message.debug("onAnimationEnd stop timer")
            self._timer.stop()

    def closeNow(self):
        self.close()
        self._timer.stop()

    # 进入事件
    def enterEvent(self, QEvent):
        self.message.debug("enterEvent setFocus Qt.MouseFocusReason")
        self.setFocus(Qt.MouseFocusReason)

    # 离开事件
    def leaveEvent(self, QEvent):
        self.message.debug("leaveEvent clearFocus")
        self.clearFocus()
        if self._hasFocus:
            QTimer.start(1000, self.closeAnimation)

    # 设置内容
    def setContent(self, content):
        if content:
            self.label.setText(content)

    def content(self):
        return self.label.text()

    #设置超时
    def setTimeout(self, timeout):
        if isinstance(timeout, int):
            self._timeout = timeout
        return self

    def timeout(self):
        return self._timeout
예제 #40
0
class Widgets(QWidget):
    def __init__(self, parent=None):
        super(Widgets, self).__init__(parent)

        self.parent = parent

        self.initUI()

    def initUI(self):

        # ======================== WIDGETS ===========================

        framePrincipal = QFrame(self)
        framePrincipal.setFrameShape(QFrame.Box)
        framePrincipal.setFrameShadow(QFrame.Sunken)
        framePrincipal.setAutoFillBackground(True)
        framePrincipal.setBackgroundRole(QPalette.Light)
        framePrincipal.setFixedSize(662, 503)
        framePrincipal.move(10, 10)

        frame = QFrame(framePrincipal)
        frame.setFixedSize(640, 480)
        frame.move(10, 10)

        self.labelImagen = QLabel(frame)
        self.labelImagen.setAlignment(Qt.AlignCenter)
        self.labelImagen.setGeometry(0, 0, 640, 480)
        # self.labelImagen.setScaledContents(True)

        self.labelImagenUno = QLabel(frame)
        self.labelImagenUno.setAlignment(Qt.AlignCenter)
        self.labelImagenUno.setGeometry(-650, 0, 640, 480)

        # =================== BOTONES (QPUSHBUTTON) ==================

        self.buttonCargar = QPushButton("Cargar imagen", self)
        self.buttonCargar.setCursor(Qt.PointingHandCursor)
        self.buttonCargar.setFixedSize(325, 30)
        self.buttonCargar.move(10, 519)

        self.buttonEliminar = QPushButton("Eliminar imagen", self)
        self.buttonEliminar.setCursor(Qt.PointingHandCursor)
        self.buttonEliminar.setFixedSize(255, 30)
        self.buttonEliminar.move(345, 519)

        self.buttonAnterior = QPushButton("<", self)
        self.buttonAnterior.setObjectName("Anterior")
        self.buttonAnterior.setToolTip("Imagen anterior")
        self.buttonAnterior.setCursor(Qt.PointingHandCursor)
        self.buttonAnterior.setFixedSize(30, 30)
        self.buttonAnterior.move(607, 519)

        self.buttonSiguiente = QPushButton(">", self)
        self.buttonSiguiente.setObjectName("Siguiente")
        self.buttonSiguiente.setToolTip("Imagen siguiente")
        self.buttonSiguiente.setCursor(Qt.PointingHandCursor)
        self.buttonSiguiente.setFixedSize(30, 30)
        self.buttonSiguiente.move(642, 519)

        # ===================== CONECTAR SEÑALES =====================

        self.buttonCargar.clicked.connect(self.Cargar)
        self.buttonEliminar.clicked.connect(self.Eliminar)
        self.buttonAnterior.clicked.connect(self.anteriorSiguiente)
        self.buttonSiguiente.clicked.connect(self.anteriorSiguiente)

        # Establecer los valores predeterminados
        self.posicion = int
        self.estadoAnterior, self.estadoSiguiente = False, False
        self.carpetaActual = QDir()
        self.imagenesCarpeta = []

    # ======================= FUNCIONES ==============================

    def bloquearBotones(self, bool):
        self.buttonCargar.setEnabled(bool)
        self.buttonEliminar.setEnabled(bool)
        self.buttonAnterior.setEnabled(bool)
        self.buttonSiguiente.setEnabled(bool)

    def Mostrar(self, label, imagen, nombre, posicionX=650):
        imagen = QPixmap.fromImage(imagen)

        # Escalar imagen a 640x480 si el ancho es mayor a 640 o el alto mayor a 480
        if imagen.width() > 640 or imagen.height() > 480:
            imagen = imagen.scaled(640, 480, Qt.KeepAspectRatio,
                                   Qt.SmoothTransformation)

        # Mostrar imagen
        label.setPixmap(imagen)

        # Animación (al finalizar la animación se muestra en la barra de estado el nombre y la extensión de la imagen
        # y se desbloquean los botones).
        self.animacionMostar = QPropertyAnimation(label, b"geometry")
        self.animacionMostar.finished.connect(
            lambda: (self.parent.statusBar.showMessage(nombre),
                     self.bloquearBotones(True)))
        self.animacionMostar.setDuration(200)
        self.animacionMostar.setStartValue(QRect(posicionX, 0, 640, 480))
        self.animacionMostar.setEndValue(QRect(0, 0, 640, 480))
        self.animacionMostar.start(QAbstractAnimation.DeleteWhenStopped)

    def Limpiar(self,
                labelConImagen,
                labelMostrarImagen,
                imagen,
                nombre,
                posicionInternaX,
                posicionX=None):
        def Continuar(estado):
            if estado:
                if posicionX:
                    self.Mostrar(labelMostrarImagen, imagen, nombre, posicionX)
                else:
                    self.Mostrar(labelMostrarImagen, imagen, nombre)

        self.animacionLimpiar = QPropertyAnimation(labelConImagen, b"geometry")
        self.animacionLimpiar.finished.connect(lambda: labelConImagen.clear())
        self.animacionLimpiar.setDuration(200)
        # self.animacionLimpiar.valueChanged.connect(lambda x: print(x))
        self.animacionLimpiar.stateChanged.connect(Continuar)
        self.animacionLimpiar.setStartValue(QRect(0, 0, 640, 480))
        self.animacionLimpiar.setEndValue(QRect(posicionInternaX, 0, 640, 480))
        self.animacionLimpiar.start(QAbstractAnimation.DeleteWhenStopped)

    def Cargar(self):
        nombreImagen, _ = QFileDialog.getOpenFileName(
            self, "Seleccionar imagen", QDir.currentPath(),
            "Archivos de imagen (*.jpg *.png *.ico *.bmp)")

        if nombreImagen:
            # Verificar que QLabel tiene imagen
            labelConImagen = ""
            if self.labelImagen.pixmap():
                labelConImagen = self.labelImagen
            elif self.labelImagenUno.pixmap():
                labelConImagen = self.labelImagenUno

            imagen = QImage(nombreImagen)
            if imagen.isNull():
                if labelConImagen:
                    self.Eliminar()

                QMessageBox.information(
                    self, "Visor de imágenes",
                    "No se puede cargar %s." % nombreImagen)
                return

            # Obtener ruta de la carpeta que contiene la imagen seleccionada
            self.carpetaActual = QDir(
                QFileInfo(nombreImagen).absoluteDir().path())

            # Obtener la ruta y el nombre de las imagenes que se encuentren en la carpeta de
            # la imagen seleccionada
            imagenes = self.carpetaActual.entryInfoList(
                ["*.jpg", "*.png", "*.ico", "*.bmp"], QDir.Files, QDir.Name)
            self.imagenesCarpeta = [
                imagen.absoluteFilePath() for imagen in imagenes
            ]

            self.posicion = self.imagenesCarpeta.index(nombreImagen)
            self.estadoAnterior = True if self.posicion == 0 else False
            self.estadoSiguiente = True if self.posicion == len(
                self.imagenesCarpeta) - 1 else False

            # Función encargada de bloquear o desbloquear los botones
            self.bloquearBotones(False)

            # Nombre y extensión de la imagen
            nombre = QFileInfo(nombreImagen).fileName()

            if labelConImagen:
                posicionInternaX = -650
                labelMostrarImagen = self.labelImagen if self.labelImagenUno.pixmap(
                ) else self.labelImagenUno
                self.Limpiar(labelConImagen, labelMostrarImagen, imagen,
                             nombre, posicionInternaX)
            else:
                self.Mostrar(self.labelImagen, imagen, nombre)

    def Eliminar(self):
        def establecerValores():
            labelConImagen.clear()
            labelConImagen.move(0, 0)

            # Limpiar la barra de estado
            self.parent.statusBar.clearMessage()

            # Establecer los valores predeterminados
            self.posicion = int
            self.estadoAnterior, self.estadoSiguiente = False, False
            self.carpetaActual = QDir()
            self.imagenesCarpeta.clear()

            self.bloquearBotones(True)

        # Verificar que QLabel tiene imagen
        labelConImagen = ""
        if self.labelImagen.pixmap():
            labelConImagen = self.labelImagen
        elif self.labelImagenUno.pixmap():
            labelConImagen = self.labelImagenUno

        if labelConImagen:
            self.bloquearBotones(False)

            self.animacionEliminar = QPropertyAnimation(
                labelConImagen, b"geometry")
            self.animacionEliminar.finished.connect(establecerValores)
            self.animacionEliminar.setDuration(200)
            self.animacionEliminar.setStartValue(QRect(0, 0, 640, 480))
            self.animacionEliminar.setEndValue(QRect(-650, 0, 640, 480))
            self.animacionEliminar.start(QAbstractAnimation.DeleteWhenStopped)

    def anteriorSiguiente(self):
        if self.imagenesCarpeta:
            widget = self.sender().objectName()

            if widget == "Anterior":
                self.estadoAnterior = True if self.posicion == 0 else False
                self.estadoSiguiente = False

                self.posicion -= 1 if self.posicion > 0 else 0
                posicionInternaX, posicionX = 650, -650
            else:
                self.estadoSiguiente = True if self.posicion == len(
                    self.imagenesCarpeta) - 1 else False
                self.estadoAnterior = False

                self.posicion += 1 if self.posicion < len(
                    self.imagenesCarpeta) - 1 else 0
                posicionInternaX, posicionX = -650, 650

            if self.estadoAnterior or self.estadoSiguiente:
                return
            else:
                imagen = self.imagenesCarpeta[self.posicion]

                # Verificar que la carpeta que contiene la imagene exista
                if not QDir(self.carpetaActual).exists():
                    self.Eliminar()
                    return
                elif not QFile.exists(imagen):
                    # Obtener la ruta y el nombre de las imagenes que se encuentren en la
                    # carpeta de la imagen seleccionada
                    imagenes = self.carpetaActual.entryInfoList(
                        ["*.jpg", "*.png", "*.ico", "*.bmp"], QDir.Files,
                        QDir.Name)

                    if not imagenes:
                        self.Eliminar()
                        return

                    self.imagenesCarpeta = [
                        imagen.absoluteFilePath() for imagen in imagenes
                    ]

                    self.posicion = randint(0, len(self.imagenesCarpeta) - 1)
                    self.estadoAnterior = True if self.posicion == 0 else False
                    self.estadoSiguiente = True if self.posicion == len(
                        self.imagenesCarpeta) - 1 else False
                elif QImage(imagen).isNull():
                    del self.imagenesCarpeta[self.posicion]

                    if not self.imagenesCarpeta:
                        self.Eliminar()
                        return

                    self.posicion = randint(0, len(self.imagenesCarpeta) - 1)
                    self.estadoAnterior = True if self.posicion == 0 else False
                    self.estadoSiguiente = True if self.posicion == len(
                        self.imagenesCarpeta) - 1 else False

                imagen = self.imagenesCarpeta[self.posicion]

                if self.labelImagen.pixmap():
                    labelConImagen = self.labelImagen
                elif self.labelImagenUno.pixmap():
                    labelConImagen = self.labelImagenUno

                # Función encargada de bloquear o desbloquear los botones
                self.bloquearBotones(False)

                # Nombre y extensión de la imagen
                nombre = QFileInfo(imagen).fileName()

                # Label en el que se va a mostrar la imagen
                labelMostrarImagen = self.labelImagen if self.labelImagenUno.pixmap(
                ) else self.labelImagenUno

                # Quitar la imagen actual y mostrar la siguiente
                self.Limpiar(labelConImagen, labelMostrarImagen,
                             QImage(imagen), nombre, posicionInternaX,
                             posicionX)
예제 #41
0
class DropdownWidget(QWidget):
    def __init__(self, parent=None, name="Total"):
        super(DropdownWidget, self).__init__(parent)
        self.name = name
        self.isOpen = False
        self.isButton = False

        layout = QVBoxLayout()
        layout.setSpacing(0)
        self.bar = MyProgressBar(parent)
        font = QFont()
        font.setFamily("Tahoma")
        font.setPointSize(15)
        self.bar.setFont(font)
        self.bar.setProperty("value", 0)
        self.bar.setValue(0)
        self.bar.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter)
        self.bar.setTextVisible(True)
        self.bar.setObjectName(self.name)
        layout.addWidget(self.bar)
        self.data = QScrollArea(self)
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.Minimum)
        self.data.setSizePolicy(sizePolicy)
        self.data.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.data.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.data.setMaximumHeight(0)
        self.data.setObjectName("DropdownSA")
        self.data.setFrameShape(QFrame.NoFrame)
        self.data.setStyleSheet(
            "QScrollArea {"
            "background-color: qlineargradient(spread:pad, "
            "x1:0, y1:0, x2:1, y2:1, stop:0 rgb(192, 221, 221), "
            "stop:1 rgb(180, 233, 197));}")
        self.data.setWidgetResizable(True)
        if name == "Total":
            self.dataWidget = DataWidget(self.data, mult=2)
        else:
            self.dataWidget = DataWidget(self.data)
        self.data.setWidget(self.dataWidget)
        layout.addWidget(self.data)
        self.setLayout(layout)

        self.bar.setFormat("   ▶  " + self.name)

        self.anim = QPropertyAnimation(self.data, b"maximumHeight")
        self.anim.setDuration(500)
        self.anim.setEasingCurve(QEasingCurve.InOutSine)
        self.anim.valueChanged.connect(self.animationEvent)

        # self.bar.mouseClicked.connect(self.onClick)

    def onClick(self):
        self.anim.stop()
        self.anim.setStartValue(self.data.maximumHeight())
        if self.isOpen:
            self.isOpen = False
            self.anim.setDuration(250)
            self.bar.setFormat("   ▶  " + self.name)
            self.anim.setEndValue(0)
        else:
            self.isOpen = True
            self.anim.setDuration(500)
            self.bar.setFormat("   ▾  " + self.name)
            self.anim.setEndValue(450)
            self.dataWidget.startAnimation()
        self.anim.start()

    def updateResults(self, results):
        if results["RunTime"] > 0.1 and not self.isButton:
            self.toggleButton()
        elif results["RunTime"] < 0.1 and self.isButton:
            self.toggleButton()
        v = (results["RunTime"] / self.dataWidget.runtimeTarget[1]) * 100
        if v > 99:
            v = 100
        v = int(v)
        self.bar.setProperty("Value", v)
        self.bar.setValue(v)
        self.dataWidget.updateResults(results)

    def toggleButton(self):
        if self.isButton:
            self.isButton = False
            self.bar.setCursor(QCursor(Qt.ArrowCursor))
            self.bar.mouseClicked.disconnect()
        else:
            self.isButton = True
            self.bar.setCursor(QCursor(Qt.PointingHandCursor))
            self.bar.mouseClicked.connect(self.onClick)

    def animationEvent(self, val):
        self.data.setMinimumHeight(min(425, val))
예제 #42
0
class terminal(Window):
    def __init__(self):
        super(
            terminal,
            self,
        ).__init__()
        self.resize(900, 600)
        self.setObjectName('terminal')
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
        self.Main_HB = QtWidgets.QHBoxLayout()
        Pixmap = QtGui.QPixmap()
        Pixmap.loadFromData(
            base64.b64decode(bytes(Maimwin_ico, encoding='utf-8')))
        self.Window_out = False
        ico = QtGui.QIcon()
        ico.addPixmap(Pixmap)
        self.iclab = QLabel(self)
        self.tab_menu = QtWidgets.QPushButton('☰', self)
        self.tab_menu.setStyleSheet(
            'line-height: 0.1;font: 7pt "微软雅黑";border-top-right-radius:10px;')
        self.tab_menu.setObjectName("tabmenu")
        self.tab_menu.clicked.connect(self.Title_men)
        self.tab_menu.setMaximumSize(30, 30)
        self.tab_menu.setMinimumSize(30, 30)
        self._MinimumButton = QHead_Button(b'\xef\x80\xb0'.decode("utf-8"),
                                           self)
        self._MinimumButton.setObjectName("MinMaxButton")
        self._MinimumButton.setMaximumSize(30, 30)
        self._MinimumButton.setMinimumSize(30, 30)
        self._MinimumButton.clicked.connect(self.showMinimized)

        self.iclab.setMaximumSize(30, 30)
        self.iclab.setMinimumSize(30, 30)
        self.iclab.setScaledContents(True)
        self.iclab.setPixmap(Pixmap)
        self.setWindowIcon(ico)
        self.Main_HB.addWidget(self.iclab)

        self.title_tab = table(self)
        self.title_tab.setMinimumSize(38, 38)
        self.title_tab.add_tab.clicked.connect(self.Init_lab)
        # self.title_tab.setGeometry(38,0,self.width() - self._ClosButton.width()-38,48)
        # self.title_tab.setStyleSheet('background-color:#FFFFFF')
        # self.title_hb.addWidget(self.title_tab)
        self.Main_HB.addWidget(self.title_tab)
        self.Main_HB.addWidget(self.tab_menu)

        self.Main_HB.addWidget(self._MinimumButton)
        self.Main_HB.addWidget(self._MaximumButton)
        self.Main_HB.addWidget(self._ClosButton)
        self.Main_HB.setContentsMargins(5, 0, 0, 0)
        self.verticalLayout_main.addLayout(self.Main_HB)
        self.window_docker = QStackedWidget(self)

        # spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout_main.addWidget(self.window_docker)
        # self.verticalLayout_main.addItem(spacerItem)
        self.verticalLayout_main.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_main.setSpacing(0)
        self._Men = QtWidgets.QMenu(self)
        # self._Men.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        self._Men.setAttribute(QtCore.Qt.WA_TranslucentBackground)

        self._Men.setObjectName('TabMen')
        self.Host_often = self._Men.addAction('最近会话')
        self.Host_list = self._Men.addAction('远程管理')
        self.Host_list.triggered.connect(lambda: self.Host_win(True))
        self.Theme = self._Men.addAction('切换主题')
        self._Men.addSeparator()
        self.Setting = self._Men.addAction('设置')
        self.Help = self._Men.addAction('帮助')
        self.Author = self._Men.addAction('关于')
        # self._ClosButton.move(self.width() - self._ClosButton.width() - 1, 5)
        # float_host = QtWidgets.QVBoxLayout(self)
        self.HostListWindow = HostWindow(self)
        # self.HostListWindow = HostWindow()

        # self.HostListWindow.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        self.HostListWindow.Send_host.connect(self.Add_lab)
        # self.HostListWindow.

        self.win_out = QPropertyAnimation(self.HostListWindow, b"geometry")
        self.win_out.setDuration(300)

        # float_host.addWidget(self.HostListWindow)
        # self.title_hb = QtWidgets.QHBoxLayout(self)
        # self.title_tab = table(self)
        # self.title_tab.setGeometry(38,0,self.width() - self._ClosButton.width()-38,48)
        # self.title_tab.setStyleSheet('background-color:#FFFFFF')
        # self.title_hb.addWidget(self.title_tab)

        # def enterEvent(self,QMouseEvent):
        #     self.setMouseTracking(True)
        self.Lable_viwe = []
        self.Init_lab()
        # self.winqss()
        # def winqss(self):

        self.setStyleSheet(''' 
        
                   QTableView
                       {
                           outline:0px;
                       }
            
            QWidget#main_widget{
                       border-top-right-radius:10px;
                       border-top-left-radius:10px;
                       border-bottom-left-radius:4px;
                       border-bottom-right-radius:4px;
                       /*background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:1 rgba(0, 0, 0, 163));*/
                       /*background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:1 rgba(0, 0, 0, 200));*/
                       background-color: qlineargradient(spread:pad, x1:0.506, y1:0.567818, x2:1, y2:0, stop:1 rgba(0, 37, 56, 200));

             }
             
             QWebEngineView#QWebEng{
                background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:1 rgba(0, 0, 0, 163));
             }
             
             QWidget#QWebEng{
                background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:1 rgba(0, 0, 0, 163));
             }
              QWidget#HostItemWidget:hover{
                background-color:#111111;
            }
            QWidget#UpdateHostWindow{
            background-color:#000000;
            color:#FFFFFF;
            }
             QWidget#HostListWindow{
             background-color:#000000;

             }
             
              QPushButton:hover{
              background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:1 rgba(47, 47, 47, 171));
              }
             QPushButton{
              color:#CCCCCC;
               border:none;
               /*font-family: "微软雅黑";*/
               border-radius:3px;
               background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:1 rgba(37, 37, 37, 171));
             }

             QPushButton#Left_QPush{
             color:#CCCCCC;
             border:none;
             background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 0, 0, 0), stop:1 rgba(255, 255, 255, 0));
             }
             /*
              QPushButton{
                color:#CCCCCC;
                border:none;
                background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 0, 0, 0), stop:1 rgba(255, 255, 255, 0));
              }*/





             QPushButton#AddHost:hover{
             background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:1 rgba(47, 47, 47, 171));
             }

                       QPushButton#subButton{
                           border:none;
                           border-radius:3px;
                           line-height: 1;
                           font: 10pt "微软雅黑";
                           padding: 0px;
                           color:#FFFFFF;
                            background-color:#CC6633;
                           outline: none;
                       }
                       QPushButton#subButton:hover {
                            background-color:#AAAAAA;

                       }
                       QPushButton#toolbarbutton{
                           border:none;
                           line-height: 1;
                           font: 10pt "微软雅黑";
                           padding: 9px;
                           text-align:left;
                           outline: none;
                       }
                        QPushButton#toolbarbutton:hover {
                            background-color:#AAAAAA;

                       }

                       QPushButton#toolbarbutton:focus
                       {

                            background-color:#CCCCCC;
                       }
                       QPushButton#ClosButton,#MinMaxButton,#tabmenu,#MinMaxButton{
                       color:#AAAAAA;
                       border:0px;
                       background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 0, 0, 0), stop:1 rgba(255, 255, 255, 0));
                       }
                       QPushButton#MinMaxButton:hover,#tabmenu:hover,#MinMaxButton:hover{
                           color:#FFFFFF
                       }

                       QPushButton#ClosButton:hover{
                           color:#FF0033
                       }
                        
                       QLabel{
                           line-height: 1.5;
                           color:#999999;
                           font: 6pt "微软雅黑";
                           font-weight: normal;
                           opacity: 0.7;
                           font-size: 16px;
                       }
                        QLabel#TitleLabel{
                        color: #000000;
                        }
                       QLabel#HostItemTitleName{
                       color:#CCCCCC;

                       font: 8pt "微软雅黑";
                       }
                       QLabel#HostItemHost{
                       color:#555555;

                       font: 7pt "微软雅黑";
                       }
                   QLineEdit
                   {
                       background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 0, 0, 0), stop:1 rgba(255, 255, 255, 0));
                       padding: 5px;
                       border-style: solid;
                       border: 1px solid #00CCFF;
                       border-radius: 2px;
                       color: #999999;

                   }
                   QWebEngineView{
                   background-color: #FFFFFF;
                   }
                   QLineEdit:hover
                   {
                       border: 1px solid #99CC99;

                   }
                   
                   QMenu#TabMen{
                  /* font: 9pt "SimSun";*/
                   font-weight: 400;
                   width: 128px;
                   color:#333333;
                   background-color:  #F7F7F7;
                    border-radius: 5px;
                   }
                   QMenu::item
                    {
                    background-color: transparent;
                    padding:3px 30px;
                    margin:2px 0px; 
                    }
                    QMenu::item:selected
                    {
                        background-color:#00CCFF;
                    }
                    QMenu::separator {
                        height: 2px;
                        background: lightblue;
                        margin-left: 0px;
                        margin-right: 5px;
                    }
                    QMenu::indicator {
                        width: 18px;
                        height: 18px;
                    }
                    
                    QTableWidget#HostTabWindow{
                    border-top: 1px solid #76797C;
                    border-bottom: 1px solid #76797C;
                    background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 0, 0, 0), stop:1 rgba(255, 255, 255, 0));
                    }

                   QScrollBar:vertical
        {
           /* background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 0, 0, 0), stop:1 rgba(255, 255, 255, 0));
            */
            background-color:#111111;
            width: 10px;
            margin: 15px 3px 15px 3px;
            border: 0px transparent #2A2929;
            border-radius: 4px;
        }
        QScrollBar::handle:vertical
        {
            /*background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:1 rgba(0, 0, 0, 80));
            */
            background-color: #222222;
            min-height: 5px;
            border-radius: 4px;
        }

        QScrollBar::sub-line:vertical
        {
            margin: 3px 0px 3px 0px;
            border-image: url(rc/up_arrow_disabled.png);
            height: 10px;
            width: 10px;
            subcontrol-position: top;
            subcontrol-origin: margin;
        }

        QScrollBar::add-line:vertical
        {
            margin: 3px 0px 3px 0px;
            border-image: url(rc/down_arrow_disabled.png);
            height: 10px;
            width: 10px;
            subcontrol-position: bottom;
            subcontrol-origin: margin;
        }

        QScrollBar::sub-line:vertical:hover,QScrollBar::sub-line:vertical:on
        {

            border-image: url(rc/up_arrow.png);
            height: 10px;
            width: 10px;
            subcontrol-position: top;
            subcontrol-origin: margin;
        }


        QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on
        {
            border-image: url(rc/down_arrow.png);
            height: 10px;
            width: 10px;
            subcontrol-position: bottom;
            subcontrol-origin: margin;
        }

        QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical
        {
            background: none;
        }


        QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical
        {
            background: none;
        }
        

                           ''')

    def Remove_lab(self, window):
        print(window)

        if len(self.Lable_viwe) != 1:
            window[1].setParent(None)
            self.title_tab.horizontalLayout.removeWidget(window[1])
            self.Lable_viwe.remove(window[1])
            self.window_docker.removeWidget(window[0])
            del window[1]
        else:
            print('关闭主窗口')
        print(self.Lable_viwe, self.window_docker.count())
        # self.window_docker.indexOf()
    def show_docker(self, window=None):

        self.window_docker.setCurrentWidget(window[0])
        # self.window_docker.setCurrentIndex(1)
    def Init_lab(self):
        term = Term(data={}, open_win=False)
        label = ItemWidget('本地Shell', term)
        # itemwidget = ItemWidget(label)
        # itemwidget.Send_env.connect(self.Remove_lab)
        label.Send_env.connect(self.Remove_lab)
        label.Send_ck.connect(self.show_docker)
        self.Lable_viwe.append(label)
        self.window_docker.addWidget(term)
        cont = len(self.Lable_viwe) - 1
        self.title_tab.horizontalLayout.addWidget(self.Lable_viwe[cont])
        # self.title_tab.horizontalLayout.addWidget(self.Lable_viwe[len(self.Lable_viwe)-1])

    def Add_lab(self, host):
        print(host)
        data = {
            'host': host[2],
            'port': host[3],
            'username': host[4],
            'ispwd': True,
            'secret': host[5]
        }
        term = Term(data=data, open_win=True)
        label = ItemWidget(host[1], term)
        label.Send_env.connect(self.Remove_lab)
        label.Send_ck.connect(self.show_docker)
        self.Lable_viwe.append(label)
        self.window_docker.addWidget(term)
        self.title_tab.horizontalLayout.addWidget(
            self.Lable_viwe[len(self.Lable_viwe) - 1])
        self.window_docker.setCurrentIndex(len(self.Lable_viwe) - 1)

    def Title_men(self):
        self._Men.exec_(
            self.tab_menu.mapToGlobal(
                QtCore.QPoint(-40, self.tab_menu.height())))

    def Host_win(self, win_type=True):
        self.Window_out = True

        self.HostListWindow.setGeometry(0, 38, 360, self.height() - 38)
        self.win_out.setStartValue(
            QtCore.QRect(self.width() if win_type else self.width() - 360, 38,
                         360,
                         self.height() - 38))
        self.win_out.setEndValue(
            QRect(self.width() - 360 if win_type else self.width(), 38, 360,
                  self.height() - 38))
        # if win_type:
        #     self.HostListWindow.show()
        # else:
        #     pass
        # self.HostListWindow.hide()

        self.win_out.start()

    def resizeEvent(self, QResizeEvent):
        self._TitleLabel.setGeometry(0, 0, self.width(), 38)
        if self.Window_out:
            self.HostListWindow.setGeometry(self.width() - 360, 38, 360,
                                            self.height() - 38)
        else:
            self.HostListWindow.setGeometry(self.width(), 38, 360,
                                            self.height() - 38)
        self._right_rect = [
            QPoint(x, y) for x in range(self.width() - self._padding,
                                        self.width() + 1)
            for y in range(1,
                           self.height() - self._padding)
        ]
        self._bottom_rect = [
            QPoint(x, y) for x in range(1,
                                        self.width() - self._padding)
            for y in range(self.height() - self._padding,
                           self.height() + 1)
        ]
        self._corner_rect = [
            QPoint(x, y) for x in range(self.width() - self._padding,
                                        self.width() + 1)
            for y in range(self.height() - self._padding,
                           self.height() + 1)
        ]

    def mousePressEvent(self, event):
        if self.Window_out:
            self.Host_win(False)
            self.Window_out = False
        # 重写鼠标点击的事件
        if event.y() < 42:
            self._MoveVarl = True
            self.move_DragPosition = event.globalPos() - self.pos()
            event.accept()

        elif (event.button() == Qt.LeftButton) and (event.pos()
                                                    in self._corner_rect):
            # 鼠标左键点击右下角边界区域
            self._corner_drag = True
            event.accept()
        elif (event.button() == Qt.LeftButton) and (event.pos()
                                                    in self._right_rect):
            # 鼠标左键点击右侧边界区域
            self._right_drag = True
            event.accept()
        elif (event.button() == Qt.LeftButton) and (event.pos()
                                                    in self._bottom_rect):
            # 鼠标左键点击下侧边界区域
            self._bottom_drag = True
            event.accept()
        elif (event.button()
              == Qt.LeftButton) and (event.y() < self._TitleLabel.height()):
            # 鼠标左键点击标题栏区域
            self._move_drag = True
            self.move_DragPosition = event.globalPos() - self.pos()
            event.accept()
예제 #43
0
from PyQt5.QtCore import QPropertyAnimation, QEasingCurve


animation = QPropertyAnimation()
animation.setTargetObject()
animation.setStartValue(0)
animation.setEndValue(1000)
animation.setDuration(1000)
animation.setEasingCurve(QEasingCurve.InOutQuad)

animation.start()
예제 #44
0
class FancyButton(QToolButton):

    def __init__(self, text="", parent=None):
        super().__init__(parent)
        self.setAttribute(Qt.WA_Hover, True)
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        if text:
            self.setText(text)
        self._fader = 0

    def _set_fader(self, value):
        self._fader = value
        self.update()

    def _get_fader(self):
        return self._fader

    fader = pyqtProperty(float, fget=_get_fader, fset=_set_fader)

    def event(self, event):
        if event.type() == QEvent.Enter:
            self.anim = QPropertyAnimation(self, b"fader")
            self.anim.setDuration(150)
            self.anim.setEndValue(1.0)
            self.anim.start(QPropertyAnimation.DeleteWhenStopped)
        elif event.type() == QEvent.Leave:
            self.anim = QPropertyAnimation(self, b"fader")
            self.anim.setDuration(124)
            self.anim.setEndValue(0.0)
            self.anim.start(QPropertyAnimation.DeleteWhenStopped)
        else:
            return QToolButton.event(self, event)
        return False

    def paintEvent(self, event):
        painter = QPainter(self)
        if self.isEnabled() and not self.isDown() and not self.isChecked():
            painter.save()
            hover_color = QColor("#424242")
            faded_hover_color = QColor(hover_color)
            faded_hover_color.setAlpha(int(self._fader * hover_color.alpha()))
            painter.fillRect(event.rect(), faded_hover_color)
            painter.restore()
        elif self.isDown() or self.isChecked():
            painter.save()
            selected_color = QColor("#090909")
            painter.fillRect(event.rect(), selected_color)
            painter.restore()
        # fm = QFontMetrics(painter.font())
        # rect = QRect(-3, 2, self.rect().width(), fm.height())
        rect = event.rect()
        icon_rect = QRect(0, 0, 22, 22)
        self.icon().paint(painter, icon_rect, Qt.AlignVCenter)
        painter.drawText(
            rect.adjusted(0, 0, -3, 0),
            Qt.AlignRight | Qt.AlignVCenter, self.text())

    def sizeHint(self):
        self.ensurePolished()
        s = self.fontMetrics().size(Qt.TextSingleLine, self.text())
        s.setWidth(s.width() + 25)
        return s.expandedTo(QApplication.globalStrut())
예제 #45
0
class ScreensharingToolbox(base_class, ui_class):
    exposedPixels = 3

    def __init__(self, parent):
        super(ScreensharingToolbox, self).__init__(parent)
        with Resources.directory:
            self.setupUi()
        parent.installEventFilter(self)
        self.animation = QPropertyAnimation(self, 'pos')
        self.animation.setDuration(250)
        self.animation.setDirection(QPropertyAnimation.Forward)
        self.animation.setEasingCurve(QEasingCurve.Linear)  # or OutCirc with 300ms
        self.retract_timer = QTimer(self)
        self.retract_timer.setInterval(3000)
        self.retract_timer.setSingleShot(True)
        self.retract_timer.timeout.connect(self.retract)
        self.resize(self.size().expandedTo(self.toolbox_layout.minimumSize()))

    def setupUi(self):
        super(ScreensharingToolbox, self).setupUi(self)

        # fix the SVG icons, as the generated code loads them as pixmaps, losing their ability to scale -Dan
        scale_icon = QIcon()
        scale_icon.addFile(Resources.get('icons/scale.svg'), mode=QIcon.Normal, state=QIcon.Off)
        viewonly_icon = QIcon()
        viewonly_icon.addFile(Resources.get('icons/viewonly.svg'), mode=QIcon.Normal, state=QIcon.Off)
        screenshot_icon = QIcon()
        screenshot_icon.addFile(Resources.get('icons/screenshot.svg'), mode=QIcon.Normal, state=QIcon.Off)
        fullscreen_icon = QIcon()
        fullscreen_icon.addFile(Resources.get('icons/fullscreen.svg'), mode=QIcon.Normal, state=QIcon.Off)
        fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'), mode=QIcon.Normal, state=QIcon.On)
        fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'), mode=QIcon.Active, state=QIcon.On)
        fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'), mode=QIcon.Disabled, state=QIcon.On)
        fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'), mode=QIcon.Selected, state=QIcon.On)
        minimize_icon = QIcon()
        minimize_icon.addFile(Resources.get('icons/minimize.svg'), mode=QIcon.Normal, state=QIcon.Off)
        minimize_icon.addFile(Resources.get('icons/minimize-active.svg'), mode=QIcon.Active, state=QIcon.Off)
        close_icon = QIcon()
        close_icon.addFile(Resources.get('icons/close.svg'), mode=QIcon.Normal, state=QIcon.Off)
        close_icon.addFile(Resources.get('icons/close-active.svg'), mode=QIcon.Active, state=QIcon.Off)

        self.scale_action.setIcon(scale_icon)
        self.viewonly_action.setIcon(viewonly_icon)
        self.screenshot_action.setIcon(screenshot_icon)
        self.fullscreen_action.setIcon(fullscreen_icon)
        self.minimize_action.setIcon(minimize_icon)
        self.close_action.setIcon(close_icon)

        self.scale_button.setIcon(scale_icon)
        self.viewonly_button.setIcon(viewonly_icon)
        self.screenshot_button.setIcon(screenshot_icon)
        self.fullscreen_button.setIcon(fullscreen_icon)
        self.minimize_button.setIcon(minimize_icon)
        self.close_button.setIcon(close_icon)

        self.scale_button.setDefaultAction(self.scale_action)
        self.viewonly_button.setDefaultAction(self.viewonly_action)
        self.screenshot_button.setDefaultAction(self.screenshot_action)
        self.fullscreen_button.setDefaultAction(self.fullscreen_action)
        self.minimize_button.setDefaultAction(self.minimize_action)
        self.close_button.setDefaultAction(self.close_action)

        self.color_depth_button.clear()
        self.color_depth_button.addItem('Default Color Depth', ServerDefault)
        self.color_depth_button.addItem('TrueColor (24 bits)', TrueColor)
        self.color_depth_button.addItem('HighColor (16 bits)', HighColor)
        self.color_depth_button.addItem('LowColor (8 bits)', LowColor)

    def eventFilter(self, watched, event):
        if watched is self.parent() and event.type() == QEvent.Resize:
            new_x = (watched.width() - self.width()) / 2
            self.move(new_x, self.y())
            self.animation.setStartValue(QPoint(new_x, -self.height() + self.exposedPixels))
            self.animation.setEndValue(QPoint(new_x, 0))
        return False

    def enterEvent(self, event):
        super(ScreensharingToolbox, self).enterEvent(event)
        self.retract_timer.stop()
        self.expose()

    def leaveEvent(self, event):
        super(ScreensharingToolbox, self).leaveEvent(event)
        self.retract_timer.start()

    def paintEvent(self, event):  # make the widget style aware
        option = QStyleOption()
        option.initFrom(self)
        painter = QStylePainter(self)
        painter.drawPrimitive(QStyle.PE_Widget, option)

    def expose(self):
        if self.animation.state() == QPropertyAnimation.Running and self.animation.direction() == QPropertyAnimation.Forward:
            return
        elif self.animation.state() == QPropertyAnimation.Stopped and self.pos() == self.animation.endValue():
            return
        self.animation.setDirection(QPropertyAnimation.Forward)
        self.animation.start()

    def retract(self):
        if self.animation.state() == QPropertyAnimation.Running and self.animation.direction() == QPropertyAnimation.Backward:
            return
        elif self.animation.state() == QPropertyAnimation.Stopped and self.pos() == self.animation.startValue():
            return
        self.animation.setDirection(QPropertyAnimation.Backward)
        self.animation.start()
예제 #46
0
            QRect(150, 100, 50, 50), button3, QRect(100, 150, 50, 50), button4,
            QRect(150, 150, 50, 50), group)

    state6 = createGeometryState(button1, QRect(50, 50, 50, 50), button2,
            QRect(200, 50, 50, 50), button3, QRect(50, 200, 50, 50), button4,
            QRect(200, 200, 50, 50), group)

    state7 = createGeometryState(button1, QRect(0, 0, 50, 50), button2,
            QRect(250, 0, 50, 50), button3, QRect(0, 250, 50, 50), button4,
            QRect(250, 250, 50, 50), group)

    group.setInitialState(state1)

    animationGroup = QParallelAnimationGroup()
    anim = QPropertyAnimation(button4, 'geometry')
    anim.setDuration(1000)
    anim.setEasingCurve(QEasingCurve.OutElastic)
    animationGroup.addAnimation(anim)

    subGroup = QSequentialAnimationGroup(animationGroup)
    subGroup.addPause(100)
    anim = QPropertyAnimation(button3, 'geometry')
    anim.setDuration(1000)
    anim.setEasingCurve(QEasingCurve.OutElastic)
    subGroup.addAnimation(anim)

    subGroup = QSequentialAnimationGroup(animationGroup)
    subGroup.addPause(150)
    anim = QPropertyAnimation(button2, 'geometry')
    anim.setDuration(1000)
    anim.setEasingCurve(QEasingCurve.OutElastic)
예제 #47
0
파일: blueApp.py 프로젝트: blackskygg/jielu
class BlueApp:
    def __init__(self, argv):
        self.app = QApplication(argv)

        self.mainWindow = QtWidgets.QMainWindow()
        self.mainWindow.closeEvent = self.onClose
        self.ui = blueMainUi.Ui_MainWindow()
        self.ui.setupUi(self.mainWindow)


        #settings and statistics
        self.defaultSettings = dict(image_detect=True, text_detect=True,
                                    game_type=0, pipeRank=0,
                                    goal = 10, startDate = time.time(),
                                    avata = "res/icon.png", name = "窜天猴")
        self.defaultStat = dict(stat = [ [0, 0, 0, 0] for i in range(7)],
                                achivement = 0, lastWater = 0, lastFertilize = 0,
                                cleanHours = 0, cleanMinutes = 0)
        self.achivementsList = ["大淫魔", "从头开始", "欲火渐盛",
                                "钢筋铁骨", "渐入佳境","心无杂念"]
        self.achivementsStd = [0, 24, 24 * 3, 24 * 7, 24 * 31, 27 * 365]
        self.loadSettings()
        self.validateSettings()
        self.loadStatistics()

        #setup the visibles
        self.setupUi2()
        self.setupWidget1()
        self.setupWidget2()
        self.setupWidget3()
        self.setupWidget4()
        self.refreshStatistics()


        #setup porn_detector
        self.devMode = False
        self.timeToExit = False
        self.pornDectector = porn_detector_final.PornDetector()
        self.pornDetected = False
        self.detectThread = threading.Thread(target = self.detectPorn)
        self.detectThread.start()
        self.alarm = False  #first alarm, then take action

        #setup timer
        self.cleanMinute = 0
        self.MinuteTimer = QTimer()
        self.MinuteTimer.setInterval(1000 * 60)
        self.MinuteTimer.timeout.connect(self.addCleanMinute)
        self.MinuteTimer.start()


        #lauch
        self.mainWindow.show()

        self.connections()

    def addCleanMinute(self):
        self.stat["cleanMinutes"] += 1
        if self.stat["cleanMinutes"] == 60:
            self.self.stat["cleanMinutes"] = 0
            self.stat["cleanHours"] += 1
            self.saveStatistics()
            self.refreshStatistics()
            self.checkLevel()

    def call_zqz(self):
        if self.settings["game_type"] == 0:
            os.system("python2 easy_maze/PyMaze.py")
        else :
            os.system("python2 esay_game/play.py")
        QtWidgets.QMessageBox.information(None, "bluer", "你有10s的时间关掉黄黄的东西。")
        time.sleep(10)



    def detectPorn(self):
        while(True):
            if "PORN_DETECTED" == self.pornDectector.porn_detector(self.settings["image_detect"], self.settings["text_detect"], self.devMode):
                if self.alarm:
                    self.call_zqz()
                    self.stat["cleanHours"] -= 24
                    if self.stat["cleanHours"] < 0:
                        self.stat["cleanHours"] = 0

                    l = self.stat["stat"][time.localtime(time.time())[6]]
                    h = time.localtime(time.time())[3]
                    if h >= 0 and h < 6:
                        l[0] = 1
                    elif h >= 6 and h < 12:
                        l[1] = 1
                    elif h >= 12 and h < 18:
                        l[2] = 1;
                    else:
                        l[3] = 1;
                else:
                    self.alarm = True
            else:
                self.alarm = True

                self.saveStatistics()
                self.refreshStatistics()

            time.sleep(10)

    def onClose(self, event):
        self.mainWindow.hide()
        event.ignore()

    def onTrayClicked(self, event):
        if event == QSystemTrayIcon.Trigger or event == QSystemTrayIcon.DoubleClick:
            self.mainWindow.show()

    def saveSettings(self, event):
        QtWidgets.QMessageBox.Question = QIcon("res/logo-tray.png")
        if self.settings["goal"] != self.ui.spin_goal.value():
            ret = QtWidgets.QMessageBox.question(self.mainWindow, "Blue", "确定要将目标改为" + str(self.ui.spin_goal.value()) + "天吗?\n"
                                                 "此操作会重置当前任务的进度。")

            if ret != QtWidgets.QMessageBox.No:
                self.settings["goal"] = self.ui.spin_goal.value()
                self.saveStatistics()
                self.refreshStatistics()
                QtWidgets.QMessageBox.information(None, "Blue", "新目标设置为" + str(self.settings["goal"]) + "天")
            else:
                QtWidgets.QMessageBox.information(None, "Blue", "目标没有被重置")

        try:
            sfile = open(PATH_TO_SETTINGS, "w")
            json.dump(self.settings, sfile)
            sfile.close()
        except Exception:
            return

        QtWidgets.QMessageBox.information(None, "Blue", "设置已保存:D")

        self.refreshStatistics()

    def checkLevel(self):
        for i in range(5, -1, -1):
            if self.stat["cleanHours"] >= self.achivementsStd[i] and self.stat["achivement"] < i:
                QtWidgets.QMessageBox.information(None, "Blue", "等级提升为Lv. " + str(i) + " :" + self.achivementsList[i])
                self.stat["achivement"] = i
                self.saveStatistics()
                break

    def saveStatistics(self):
        json.dump(self.stat, open(PATH_TO_STATISTICS, "w"))

    def refreshStatistics(self):
        days = time.localtime(time.time())

        delta = self.settings["goal"] - self.stat["cleanHours"]

        if delta == 0:
            QtWidgets.QMessageBox.information(None, "Blue", "目标达成!!!\n请设置新的目标!!!")
            self.slideClicked3(None)

        self.ui.lb_days.setText(str(delta))
        self.ui.lb_goal.setText(str(self.settings["goal"]))
        self.ui.lb_achv.setText(self.achivementsList[self.stat["achivement"]])
        self.ui.lb_lv.setText("Lv. " + str(self.stat["achivement"]))
        self.ui.lb_growth.setText(str(self.stat["cleanHours"] // 24))

        #setup the water and ferilization
        if days[7] == time.localtime(self.stat["lastWater"])[7]:
            self.ui.lb_jiaoshui.setPixmap(QPixmap("res/ack.png"))
            self.watered = True
        else:
            self.watered = False

        if days[7] == time.localtime(self.stat["lastFertilize"])[7]:
            self.ui.lb_shifei.setPixmap(QPixmap("res/ack.png"))
            self.fertilized = True
        else:
            self.fertilized = False



        #setup the calendar
        pixmapA = QPixmap("res/lu.png")
        pixmapB = QPixmap("res/blue.png")

        h = days[3]
        if h >= 0 and h < 6:
            r = 0
        elif h >= 6 and h < 12:
            r = 1
        elif h >= 12 and h < 18:
            r = 2
        else:
            r = 3

        for i in range(days[6]):
            for j in range(4):
                if self.stat["stat"][i][j] == 0:
                    self.statLabels[i][j].setPixmap(pixmapA)
                else:
                    self.statLabels[i][j].setPixmap(pixmapB)

        day = days[6]
        for j in range(r):
            if self.stat["stat"][day][j] == 0:
                self.statLabels[day][j].setPixmap(pixmapA)
            else:
                self.statLabels[day][j].setPixmap(pixmapB)

        #setup the wall
        for i in range(6):
            self.achivIcons[i].setPixmap(QPixmap("res/" + str(i) * 2))

        for i in range(self.stat["achivement"] + 1):
            self.achivIcons[i].setPixmap(QPixmap("res/" + str(i)))


    def loadSettings(self):
        try:
            sfile = open(PATH_TO_SETTINGS, "r")
            self.settings = json.load(sfile)
            sfile.close()
        except:
            self.settings = self.defaultSettings
            self.saveSettings(None)

    def validateSettings(self):
        for keys in self.defaultSettings:
            try:
                self.settings[keys]
            except:
                self.settings[keys] = self.defaultSettings[keys]

    def loadStatistics(self):
        try:
            sfile = open(PATH_TO_STATISTICS, "r")
            self.stat = json.load(sfile)
        except:
            self.stat = self.defaultStat

        for keys in self.defaultStat:
            try:
                self.stat[keys]
            except:
                self.stat[keys] = self.defaultStat[keys]
        self.saveStatistics()

    def refreshInfo(self):
        #setup avata
        pixmap = QPixmap()
        pixmap.load("res/avata_mask")
        pixmap.scaled(115, 115)
        self.ui.lb_avata.setMask(pixmap.mask())
        pixmap.load(self.settings["avata"])
        self.ui.lb_avata.setPixmap(pixmap)

#        self.ui.lb_avata2.setMask(pixmap.mask())
#        pixmap.load(self.settings["avata"])
#        self.ui.lb_avata2.setPixmap(pixmap)


        #setup the name
        self.ui.lb_welcomname.setText(self.settings["name"])
        self.ui.lb_nick.setText(self.settings["name"])



    def appExit(self, event):
        if self.devMode == False:
            QtWidgets.QMessageBox.information(None, "bluer", "开发者模式开启")
            self.devMode = True
        else:
            QtWidgets.QMessageBox.information(None, "bluer", "开发者模式关闭")
            self.devMode = False

    def avataEdit(self, event):
        openDlg = QtWidgets.QFontDialog()
        openDlg.open()

    def setupUi2(self):
        #setup event handling
        self.sideButtons = [self.ui.lb1, self.ui.lb2, self.ui.lb3, self.ui.lb4]
        self.ui.lb_exit.mousePressEvent = self.appExit
        self.setupAnimes()
        self.setupSideButtons()
        self.refreshInfo()

        #setup tray
        self.icon = QIcon("res/logo-tray.png")
        self.trayIcon = QSystemTrayIcon()
        self.trayIcon.setIcon(self.icon)
        self.trayIcon.activated.connect(self.onTrayClicked)
        self.trayIcon.show()

        #setup the info edit
        self.ui.lb_avata.mousePressEvent = self.avataEdit

    def setupAnimes(self):
        self.shiftAnime1 = QPropertyAnimation()
        self.shiftAnime1.setTargetObject(self.ui.widget1)
        self.shiftAnime1.setPropertyName("geometry".encode())
        self.shiftAnime1.setDuration(400)
        self.shiftAnime1.setStartValue(QRect(177, 29, 0, 571))
        self.shiftAnime1.setEndValue(QRect(177, 29, 623, 571))

        self.shiftAnime2 = QPropertyAnimation()
        self.shiftAnime2.setTargetObject(self.ui.widget2)
        self.shiftAnime2.setPropertyName("geometry".encode())
        self.shiftAnime2.setDuration(400)
        self.shiftAnime2.setStartValue(QRect(800, 29, 0, 571))
        self.shiftAnime2.setEndValue(QRect(177, 29, 623, 571))

        self.shiftAnime3 = QPropertyAnimation()
        self.shiftAnime3.setTargetObject(self.ui.widget3)
        self.shiftAnime3.setPropertyName("geometry".encode())
        self.shiftAnime3.setDuration(400)
        self.shiftAnime3.setStartValue(QRect(800, 29, 623, 571))
        self.shiftAnime3.setEndValue(QRect(177, 29, 623, 571))

        self.shiftAnime4 = QPropertyAnimation()
        self.shiftAnime4.setTargetObject(self.ui.widget4)
        self.shiftAnime4.setPropertyName("geometry".encode())
        self.shiftAnime4.setDuration(400)
        self.shiftAnime4.setStartValue(QRect(800, 29, 623, 571))
        self.shiftAnime4.setEndValue(QRect(177, 29, 623, 571))

        self.selectedWidget = self.ui.widget1


    def setSlideMid(self, bt):
        if self.selectedSideButton != bt:
            bt.setStyleSheet(slide_bt_mid)

    def setSlideUp(self, bt):
        if self.selectedSideButton != bt:
            bt.setStyleSheet(slide_bt_up)

    def setSlideDown(self, bt):
        self.selectedSideButton.setStyleSheet(slide_bt_up)
        self.selectedSideButton = bt
        bt.setStyleSheet(slide_bt_down)


    def slideEnter1(self, event):
        self.setSlideMid(self.ui.lb1)

    def slideEnter2(self, event):
        self.setSlideMid(self.ui.lb2)

    def slideEnter3(self, event):
        self.setSlideMid(self.ui.lb3)

    def slideEnter4(self, event):
        self.setSlideMid(self.ui.lb4)

    def slideLeave1(self, event):
        self.setSlideUp(self.ui.lb1)

    def slideLeave2(self, event):
        self.setSlideUp(self.ui.lb2)

    def slideLeave3(self, event):
        self.setSlideUp(self.ui.lb3)

    def slideLeave4(self, event):
        self.setSlideUp(self.ui.lb4)

    def slideBack(self, event):
        self.setSlideDown(self.ui.lb1)
        self.ui.widget1.raise_()
        self.shiftAnime1.start()
        self.selectedWidget = self.ui.widget1

    def slideClicked1(self, event):
        self.setSlideDown(self.ui.lb1)
        if self.selectedWidget != self.ui.widget1:
            self.ui.widget1.raise_()
            self.shiftAnime1.start()
            self.selectedWidget = self.ui.widget1

    def slideClicked2(self, event):
        self.setSlideDown(self.ui.lb2)
        if self.selectedWidget != self.ui.widget2:
            self.ui.widget2.raise_()
            self.shiftAnime2.start()
            self.selectedWidget = self.ui.widget2

    def slideClicked3(self, event):
        self.setSlideDown(self.ui.lb3)
        if self.selectedWidget != self.ui.widget3:
            self.ui.widget3.raise_()
            self.shiftAnime3.start()
            self.selectedWidget = self.ui.widget3

    def jiaoshuiCheck(self, event):
        pixmap = QPixmap()
        pixmap.load("res/ack.png")
        self.ui.lb_jiaoshui.setPixmap(pixmap)
        self.stat["lastWater"] = time.time()
        self.saveStatistics()

    def shifeiCheck(self, event):
        pixmap = QPixmap()
        pixmap.load("res/ack.png")
        self.ui.lb_shifei.setPixmap(pixmap)
        self.stat["lastFertilize"] = time.time()
        self.saveStatistics()


    def slideClicked4(self, event):
        self.setSlideDown(self.ui.lb4)
        if self.selectedWidget != self.ui.widget4:
            self.ui.widget4.raise_()
            self.shiftAnime4.start()
            self.selectedWidget = self.ui.widget4

    def setupWidget1(self):
        #setup the tree
        movie = QMovie()
        movie.setFileName("res/tree.gif")
        self.ui.lb_tree.setMovie(movie)
        self.ui.lb_tree_big.setMovie(movie)
        movie.start()

        #setup the statistics
        self.ui.gridLayout.setHorizontalSpacing(60)
        self.ui.gridLayout.setVerticalSpacing(10)
        self.ui.gridLayout.setGeometry(QRect(0, 51, 291, 224))
        self.ui.gridLayout.setAlignment(QtCore.Qt.AlignCenter)
        self.statLabels = []
        for i in range(7):
            self.statLabels.append([])
            for j in range(4):
                self.statLabels[i].append(QLabel())
                self.statLabels[i][j].setScaledContents(True)
                self.statLabels[i][j].setAutoFillBackground(False)
                self.statLabels[i][j].setAlignment(QtCore.Qt.AlignCenter)
                self.ui.gridLayout.addWidget(self.statLabels[i][j], i, j, 1, 1)

    def setupWidget2(self):
        self.ui.lb_jiaoshui.mousePressEvent = self.jiaoshuiCheck
        self.ui.lb_shifei.mousePressEvent = self.shifeiCheck

    def setupWidget3(self):
        self.ui.check_maze.mousePressEvent = self.mazeCliked
        self.ui.check_paper.mousePressEvent = self.paperCliked
        self.ui.check_pic.mousePressEvent = self.picCliked
        self.ui.check_text.mousePressEvent = self.textClicked
        self.ui.lb_save.mousePressEvent = self.saveSettings

        self.ui.spin_goal.setValue(self.settings["goal"])

        if self.settings["game_type"] == 0:
            self.mazeCliked(None)
        else:
            self.paperCliked(None)

        self.picCliked(None)
        self.picCliked(None)

        self.textClicked(None)
        self.textClicked(None)

    def setupWidget4(self):
        self.achivIcons = [self.ui.lb_a0, self.ui.lb_a1, self.ui.lb_a2,
                           self.ui.lb_a3, self.ui.lb_a4, self.ui.lb_a5]

        for i in range(6):
            self.achivIcons[i].setPixmap(QPixmap("res/" + str(i) * 2))

    def mazeCliked(self, event):
        pixmap = QPixmap()
        pixmap.load("res/checked.png")
        self.ui.check_maze.setPixmap(pixmap)

        pixmap.load("res/unchecked.png")
        self.ui.check_paper.setPixmap(pixmap)

        self.settings["game_type"] = 0

    def paperCliked(self, event):
        pixmap = QPixmap()
        pixmap.load("res/checked.png")
        self.ui.check_paper.setPixmap(pixmap)

        pixmap.load("res/unchecked.png")
        self.ui.check_maze.setPixmap(pixmap)

        self.settings["game_type"] = 1

    def picCliked(self, event):
        pixmap = QPixmap()
        pixmap.load("res/checked.png")
        self.ui.check_pic.setPixmap(pixmap)

        pixmap.load("res/unchecked.png")
        self.ui.check_text.setPixmap(pixmap)

        self.settings["pic_detect"] = 1
        self.settings["text_detect"] = 0


    def textClicked(self, event):
        pixmap = QPixmap()
        pixmap.load("res/checked.png")
        self.ui.check_text.setPixmap(pixmap)

        pixmap.load("res/unchecked.png")
        self.ui.check_pic.setPixmap(pixmap)

        self.settings["pic_detect"] = 1
        self.settings["text_detect"] = 1

    def setupSideButtons(self):
        self.ui.lb1.enterEvent = self.slideEnter1
        self.ui.lb1.leaveEvent = self.slideLeave1
        self.ui.lb1.mousePressEvent = self.slideClicked1
        self.ui.lb2.enterEvent = self.slideEnter2
        self.ui.lb2.leaveEvent = self.slideLeave2
        self.ui.lb2.mousePressEvent = self.slideClicked2
        self.ui.lb3.enterEvent = self.slideEnter3
        self.ui.lb3.leaveEvent = self.slideLeave3
        self.ui.lb3.mousePressEvent = self.slideClicked3
        self.ui.lb4.enterEvent = self.slideEnter4
        self.ui.lb4.leaveEvent = self.slideLeave4
        self.ui.lb4.mousePressEvent = self.slideClicked4
        self.ui.lb4.enterEvent = self.slideEnter4
        self.ui.lb4.leaveEvent = self.slideLeave4
        self.ui.lb4.mousePressEvent = self.slideClicked4


        self.ui.lb_back2.mousePressEvent = self.slideBack
        self.ui.lb_back3.mousePressEvent = self.slideBack
        self.ui.lb_back4.mousePressEvent = self.slideBack


        for lb in self.sideButtons:
            lb.setStyleSheet(slide_bt_up)
        self.selectedSideButton = self.ui.lb1
        self.slideClicked1(None)

    def connections(self):
        pass
예제 #48
0
class CoolToolButton(QToolButton):

    def __init__(self, action=None, parent=None):
        super().__init__(parent)

        self._fader = 0
        if action is not None:
            self.setDefaultAction(action)
        self.setAttribute(Qt.WA_Hover, True)
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)

    def _set_fader(self, value):
        self._fader = value
        self.update()

    def _get_fader(self):
        return self._fader

    fader = pyqtProperty(float, fget=_get_fader, fset=_set_fader)

    def event(self, event):
        if event.type() == QEvent.Enter:
            self.anim = QPropertyAnimation(self, b"fader")
            self.anim.setDuration(150)
            self.anim.setEndValue(1.0)
            self.anim.start(QPropertyAnimation.DeleteWhenStopped)
        elif event.type() == QEvent.Leave:
            self.anim = QPropertyAnimation(self, b"fader")
            self.anim.setDuration(124)
            self.anim.setEndValue(0.0)
            self.anim.start(QPropertyAnimation.DeleteWhenStopped)
        else:
            return QToolButton.event(self, event)
        return False

    def paintEvent(self, event):
        painter = QPainter(self)
        if self.isEnabled() and not self.isDown() and not self.isChecked():
            painter.save()
            hover_color = QColor("#424242")
            faded_hover_color = QColor(hover_color)
            faded_hover_color.setAlpha(int(self._fader * hover_color.alpha()))
            painter.fillRect(event.rect(), faded_hover_color)
            painter.restore()
        elif self.isDown() or self.isChecked():
            painter.save()
            selected_color = QColor("#161719")
            painter.fillRect(event.rect(), selected_color)
            painter.restore()

        is_titled = bool(self.defaultAction().property("titled"))
        icon_rect = QRect(0, 0, 32, 32)
        icon_rect.moveCenter(event.rect().center())

        if is_titled:
            font = painter.font()
            center_rect = event.rect()
            font.setPointSizeF(6)
            fm = QFontMetrics(font)
            line_height = fm.height()
            text_flags = Qt.AlignHCenter | Qt.AlignTop
            project_name = self.defaultAction().property("heading")
            if project_name is not None:
                center_rect.adjust(0, line_height, 0, 0)
                icon_rect.moveTop(center_rect.top())
            else:
                icon_rect.moveCenter(center_rect.center())
            self.icon().paint(painter, icon_rect, Qt.AlignCenter)
            painter.setFont(font)
            r = QRect(0, 5, self.rect().width(), line_height)
            painter.setPen(Qt.white)
            margin = 5
            available_width = r.width() - margin
            ellided_project_name = fm.elidedText(
                project_name, Qt.ElideMiddle, available_width)
            painter.drawText(r, text_flags, ellided_project_name)
        else:
            self.icon().paint(painter, icon_rect, Qt.AlignCenter)

    def sizeHint(self):
        button_size = self.iconSize().expandedTo(QSize(48, 48))
        return button_size

    def minimumSizeHint(self):
        return QSize(8, 8)
예제 #49
0
class LineEditMenu(AeroMenu):
    """ 单行输入框右击菜单 """
    def __init__(self, parent):
        super().__init__('', parent)
        # 不能直接改width
        self.animation = QPropertyAnimation(self, b'geometry')
        self.initWidget()

    def initWidget(self):
        """ 初始化小部件 """
        self.setObjectName('lineEditMenu')
        self.animation.setDuration(300)
        self.animation.setEasingCurve(QEasingCurve.OutQuad)
        self.setQss()

    def createActions(self):
        # 创建动作
        self.cutAct = QAction(QIcon('resource\\images\\menu\\黑色剪刀.png'),
                              '剪切',
                              self,
                              shortcut='Ctrl+X',
                              triggered=self.parent().cut)
        self.copyAct = QAction(QIcon('resource\\images\\menu\\黑色复制.png'),
                               '复制',
                               self,
                               shortcut='Ctrl+C',
                               triggered=self.parent().copy)
        self.pasteAct = QAction(QIcon('resource\\images\\menu\\黑色粘贴.png'),
                                '粘贴',
                                self,
                                shortcut='Ctrl+V',
                                triggered=self.parent().paste)
        self.cancelAct = QAction(QIcon('resource\\images\\menu\\黑色撤销.png'),
                                 '取消操作',
                                 self,
                                 shortcut='Ctrl+Z',
                                 triggered=self.parent().undo)
        self.selectAllAct = QAction('全选',
                                    self,
                                    shortcut='Ctrl+A',
                                    triggered=self.parent().selectAll)
        # 创建动作列表
        self.action_list = [
            self.cutAct, self.copyAct, self.pasteAct, self.cancelAct,
            self.selectAllAct
        ]

    def exec_(self, pos):
        # 删除所有动作
        self.clear()
        # clear之后之前的动作已不再存在故需重新创建
        self.createActions()
        # 初始化属性
        self.setProperty('hasCancelAct', 'false')
        width = 176
        actionNum = len(self.action_list)
        # 访问系统剪贴板
        self.clipboard = QApplication.clipboard()
        # 根据剪贴板内容是否为text分两种情况讨论
        if self.clipboard.mimeData().hasText():
            # 再根据3种情况分类讨论
            if self.parent().text():
                self.setProperty('hasCancelAct', 'true')
                width = 213
                if self.parent().selectedText():
                    self.addActions(self.action_list)
                else:
                    self.addActions(self.action_list[2:])
                    actionNum -= 2
            else:
                self.addAction(self.pasteAct)
                actionNum = 1
        else:
            if self.parent().text():
                self.setProperty('hasCancelAct', 'true')
                width = 213
                if self.parent().selectedText():
                    self.addActions(self.action_list[:2] +
                                    self.action_list[3:])
                    actionNum -= 1
                else:
                    self.addActions(self.action_list[3:])
                    actionNum -= 3
            else:
                return
        # 每个item的高度为38px,10为上下的内边距和
        height = actionNum * 38 + 10
        # 不能把初始的宽度设置为0px,不然会报警
        self.animation.setStartValue(QRect(pos.x(), pos.y(), 1, 1))
        self.animation.setEndValue(QRect(pos.x(), pos.y(), width, height))
        self.setStyle(QApplication.style())
        # 开始动画
        self.animation.start()
        super().exec_(pos)
예제 #50
0
            QRect(150, 100, 50, 50), button3, QRect(100, 150, 50, 50), button4,
            QRect(150, 150, 50, 50), group)

    state6 = createGeometryState(button1, QRect(50, 50, 50, 50), button2,
            QRect(200, 50, 50, 50), button3, QRect(50, 200, 50, 50), button4,
            QRect(200, 200, 50, 50), group)

    state7 = createGeometryState(button1, QRect(0, 0, 50, 50), button2,
            QRect(250, 0, 50, 50), button3, QRect(0, 250, 50, 50), button4,
            QRect(250, 250, 50, 50), group)

    group.setInitialState(state1)

    animationGroup = QParallelAnimationGroup()
    anim = QPropertyAnimation(button4, b'geometry')
    anim.setDuration(1000)
    anim.setEasingCurve(QEasingCurve.OutElastic)
    animationGroup.addAnimation(anim)

    subGroup = QSequentialAnimationGroup(animationGroup)
    subGroup.addPause(100)
    anim = QPropertyAnimation(button3, b'geometry')
    anim.setDuration(1000)
    anim.setEasingCurve(QEasingCurve.OutElastic)
    subGroup.addAnimation(anim)

    subGroup = QSequentialAnimationGroup(animationGroup)
    subGroup.addPause(150)
    anim = QPropertyAnimation(button2, b'geometry')
    anim.setDuration(1000)
    anim.setEasingCurve(QEasingCurve.OutElastic)
예제 #51
0
class SnackbarWidget(QWidget, Ui_SnackbarWidget):
    _dismissed = pyqtSignal(QWidget)

    def _set_opacity(self, o):
        self._opacity = o
        self.setWindowOpacity(o)

    def _get_opacity(self):
        return self._opacity

    opacity = pyqtProperty(float, fset=_set_opacity, fget=_get_opacity)

    def __init__(self, msg, icon=None, timeout=3000, action_text=None, action=None, animate=True):
        super().__init__()
        self.setupUi(self)
        self.animate = animate
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool | Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setAttribute(Qt.WA_ShowWithoutActivating)
        self.setObjectName("SnackbarWidget")
        self.label.setText(msg)
        self.action = action
        if action_text and action:
            self.button_action.setText(action_text)
            self.button_action.clicked.connect(self._on_action_clicked)
            self.button_action.setCursor(QCursor(Qt.PointingHandCursor))
        if icon:
            self.label_icon.setPixmap(icon)
        self.button_close.clicked.connect(self._on_timeout)

        self.timer = QTimer()
        self.timer.setInterval(timeout)
        self.timer.setSingleShot(True)
        self.timer.timeout.connect(self._on_timeout)
        self.index = 0

        if self.animate:
            self._set_opacity(0.0)
            self.show_animation = QPropertyAnimation(self, b"opacity")
            self.show_animation.finished.connect(self.timer.start)
            self.show_animation.setDuration(500)
            self.show_animation.setStartValue(0.0)
            self.show_animation.setEndValue(1.0)
            self.show_animation.setEasingCurve(QEasingCurve.Linear)

            self.hide_animation = QPropertyAnimation(self, b"opacity")
            self.hide_animation.finished.connect(self.hide)
            self.hide_animation.setDuration(500)
            self.hide_animation.setStartValue(1.0)
            self.hide_animation.setEndValue(0.0)
            self.show_animation.setEasingCurve(QEasingCurve.Linear)
        else:
            self._set_opacity(1.0)

    def _on_action_clicked(self):
        self.action()
        self.timer.stop()
        if self.animate:
            self.show_animation.stop()
            self.hide_animation.start()

    def set_index(self, index):
        self.index = index
        self.move_popup()

    def paintEvent(self, _):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        rect = QRect()
        rect.setX(self.rect().x() + 5)
        rect.setY(self.rect().y() + 5)
        rect.setWidth(self.rect().width() - 10)
        rect.setHeight(self.rect().height() - 10)
        painter.setBrush(QBrush(QColor(0x32, 0x32, 0x32, 0xDD)))
        painter.setPen(Qt.NoPen)
        painter.drawRoundedRect(rect, 10, 10)

    def move_popup(self):
        main_window = ParsecApp.get_main_window()
        if not main_window:
            return
        offset = 10
        height = 101 if platform.system() == "Windows" else 75
        width = min(500, main_window.size().width() - 40)
        self.resize(QSize(width, height))

        x = main_window.size().width() - width - 20
        y = main_window.size().height() - ((height + offset) * (self.index + 1))
        # Hide the snackbar if the main window does not have enough space to show it
        self.set_visible(y > 30)
        pos = main_window.mapToGlobal(QPoint(x, y))
        self.setGeometry(pos.x(), pos.y(), width, height)

    def _on_timeout(self):
        if self.animate:
            self.show_animation.stop()
            self.hide_animation.start()
        else:
            self.hide()

    def set_visible(self, visible):
        if not visible:
            super().hide()
        else:
            super().show()

    def hide(self):
        if self.animate:
            self.show_animation.stop()
            self.hide_animation.stop()
        self.timer.stop()
        super().hide()
        self._dismissed.emit(self)

    def show(self):
        self.move_popup()
        super().show()
        if self.animate:
            self._set_opacity(0.0)
            self.show_animation.start()
        else:
            self._set_opacity(1.0)
            self.timer.start()
예제 #52
0
class AnimatedStackedWidget(QFrame):
    # Current widget has changed
    currentChanged = Signal(int)

    # Transition animation has started
    transitionStarted = Signal()

    # Transition animation has finished
    transitionFinished = Signal()

    def __init__(self, parent=None, animationEnabled=True):
        QFrame.__init__(self, parent)
        self.__animationEnabled = animationEnabled

        layout = StackLayout()

        self.__fadeWidget = CrossFadePixmapWidget(self)

        self.transitionAnimation = \
            QPropertyAnimation(self.__fadeWidget, b"blendingFactor_", self)
        self.transitionAnimation.setStartValue(0.0)
        self.transitionAnimation.setEndValue(1.0)
        self.transitionAnimation.setDuration(100 if animationEnabled else 0)
        self.transitionAnimation.finished.connect(self.__onTransitionFinished)

        layout.addWidget(self.__fadeWidget)
        layout.currentChanged.connect(self.__onLayoutCurrentChanged)

        self.setLayout(layout)

        self.__widgets = []
        self.__currentIndex = -1
        self.__nextCurrentIndex = -1

    def setAnimationEnabled(self, animationEnabled):
        """
        Enable/disable transition animations.
        """
        if self.__animationEnabled != animationEnabled:
            self.__animationEnabled = animationEnabled
            self.transitionAnimation.setDuration(
                100 if animationEnabled else 0)

    def animationEnabled(self):
        """
        Is the transition animation enabled.
        """
        return self.__animationEnabled

    def addWidget(self, widget):
        """
        Append the widget to the stack and return its index.
        """
        return self.insertWidget(self.layout().count(), widget)

    def insertWidget(self, index, widget):
        """
        Insert `widget` into the stack at `index`.
        """
        index = min(index, self.count())
        self.__widgets.insert(index, widget)
        if index <= self.__currentIndex or self.__currentIndex == -1:
            self.__currentIndex += 1
        return self.layout().insertWidget(index, widget)

    def removeWidget(self, widget):
        """
        Remove `widget` from the stack.

        .. note:: The widget is hidden but is not deleted.

        """
        index = self.__widgets.index(widget)
        self.layout().removeWidget(widget)
        self.__widgets.pop(index)

    def widget(self, index):
        """
        Return the widget at `index`
        """
        return self.__widgets[index]

    def indexOf(self, widget):
        """
        Return the index of `widget` in the stack.
        """
        return self.__widgets.index(widget)

    def count(self):
        """
        Return the number of widgets in the stack.
        """
        return max(self.layout().count() - 1, 0)

    def setCurrentWidget(self, widget):
        """
        Set the current shown widget.
        """
        index = self.__widgets.index(widget)
        self.setCurrentIndex(index)

    def setCurrentIndex(self, index):
        """
        Set the current shown widget index.
        """
        index = max(min(index, self.count() - 1), 0)
        if self.__currentIndex == -1:
            self.layout().setCurrentIndex(index)
            self.__currentIndex = index
            return

        current = self.__widgets[self.__currentIndex]
        next_widget = self.__widgets[index]

        def has_pending_resize(widget):
            return widget.testAttribute(Qt.WA_PendingResizeEvent) or \
                   not widget.testAttribute(Qt.WA_WState_Created)

        current_pix = next_pix = None
        if not has_pending_resize(current):
            current_pix = current.grab()
        if not has_pending_resize(next_widget):
            next_pix = next_widget.grab()

        with updates_disabled(self):
            self.__fadeWidget.setPixmap(current_pix)
            self.__fadeWidget.setPixmap2(next_pix)
            self.__nextCurrentIndex = index
            self.__transitionStart()

    def currentIndex(self):
        """
        Return the current shown widget index.
        """
        return self.__currentIndex

    def sizeHint(self):
        hint = QFrame.sizeHint(self)
        if hint.isEmpty():
            hint = QSize(0, 0)
        return hint

    def __transitionStart(self):
        """
        Start the transition.
        """
        log.debug("Stack transition start (%s)", str(self.objectName()))
        # Set the fade widget as the current widget
        self.__fadeWidget.blendingFactor_ = 0.0
        self.layout().setCurrentWidget(self.__fadeWidget)
        self.transitionAnimation.start()
        self.transitionStarted.emit()

    def __onTransitionFinished(self):
        """
        Transition has finished.
        """
        log.debug("Stack transition finished (%s)" % str(self.objectName()))
        self.__fadeWidget.blendingFactor_ = 1.0
        self.__currentIndex = self.__nextCurrentIndex
        with updates_disabled(self):
            self.layout().setCurrentIndex(self.__currentIndex)
        self.transitionFinished.emit()

    def __onLayoutCurrentChanged(self, index):
        # Suppress transitional __fadeWidget current widget
        if index != self.count():
            self.currentChanged.emit(index)
예제 #53
0
class SwitchButton(QWidget):
    signal_on = pyqtSignal(bool)

    def __init__(self,
                 parent=None,
                 w1="Start",
                 l1=12,
                 w2="Stop",
                 l2=43,
                 width=80):
        super(SwitchButton, self).__init__(parent)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.__labeloff = QLabel(self)
        self.__labeloff.setText(w2)
        self.__labeloff.setStyleSheet(
            """color: rgb(120, 120, 120); font-weight: bold;""")
        self.__background = Background(self)
        self.__labelon = QLabel(self)
        self.__labelon.setText(w1)
        self.__labelon.setStyleSheet(
            """color: rgb(255, 255, 255); font-weight: bold;""")
        self.__circle = Circle(self)
        self.__circlemove = None
        self.__ellipsemove = None
        self.__enabled = True
        self.__duration = 100

        self.setFixedSize(width, 24)

        self.__background.resize(20, 20)
        self.__background.move(2, 2)
        self.__labelon.move(l1, 5)
        self.__labeloff.move(l2, 5)

        self.switch_on = False

        if self.switch_on:
            self.__circle.move(self.width() - 22, 2)
            self.__background.resize(self.width() - 4, 20)
        else:
            self.__circle.move(2, 2)

    def change_state(self):
        if self.switch_on:
            self.__circle.move(2, 2)
            self.__background.resize(20, 20)
        else:
            self.__circle.move(self.width() - 22, 2)
            self.__background.resize(self.width() - 4, 20)

        self.switch_on = not self.switch_on

    def setDuration(self, time):
        self.__duration = time

    def setEnabled(self, bool):
        self.__enabled = bool
        # self.__background.setEnabled(bool)
        self.__circle.setEnabled(bool)

    def mouseReleaseEvent(self, event):
        if not self.__enabled:
            return

        self.__circlemove = QPropertyAnimation(self.__circle, b"pos")
        self.__circlemove.setDuration(self.__duration)

        self.__ellipsemove = QPropertyAnimation(self.__background, b"size")
        self.__ellipsemove.setDuration(self.__duration)

        xs = 2
        y = 2
        xf = self.width() - 22
        hback = 20
        isize = QSize(hback, hback)
        bsize = QSize(self.width() - 4, hback)
        if self.switch_on:
            xf = 2
            xs = self.width() - 22
            bsize = QSize(hback, hback)
            isize = QSize(self.width() - 4, hback)

        self.__circlemove.setStartValue(QPoint(xs, y))
        self.__circlemove.setEndValue(QPoint(xf, y))

        self.__ellipsemove.setStartValue(isize)
        self.__ellipsemove.setEndValue(bsize)

        self.__circlemove.start()
        self.__ellipsemove.start()
        self.switch_on = not self.switch_on

        self.signal_on.emit(self.switch_on)

    def paintEvent(self, event):
        s = self.size()
        qp = QPainter()
        qp.begin(self)
        qp.setRenderHint(QPainter.Antialiasing, True)
        pen = QPen(Qt.NoPen)
        qp.setPen(pen)
        qp.setBrush(QColor(170, 170, 170))
        qp.drawRoundedRect(0, 0, s.width(), s.height(), 12, 12)
        # lg = QLinearGradient(35, 30, 35, 0)
        # lg.setColorAt(0, QColor(210, 210, 210, 255))
        # lg.setColorAt(0.25, QColor(255, 255, 255, 255))
        # lg.setColorAt(0.82, QColor(255, 255, 255, 255))
        # lg.setColorAt(1, QColor(210, 210, 210, 255))
        # qp.setBrush(lg)
        # qp.drawRoundedRect(1, 1, s.width()-2, s.height()-2, 10, 10)
        qp.setBrush(QColor(255, 255, 255))
        qp.drawRoundedRect(2, 2, s.width() - 4, s.height() - 4, 10, 10)

        if self.__enabled:
            # lg = QLinearGradient(50, 30, 35, 0)
            # lg.setColorAt(0, QColor(230, 230, 230, 255))
            # lg.setColorAt(0.25, QColor(255, 255, 255, 255))
            # lg.setColorAt(0.82, QColor(255, 255, 255, 255))
            # lg.setColorAt(1, QColor(230, 230, 230, 255))
            qp.setBrush(QColor(255, 255, 255))
            qp.drawRoundedRect(2, 2, s.width() - 4, s.height() - 4, 10, 10)
            self.__labelon.setStyleSheet(
                """color: rgb(255, 255, 255); font-weight: bold;""")
        else:
            # lg = QLinearGradient(50, 30, 35, 0)
            # lg.setColorAt(0, QColor(200, 200, 200, 255))
            # lg.setColorAt(0.25, QColor(230, 230, 230, 255))
            # lg.setColorAt(0.82, QColor(230, 230, 230, 255))
            # lg.setColorAt(1, QColor(200, 200, 200, 255))
            qp.setBrush(QColor(210, 210, 210))
            self.__labelon.setStyleSheet(
                """color: rgb(210, 210, 210); font-weight: bold;""")
            qp.drawRoundedRect(2, 2, s.width() - 4, s.height() - 4, 10, 10)
        qp.end()
예제 #54
0
파일: tile.py 프로젝트: Longhanks/Tiles
class Tile(QLabel):
    moved = pyqtSignal()

    def __init__(self, parent=None):
        super(Tile, self).__init__(parent)
        self.isEmpty = False
        self.perfectPos = None
        self.hasPerfectPos = True
        self.moveEnabled = False

    def mousePressEvent(self, event):
        if not self.moveEnabled:
            return
        if self.switch():
            self.moved.emit()

    def switch(self, anim=True):
        var = False
        for neighbor in self.getNeighbors():
            if neighbor.isEmpty:
                Xself = self.pos().x()
                Yself = self.pos().y()
                Xneigh = neighbor.pos().x()
                Yneigh = neighbor.pos().y()
                if self.perfectPos.x() == Xneigh and \
                   self.perfectPos.y() == Yneigh:
                    self.hasPerfectPos = True
                else:
                    self.hasPerfectPos = False
                if neighbor.perfectPos.x() == Xself and \
                   neighbor.perfectPos.y() == Yself:
                    neighbor.hasPerfectPos = True
                else:
                    neighbor.hasPerfectPos = False
                if anim:
                    self.animation = QPropertyAnimation(self, "geometry")
                    self.animation.setDuration(200)
                    self.animation.setEndValue(QRect(Xneigh,
                                                     Yneigh,
                                                     self.width(),
                                                     self.height()))
                    self.animation.start()
                else:
                    self.move(Xneigh, Yneigh)
                neighbor.move(Xself, Yself)
                var = True
        return var

    def getNeighbors(self):
        neighbors = []
        x = self.pos().x()
        y = self.pos().y()
        if self.parent().childAt(x-1, y):
            neighbors.append(self.parent().childAt(x-1, y))
        if self.parent().childAt(x+41, y):
            neighbors.append(self.parent().childAt(x+41, y))
        if self.parent().childAt(x, y-1):
            neighbors.append(self.parent().childAt(x, y-1))
        if self.parent().childAt(x, y+41):
            neighbors.append(self.parent().childAt(x, y+41))
        return neighbors
예제 #55
0
    def __init__(self, size, parent=None):
        super(PadNavigator, self).__init__(parent)

        self.form = Ui_Form()

        splash = SplashItem()
        splash.setZValue(1)

        pad = FlippablePad(size)
        flipRotation = QGraphicsRotation(pad)
        xRotation = QGraphicsRotation(pad)
        yRotation = QGraphicsRotation(pad)
        flipRotation.setAxis(Qt.YAxis)
        xRotation.setAxis(Qt.YAxis)
        yRotation.setAxis(Qt.XAxis)
        pad.setTransformations([flipRotation, xRotation, yRotation])

        backItem = QGraphicsProxyWidget(pad)
        widget = QWidget()
        self.form.setupUi(widget)
        self.form.hostName.setFocus()
        backItem.setWidget(widget)
        backItem.setVisible(False)
        backItem.setFocus()
        backItem.setCacheMode(QGraphicsItem.ItemCoordinateCache)
        r = backItem.rect()
        backItem.setTransform(QTransform().rotate(180, Qt.YAxis).translate(-r.width()/2, -r.height()/2))

        selectionItem = RoundRectItem(QRectF(-60, -60, 120, 120),
                QColor(Qt.gray), pad)
        selectionItem.setZValue(0.5)

        smoothSplashMove = QPropertyAnimation(splash, b'y')
        smoothSplashOpacity = QPropertyAnimation(splash, b'opacity')
        smoothSplashMove.setEasingCurve(QEasingCurve.InQuad)
        smoothSplashMove.setDuration(250)
        smoothSplashOpacity.setDuration(250)

        smoothXSelection = QPropertyAnimation(selectionItem, b'x')
        smoothYSelection = QPropertyAnimation(selectionItem, b'y')
        smoothXRotation = QPropertyAnimation(xRotation, b'angle')
        smoothYRotation = QPropertyAnimation(yRotation, b'angle')
        smoothXSelection.setDuration(125)
        smoothYSelection.setDuration(125)
        smoothXRotation.setDuration(125)
        smoothYRotation.setDuration(125)
        smoothXSelection.setEasingCurve(QEasingCurve.InOutQuad)
        smoothYSelection.setEasingCurve(QEasingCurve.InOutQuad)
        smoothXRotation.setEasingCurve(QEasingCurve.InOutQuad)
        smoothYRotation.setEasingCurve(QEasingCurve.InOutQuad)

        smoothFlipRotation = QPropertyAnimation(flipRotation, b'angle')
        smoothFlipScale = QPropertyAnimation(pad, b'scale')
        smoothFlipXRotation = QPropertyAnimation(xRotation, b'angle')
        smoothFlipYRotation = QPropertyAnimation(yRotation, b'angle')
        flipAnimation = QParallelAnimationGroup(self)
        smoothFlipScale.setDuration(500)
        smoothFlipRotation.setDuration(500)
        smoothFlipXRotation.setDuration(500)
        smoothFlipYRotation.setDuration(500)
        smoothFlipScale.setEasingCurve(QEasingCurve.InOutQuad)
        smoothFlipRotation.setEasingCurve(QEasingCurve.InOutQuad)
        smoothFlipXRotation.setEasingCurve(QEasingCurve.InOutQuad)
        smoothFlipYRotation.setEasingCurve(QEasingCurve.InOutQuad)
        smoothFlipScale.setKeyValueAt(0, 1.0)
        smoothFlipScale.setKeyValueAt(0.5, 0.7)
        smoothFlipScale.setKeyValueAt(1, 1.0)
        flipAnimation.addAnimation(smoothFlipRotation)
        flipAnimation.addAnimation(smoothFlipScale)
        flipAnimation.addAnimation(smoothFlipXRotation)
        flipAnimation.addAnimation(smoothFlipYRotation)

        setVariablesSequence = QSequentialAnimationGroup()
        setFillAnimation = QPropertyAnimation(pad, b'fill')
        setBackItemVisibleAnimation = QPropertyAnimation(backItem, b'visible')
        setSelectionItemVisibleAnimation = QPropertyAnimation(selectionItem, b'visible')
        setFillAnimation.setDuration(0)
        setBackItemVisibleAnimation.setDuration(0)
        setSelectionItemVisibleAnimation.setDuration(0)
        setVariablesSequence.addPause(250)
        setVariablesSequence.addAnimation(setBackItemVisibleAnimation)
        setVariablesSequence.addAnimation(setSelectionItemVisibleAnimation)
        setVariablesSequence.addAnimation(setFillAnimation)
        flipAnimation.addAnimation(setVariablesSequence)

        stateMachine = QStateMachine(self)
        splashState = QState(stateMachine)
        frontState = QState(stateMachine)
        historyState = QHistoryState(frontState)
        backState = QState(stateMachine)

        frontState.assignProperty(pad, "fill", False)
        frontState.assignProperty(splash, "opacity", 0.0)
        frontState.assignProperty(backItem, "visible", False)
        frontState.assignProperty(flipRotation, "angle", 0.0)
        frontState.assignProperty(selectionItem, "visible", True)

        backState.assignProperty(pad, "fill", True)
        backState.assignProperty(backItem, "visible", True)
        backState.assignProperty(xRotation, "angle", 0.0)
        backState.assignProperty(yRotation, "angle", 0.0)
        backState.assignProperty(flipRotation, "angle", 180.0)
        backState.assignProperty(selectionItem, "visible", False)

        stateMachine.addDefaultAnimation(smoothXRotation)
        stateMachine.addDefaultAnimation(smoothYRotation)
        stateMachine.addDefaultAnimation(smoothXSelection)
        stateMachine.addDefaultAnimation(smoothYSelection)
        stateMachine.setInitialState(splashState)

        anyKeyTransition = QEventTransition(self, QEvent.KeyPress, splashState)
        anyKeyTransition.setTargetState(frontState)
        anyKeyTransition.addAnimation(smoothSplashMove)
        anyKeyTransition.addAnimation(smoothSplashOpacity)

        enterTransition = QKeyEventTransition(self, QEvent.KeyPress,
                Qt.Key_Enter, backState)
        returnTransition = QKeyEventTransition(self, QEvent.KeyPress,
                Qt.Key_Return, backState)
        backEnterTransition = QKeyEventTransition(self, QEvent.KeyPress,
                Qt.Key_Enter, frontState)
        backReturnTransition = QKeyEventTransition(self, QEvent.KeyPress,
                Qt.Key_Return, frontState)
        enterTransition.setTargetState(historyState)
        returnTransition.setTargetState(historyState)
        backEnterTransition.setTargetState(backState)
        backReturnTransition.setTargetState(backState)
        enterTransition.addAnimation(flipAnimation)
        returnTransition.addAnimation(flipAnimation)
        backEnterTransition.addAnimation(flipAnimation)
        backReturnTransition.addAnimation(flipAnimation)

        columns = size.width()
        rows = size.height()
        stateGrid = []
        for y in range(rows):
            stateGrid.append([QState(frontState) for _ in range(columns)])

        frontState.setInitialState(stateGrid[0][0])
        selectionItem.setPos(pad.iconAt(0, 0).pos())

        for y in range(rows):
            for x in range(columns):
                state = stateGrid[y][x]

                rightTransition = QKeyEventTransition(self, QEvent.KeyPress,
                        Qt.Key_Right, state)
                leftTransition = QKeyEventTransition(self, QEvent.KeyPress,
                        Qt.Key_Left, state)
                downTransition = QKeyEventTransition(self, QEvent.KeyPress,
                        Qt.Key_Down, state)
                upTransition = QKeyEventTransition(self, QEvent.KeyPress,
                        Qt.Key_Up, state)

                rightTransition.setTargetState(stateGrid[y][(x + 1) % columns])
                leftTransition.setTargetState(stateGrid[y][((x - 1) + columns) % columns])
                downTransition.setTargetState(stateGrid[(y + 1) % rows][x])
                upTransition.setTargetState(stateGrid[((y - 1) + rows) % rows][x])

                icon = pad.iconAt(x, y)
                state.assignProperty(xRotation, "angle", -icon.x() / 6.0)
                state.assignProperty(yRotation, "angle", icon.y() / 6.0)
                state.assignProperty(selectionItem, "x", icon.x())
                state.assignProperty(selectionItem, "y", icon.y())
                frontState.assignProperty(icon, "visible", True)
                backState.assignProperty(icon, "visible", False)

                setIconVisibleAnimation = QPropertyAnimation(icon, b'visible')
                setIconVisibleAnimation.setDuration(0)
                setVariablesSequence.addAnimation(setIconVisibleAnimation)

        scene = QGraphicsScene(self)
        scene.setBackgroundBrush(QBrush(QPixmap(":/images/blue_angle_swirl.jpg")))
        scene.setItemIndexMethod(QGraphicsScene.NoIndex)
        scene.addItem(pad)
        scene.setSceneRect(scene.itemsBoundingRect())
        self.setScene(scene)

        sbr = splash.boundingRect()
        splash.setPos(-sbr.width() / 2, scene.sceneRect().top() - 2)
        frontState.assignProperty(splash, "y", splash.y() - 100.0)
        scene.addItem(splash)

        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setMinimumSize(50, 50)
        self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
        self.setCacheMode(QGraphicsView.CacheBackground)
        self.setRenderHints(QPainter.Antialiasing |
                QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing)

        if QGLFormat.hasOpenGL():
            self.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers)))

        stateMachine.start()
예제 #56
0
class MainWindow(QMainWindow,Form):

    def initRandomTable(self):
        self.random_board=board.Board().getTable()
        
        self.Tiles=[[self.Tile_1,
                    self.Tile_2,
                    self.Tile_3],
                    [self.Tile_4,
                    self.Tile_5,
                    self.Tile_6],
                    [self.Tile_7,
                    self.Tile_8,
                    self.Tile_9]]
        
        for i in range(0,3):
            for j in range(0,3):
                if self.random_board[i][j]!=0:
                    self.Tiles[i][j].setText(
                    (str)(self.random_board[i][j])
                    )
                else:
                    self.Tiles[i][j].setText(
                    '0'
                    )
                    self.Tiles[i][j].setVisible(False)       
    def changeTable(self,next_board,index):
        self.setupUi(self)
        self.Tiles=[[self.Tile_1,
                    self.Tile_2,
                    self.Tile_3],
                    [self.Tile_4,
                    self.Tile_5,
                    self.Tile_6],
                    [self.Tile_7,
                    self.Tile_8,
                    self.Tile_9]]
        self.solve_button.clicked.connect(self.solve)
        self.pushButton_next.clicked.connect(self.nextState)
        self.pushButton_prev.clicked.connect(self.prevState)
        self.lineEdit_Start.setInputMask("9 9 9 9 9 9 9 9 9")
        self.lineEdit_Goal.setInputMask("9 9 9 9 9 9 9 9 9")
        self.comboBox_Method.setCurrentIndex(index)
        def stringBoard(b):
            s=""
            for i in b:
                for j in i:
                    s+=str(j)
            return s
        self.lineEdit_Start.setText(stringBoard(next_board))
        self.pushButton_next.setEnabled(False)
        self.pushButton_prev.setEnabled(False)
               
        for i in range(0,3):
            for j in range(0,3):
                if next_board[i][j]!=0:
                    self.Tiles[i][j].setVisible(True)
                    self.Tiles[i][j].setText(
                    (str)(next_board[i][j])
                    )
                else:
                    self.Tiles[i][j].setText(
                    '0'
                    )
                    self.Tiles[i][j].setVisible(False)



    def __init__(self):
        super(MainWindow,self).__init__()
        self.setupUi(self)
        self.initRandomTable()
        self.solve_button.clicked.connect(self.solve)
        self.pushButton_next.clicked.connect(self.nextState)
        self.pushButton_prev.clicked.connect(self.prevState)
        self.lineEdit_Start.setInputMask("9 9 9 9 9 9 9 9 9")
        self.lineEdit_Goal.setInputMask("9 9 9 9 9 9 9 9 9")
        self.pushButton_next.setEnabled(False)
        self.pushButton_prev.setEnabled(False)
        
        def stringBoard(b):
            s=""
            for i in b:
                for j in i:
                    s+=str(j)
            return s
        self.lineEdit_Start.setText(stringBoard(self.random_board))
        self.lineEdit_Level.setInputMask("90")
        
      
    def moveTile(self,destination,location,direction,isNext):
        def swapPositionsInTileList(tlist,pos1, pos2): 
            tlist[pos1[0]][pos1[1]], tlist[pos2[0]][pos2[1]] = tlist[pos2[0]][pos2[1]], tlist[pos1[0]][pos1[1]]
            return tlist  
        i=location[0]
        j=location[1]
        self.animation=QPropertyAnimation(self.Tiles[i][j],b"geometry")
        self.animation.setDuration(100)
        
        self.animation.setStartValue(QRect(
            self.Tiles[i][j].x(),
            self.Tiles[i][j].y(),
            self.Tiles[i][j].width(),
            self.Tiles[i][j].height()
        ))

        self.animation.setEndValue(QRect(
            self.Tiles[i][j].x()+direction[1]*self.Tiles[i][j].width(),
            self.Tiles[i][j].y()+direction[0]*self.Tiles[i][j].height(),
            self.Tiles[i][j].width(),
            self.Tiles[i][j].height()
        ))
        self.animation.start()
        a=destination[0]
        b=destination[1]
        self.animation2=QPropertyAnimation(self.Tiles[a][b],b"geometry")
        self.animation2.setDuration(100)
        
        self.animation2.setStartValue(QRect(
            self.Tiles[a][b].x(),
            self.Tiles[a][b].y(),
            self.Tiles[a][b].width(),
            self.Tiles[a][b].height()
        ))

        self.animation2.setEndValue(QRect(
            self.Tiles[a][b].x()-direction[1]*self.Tiles[a][b].width(),
            self.Tiles[a][b].y()-direction[0]*self.Tiles[a][b].height(),
            self.Tiles[a][b].width(),
            self.Tiles[a][b].height()
        ))
        self.animation2.start()
        self.currentState+=isNext
        swapPositionsInTileList(self.Tiles,destination,location)
         


    def solve(self):
        if(self.lineEdit_Goal.hasAcceptableInput() and
            self.lineEdit_Start.hasAcceptableInput() and
            self.lineEdit_Level.hasAcceptableInput()):
            #correct input user
            
            def stringToTuple(string):
                a=[]
                string=list(string)
                for i in string:
                    if i != ' ':
                        a.append(int(i))
                return tuple(a)
            

            start = board.Board(stringToTuple(self.lineEdit_Start.text()))
            goal = board.Board(stringToTuple(self.lineEdit_Goal.text()))
            # self.Tiles=list(self.tempTiles)
            
            # print(start)
            # print(goal)
            


            if(self.comboBox_Method.currentIndex()==0):
                #dfsTraverse :
                dfs=traverse.DFSTraverseClass()
                self.sol=traverse.DFSTraverseClass.DFSTraverse(dfs,start,goal,(int)(self.lineEdit_Level.text()))
                a=([i.getTable() for i in self.sol])
                a.insert(0,start.getTable())
                self.sol=tuple(a)
            elif(self.comboBox_Method.currentIndex()==1):
                #bfsTraverse :
                self.sol=traverse.BFSTraverse(start,goal,(int)(self.lineEdit_Level.text()))
                b=[i.getTable() for i in self.sol]
                b.reverse()
                b.insert(0,start.getTable())
                self.sol=tuple(b)
            if self.sol.__len__()>1:
                self.changeTable(start.getTable(),self.comboBox_Method.currentIndex())
                self.currentState = 0
                self.pushButton_next.setEnabled(True)
                self.pushButton_prev.setEnabled(True)
                
        else:
            d = QDialog(self)
            d.setFixedSize(300,100)
            b1 = QPushButton("ok",d)
            b1.move(math.floor(d.width()/2)-math.floor(b1.width()/3),math.floor(d.height()/2))
            d.setWindowTitle("Dialog")
            l1 = QLabel("Please enter valid inputs ...",d)
            l1.move(math.floor(d.width()/2)-math.floor(l1.width()),math.floor(d.height()/3))
            b1.clicked.connect(lambda : d.close())
            d.setWindowModality(Qt.ApplicationModal)
            d.exec_()


            
    def nextState(self):
        def findZeroLocation(b):

            for i in range(0,3):
                for j in range(0,3):
                    if b[i][j] == 0:
                        return (i,j)
            
        if 0 <= self.currentState < self.sol.__len__()-1:
            a=findZeroLocation(self.sol[self.currentState])
            b=findZeroLocation(self.sol[self.currentState+1])

            def findMovementDirection(a,b):
                direction = (a[0]-b[0] , a[1]-b[1])
                return direction

            self.moveTile(a,b,findMovementDirection(a,b),1)
                    
    def prevState(self):
        def findZeroLocation(b):

            for i in range(0,3):
                for j in range(0,3):
                    if b[i][j] == 0:
                        return (i,j)
            
        if  1 <= self.currentState < self.sol.__len__():
            a=findZeroLocation(self.sol[self.currentState])
            b=findZeroLocation(self.sol[self.currentState-1])

            def findMovementDirection(a,b):
                direction = (a[0]-b[0] , a[1]-b[1])
                return direction

            self.moveTile(a,b,findMovementDirection(a,b),-1)