class FaderWidget(QLabel):

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

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

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

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

    def fade(self, old_pic, old_geometry, move_to):
        """Fade from previous tab to new tab."""
        if self.isVisible():
            self.close()
        if self.timeline.state():
            self.timeline.stop()
        self.setGeometry(old_geometry)
        self.move(1, move_to)
        self.old_pic = old_pic
        self.timeline.start()
        self.show()
Exemple #2
0
class FaderWidget(QtWidgets.QWidget):

    pixmap_opacity = 0

    def __init__(self, old_widget, new_widget):

        QtWidgets.QWidget.__init__(self, new_widget)

        self.old_pixmap = QtGui.QPixmap(new_widget.size())
        old_widget.render(self.old_pixmap)
        self.pixmap_opacity = 1.0

        self.timeline = QTimeLine()
        self.timeline.valueChanged.connect(self.animate)
        self.timeline.finished.connect(self.close)
        self.timeline.setDuration(500)
        self.timeline.start()

        self.resize(new_widget.size())
        self.show()

    def paintEvent(self, event):
        painter = QtGui.QPainter()
        painter.begin(self)
        painter.setOpacity(self.pixmap_opacity)
        painter.drawPixmap(0, 0, self.old_pixmap)
        painter.end()

    def animate(self, value):
        self.pixmap_opacity = 1.0 - value
        self.repaint()
class FaderWidget(QWidget):
    """
    A QWidget that allows for fading in and out on display.
    """
    def __init__(self, old_widget, new_widget):

        QWidget.__init__(self, new_widget)

        self.old_pixmap = QPixmap(new_widget.size())
        old_widget.render(self.old_pixmap)
        self.pixmap_opacity = 1.0

        self.timeline = QTimeLine()
        self.timeline.valueChanged.connect(self.animate)
        self.timeline.finished.connect(self.close)
        self.timeline.setDuration(450)
        self.timeline.start()

        self.resize(new_widget.size())
        self.show()

    def paintEvent(self, event):

        painter = QPainter()
        painter.begin(self)
        painter.setOpacity(self.pixmap_opacity)
        painter.drawPixmap(0, 0, self.old_pixmap)
        painter.end()

    def animate(self, value):
        self.pixmap_opacity = 1.0 - value
        self.repaint()
Exemple #4
0
class FaderWidget(QWidget):

    def __init__(self, old_widget, new_widget):
        super(FaderWidget, self).__init__(new_widget)

        self.old_pixmap = QPixmap(new_widget.size())
        old_widget.render(self.old_pixmap)
        self.pixmap_opacity = 1.0

        self.timeline = QTimeLine()
        self.timeline.valueChanged.connect(self.animate)
        self.timeline.finished.connect(self.close)
        self.timeline.setDuration(500)
        self.timeline.start()

        self.resize(new_widget.size())
        self.show()

    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)
        painter.setOpacity(self.pixmap_opacity)
        painter.drawPixmap(0, 0, self.old_pixmap)
        painter.end()

    def animate(self, value):
        self.pixmap_opacity = 1.0 - value
        self.repaint()
Exemple #5
0
class CCountUp(QLabel):
    def __init__(self, *args, **kwargs):
        super(CCountUp, self).__init__(*args, **kwargs)
        self.isFloat = False  # 是否是小数
        font = self.font() or QFont()
        font.setBold(True)
        self.setFont(font)
        self.timeline = QTimeLine(6000, self)
        self.timeline.setEasingCurve(QEasingCurve.OutExpo)
        self.timeline.frameChanged.connect(self.onFrameChanged)

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

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

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

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

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

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

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

        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)

        self.timeline = QTimeLine()
        settings = [
        #             item               position    rotation at
        #                                 x    y    time 0  /  1
            ( self.headItem,              0,  -18,      20,   -20 ),
            ( self.upperLeftArmItem,    -15,  -10,     190,   180 ),
            ( self.lowerLeftArmItem,     30,    0,      50,    10 ),
            ( self.upperRightArmItem,    15,  -10,     300,   310 ),
            ( self.lowerRightArmItem,    30,    0,       0,   -70 ),
            ( self.upperRightLegItem,    10,   32,      40,   120 ),
            ( self.lowerRightLegItem,    30,    0,      10,    50 ),
            ( self.upperLeftLegItem,    -10,   32,     150,    80 ),
            ( self.lowerLeftLegItem,     30,    0,      70,    10 ),
            ( self.torsoItem,             0,    0,       5,   -20 )
        ]
        self.animations = []
        for item, pos_x, pos_y, rotation1, rotation2 in settings: 
            item.setPos(pos_x,pos_y)
            animation = QGraphicsItemAnimation()
            animation.setItem(item)
            animation.setTimeLine(self.timeline)
            animation.setRotationAt(0, rotation1)
            animation.setRotationAt(1, rotation2)
            self.animations.append(animation)
        self.animations[0].setScaleAt(1, 1.1, 1.1)
    
        self.timeline.setUpdateInterval(1000 / 25)
        self.timeline.setCurveShape(QTimeLine.SineCurve)
        self.timeline.setLoopCount(0)
        self.timeline.setDuration(2000)
        self.timeline.start()

    def boundingRect(self):
        return QRectF()

    def paint(self, painter, option, widget=None):
        pass
Exemple #7
0
class Robot(RobotPart):
    def __init__(self):
        super(Robot, self).__init__()

        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)

        self.timeline = QTimeLine()
        settings = [
            #             item               position    rotation at
            #                                 x    y    time 0  /  1
            (self.headItem, 0, -18, 20, -20),
            (self.upperLeftArmItem, -15, -10, 190, 180),
            (self.lowerLeftArmItem, 30, 0, 50, 10),
            (self.upperRightArmItem, 15, -10, 300, 310),
            (self.lowerRightArmItem, 30, 0, 0, -70),
            (self.upperRightLegItem, 10, 32, 40, 120),
            (self.lowerRightLegItem, 30, 0, 10, 50),
            (self.upperLeftLegItem, -10, 32, 150, 80),
            (self.lowerLeftLegItem, 30, 0, 70, 10),
            (self.torsoItem, 0, 0, 5, -20)
        ]
        self.animations = []
        for item, pos_x, pos_y, rotation1, rotation2 in settings:
            item.setPos(pos_x, pos_y)
            animation = QGraphicsItemAnimation()
            animation.setItem(item)
            animation.setTimeLine(self.timeline)
            animation.setRotationAt(0, rotation1)
            animation.setRotationAt(1, rotation2)
            self.animations.append(animation)
        self.animations[0].setScaleAt(1, 1.1, 1.1)

        self.timeline.setUpdateInterval(1000 / 25)
        self.timeline.setCurveShape(QTimeLine.SineCurve)
        self.timeline.setLoopCount(0)
        self.timeline.setDuration(2000)
        self.timeline.start()

    def boundingRect(self):
        return QRectF()

    def paint(self, painter, option, widget=None):
        pass
Exemple #8
0
    def wheelEvent(self, event):
        numDegrees = event.angleDelta() / 8
        print("wheel: {}".format(numDegrees))
        numSteps = numDegrees.y() / 15
        self._numScheduledScalings += numSteps
        if self._numScheduledScalings * numSteps < 0:
            self._numScheduledScalings = numSteps

        anim = QTimeLine(350, self)
        anim.setUpdateInterval(20)
        anim.valueChanged.connect(self.ScalingTime)
        anim.finished.connect(self.AnimFinished)
        anim.start()
Exemple #9
0
 def wheelEvent(self, event):
     # Check if zooming is enabled
     if not self.parent.menu.options[1].isChecked(): return
     # Zooming event on mouse scroll
     numDegrees = event.angleDelta() / 8
     numSteps = (numDegrees / 15).y()
     self._numScheduledScalings += numSteps
     if self._numScheduledScalings * numSteps < 0:
         self._numScheduledScalings = numSteps
     anim = QTimeLine(350, self)
     anim.setUpdateInterval(20)
     anim.valueChanged.connect(self.scalingTime)
     anim.finished.connect(self.animFinished)
     anim.start()
Exemple #10
0
    def wheelEvent(self, event):
        numDegrees = event.angleDelta() / 8
        numSteps = numDegrees / 15
        self._numScheduledScalings += numSteps.y()
        """ if user moved the wheel in another direction, we reset previously scheduled scalings """
        if self._numScheduledScalings * numSteps.y() < 0:
            self._numScheduledScalings = numSteps.y()

        anim = QTimeLine(350, self)
        anim.setUpdateInterval(20)

        anim.valueChanged.connect(self.scalingTime)
        anim.finished.connect(self.animFinished)

        anim.start()
Exemple #11
0
    def zoom(self, numDegrees):
        numSteps = numDegrees / 15
        self._numScheduledScalings += numSteps

        if (
                self._numScheduledScalings * numSteps < 0
        ):  # if user moved the wheel in another direction, we reset previously scheduled scalings
            self._numScheduledScalings = numSteps

        anim = QTimeLine(350, self)
        anim.setUpdateInterval(20)

        anim.valueChanged.connect(self.scalingTime)
        anim.finished.connect(self.scaleAnimFinished)
        anim.start()
Exemple #12
0
    def wheelEvent(self, event):
        degree = event.angleDelta().y() / 8
        step = degree / 15

        self.scheduledscaling = self.scheduledscaling + step

        animation = QTimeLine(350)
        animation.setUpdateInterval(20)
        animation.valueChanged.connect(
            animation.currentValue
        )  #Timeline does not start without this line, maybe a QT bug
        animation.valueChanged.connect(
            lambda: self.scale(1.0 + self.scheduledscaling / 300.0, 1.0 + self.
                               scheduledscaling / 300.0))
        animation.finished.connect(self.reset)
        animation.start()
Exemple #13
0
    def translateVerticalEvent(self, dy):
        numSteps = dy * 20
        self._numScheduledVTranslations += numSteps

        if (
                self._numScheduledVTranslations * numSteps < 0
        ):  # if user moved the wheel in another direction, we reset previously scheduled scalings
            self._numScheduledVTranslations = numSteps

        if not self.animatingV:
            anim = QTimeLine(350, self)
            anim.setUpdateInterval(10)

            anim.valueChanged.connect(self.translateVTime)
            anim.finished.connect(self.translateVAnimFinished)
            anim.start()
Exemple #14
0
class AnimationView(QWidget):
	"""docstring for AnimationView"""

	frameIndex = 0
	frameCount = 0

	def __init__(self, bmpFrames):
		super(AnimationView, self).__init__()
		self.setFixedSize(frameWidth,frameHeight)
		self.bmpSize =64
		if bmpFrames :
			self.bmpFrames = bmpFrames
			self.frameCount = len(bmpFrames)
			self.bmpSize = bmpFrames[0].width()
		else :
			self.initDefaultFrames()

	def initDefaultFrames(self):
		self.bmpFrames = []
		defaultImage = QImage("..\\resource\\default.bmp")
		imageWidth = defaultImage.width()
		imageHeight = defaultImage.height()
		#判断各幀图片是否是横向排列
		isHorizontal = min(imageWidth,imageHeight) == imageHeight
		#计算幀数
		self.frameCount = imageWidth//frameWidth if isHorizontal else imageHeight//frameHeight
		for i in range(0,self.frameCount):
			pixmap = QPixmap(defaultImage.copy(i*frameWidth if isHorizontal else 0,
				0 if isHorizontal else i*frameHeight,frameWidth,frameHeight))
			eliminateBackgroundColor(pixmap)
			self.bmpFrames.append(pixmap)
	
	def createAnimation(self):
		self.timeLine = QTimeLine(10*1000)
		self.timeLine.setFrameRange(0,60//(4/self.frameCount))
		self.timeLine.frameChanged.connect(self.refreshFrameIndex)
		self.timeLine.setLoopCount(0)
		self.timeLine.setCurveShape(3)
		self.timeLine.start()

	def refreshFrameIndex(self,currFrame):
		self.update()
		self.frameIndex = (self.frameIndex+1) % self.frameCount

	def paintEvent(self,event):
		painter = QPainter(self)
		painter.drawPixmap((frameWidth-self.bmpSize)//2,(frameHeight-self.bmpSize)//2,self.bmpFrames[self.frameIndex])
class MyView(QGraphicsView):
    def __init__(self):
        super().__init__()

        self.initView()
        self.setupScene()
        self.setupAnimation()

        self.setGeometry(300, 150, 250, 250)

    def initView(self):

        self.setWindowTitle("Progress meter")
        self.setRenderHint(QPainter.Antialiasing)

        policy = Qt.ScrollBarAlwaysOff
        self.setVerticalScrollBarPolicy(policy)
        self.setHorizontalScrollBarPolicy(policy)

        self.setBackgroundBrush(self.palette().window())

        self.pm = ProgressMeter(self)
        self.pm.setPos(55, 55)

    def setupScene(self):

        self.scene = QGraphicsScene(self)
        self.scene.setSceneRect(0, 0, 250, 250)
        self.scene.addItem(self.pm)

        self.setScene(self.scene)

    def setupAnimation(self):

        self.timer = QTimeLine()
        self.timer.setLoopCount(0)
        self.timer.setFrameRange(0, 100)

        self.timer.frameChanged[int].connect(self.doStep)
        self.timer.start()

    def doStep(self, i):

        if not self.pm.increment():
            self.timer.stop()

        self.pm.update()
Exemple #16
0
    def __init__(self, size, color):
        super().__init__()

        self._loading_angle = 0
        self.width = 0
        self.color = color

        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setStyleSheet("background:transparent;")

        self.resize(size, size)
        self.center()
        self.initUI()

        timeline = QTimeLine(3000, self)
        timeline.setFrameRange(360, 0)
        timeline.frameChanged.connect(self.setLoadingAngle)
        timeline.start()
Exemple #17
0
    def __init__(self, size, color, side):
        super().__init__()

        self._next_step = 0
        self.width = 0
        self.color = color
        self.side = side

        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setStyleSheet("background:transparent;")

        self.resize(size, size)
        self.center()
        self.initUI()

        timeline = QTimeLine(3000, self)
        timeline.setFrameRange(size, 0)
        timeline.frameChanged.connect(self.setNextStep)
        timeline.start()
    def wheelEvent(self, event: QWheelEvent) -> None:
        if event.modifiers() & Qt.ControlModifier:
            num_degrees = event.angleDelta().y() / 8.0
            num_steps = num_degrees / 15.0

            self.num_scheduled_steps += num_steps

            if self.num_scheduled_steps * num_steps < 0:
                self.num_scheduled_steps = num_steps

            animation = QTimeLine(duration=350, parent=self)
            animation.setUpdateInterval(20)

            value_changed_sig: pyqtBoundSignal = animation.valueChanged
            value_changed_sig.connect(self.scaling_step)

            finished_sig: pyqtBoundSignal = animation.finished
            finished_sig.connect(self.animation_finished)

            animation.start()
        else:
            super().wheelEvent(event)
Exemple #19
0
class FaderWidget(QWidget):
    def __init__(self, old_widget, new_widget):

        QWidget.__init__(self, new_widget)

        self.old_pixmap = QPixmap(new_widget.size())
        old_widget.render(self.old_pixmap)

        self.pixmap_opacity = None
        self.timeline = QTimeLine(333, self)
        self.timeline.valueChanged.connect(self.animate)
        self.timeline.finished.connect(self.close)

        self.resize(new_widget.size())
        self.show()

    def start(self, old_widget, new_widget):
        self.pixmap_opacity = 1.0
        self.old_pixmap = QPixmap(new_widget.size())
        old_widget.render(self.old_pixmap)

        self.timeline.start()

        self.resize(new_widget.size())
        self.show()

    def animate(self, value):

        self.pixmap_opacity = 1.0 - value
        self.repaint()

    def paintEvent(self, event):
        if self.pixmap_opacity:
            QWidget.paintEvent(self, event)
            painter = QPainter(self)
            painter.setOpacity(self.pixmap_opacity)
            painter.drawPixmap(0, 0, self.old_pixmap)
class E5AnimatedWidget(QWidget):
    """
    Class implementing an animated widget.
    """
    DirectionDown = 0
    DirectionUp = 1

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

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

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

        self.setMaximumHeight(0)

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

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

        shown = 0
        hidden = 0

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

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

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

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

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

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

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

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

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

        super(E5AnimatedWidget, self).resizeEvent(evt)
Exemple #21
0
class TSScene(QGraphicsScene):

    starttimechanged = pyqtSignal(str)
    endtimechanged = pyqtSignal(str)

    def __init__(self, parent, width=14, height=12, numofchannel=6):
        super(TSScene, self).__init__(parent)

        # set waveform windows
        figure = Figure()
        figure.set_size_inches(width, height)
        self.graphwidth = figure.dpi * width
        self.canvas = FigureCanvas(figure)
        self.addWidget(self.canvas)
        self.canvas.mpl_connect('button_press_event',self.button_press_event)
        self.canvas.mpl_connect('button_release_event', self.button_release_event)
        self.canvas.mpl_connect('motion_notify_event', self.motion_notify_event)
        self.canvas.mpl_connect('scroll_event', self.scroll_event)

        self.axesavailability = [True for i in range(numofchannel)]
        self.axes = []
        for i in range(numofchannel):
            self.axes.append(figure.add_subplot(str(numofchannel)+'1'+str(i+1)))


        # set backend data model
        self.data = TSData()
        self.visibleWave = {}
        self.starttime = None
        self.endtime = None

        # prepare for user input
        self.downxcoord = None
        self.wheelactive = False
        self.rect = None

        self.installEventFilter(self)
        self.showgap = False
        self.downbutton = None
        self.currentxdata = None

        self.count = 0
        self.state = 'ready'

        self.timeline = QTimeLine(1)
        self.timeline.setCurrentTime(0)
        self.timeline.setUpdateInterval(1)
        self.timeline.finished.connect(self.timeshift)
        self.timeline.finished.connect(self.animfinished)



    def animfinished(self):
        self.state = 'ready'
        self.timeline.setCurrentTime(0)

    def togglegap(self):
        self.showgap = ~self.showgap

        tmplist = self.visibleWave.copy()
        for wave in tmplist:
            self.refreshwave(wave,tmplist[wave][1])

            # self.togglewave(wave)
            # self.togglewave(wave, tmplist[wave][1])

    def applytime(self, start: str, end: str):
        if self.data is None:
            return


        for wave in self.visibleWave:
            if start<self.visibleWave[wave][3]:
                start = self.visibleWave[wave][3]
            if end>self.visibleWave[wave][4]:
                end = self.visibleWave[wave][4]

        self.starttime = UTCDateTime(start)
        self.endtime = UTCDateTime(end)
        print((self.starttime, self.endtime, '-----------------'))

        tmplist = self.visibleWave.copy()
        for wave in tmplist:
            self.refreshwave(wave, tmplist[wave][1])
            # self.togglewave(wave)
            # self.togglewave(wave, tmplist[wave][2])

    def loadfile(self, filename: str):
        self.data.loadFile(filename)

    def getlist(self):
        return self.data.getlist()

    def getsegments(self, item: object):
        waves = self.data.getsegments(item.text(0))


        wavelist = QListWidget()
        for w in waves:
            wavelist.addItem(w)
            # print(w)
        wavelist.itemDoubleClicked.connect(self.segmentselected)

        wavelistwindowlayout = QVBoxLayout()
        wavelistwindowlayout.addWidget(wavelist)

        self.wavelistwindow = QDialog(self.parent())
        self.wavelistwindow.setWindowTitle('segments')
        self.wavelistwindow.setLayout(wavelistwindowlayout)
        self.wavelistwindow.resize(800,600)
        self.wavelistwindow.show()
        self.segmentsource = item.text(0)
        self.currentitem = item

    def segmentselected(self, segment: str):

        matches = re.match(r'[^ ]+ \| ([^ ]+) - ([^ ]+) \| .*', segment.text(), flags=0)
        start = UTCDateTime(matches.group(1))
        end = UTCDateTime(matches.group(2))
        print(start)
        print(end)

        if self.segmentsource in self.visibleWave:
            self.applytime(start, end)
        else:
            self.starttime = start
            self.endtime = end
            print((self.segmentsource))
            self.togglewave(self.segmentsource)
            self.currentitem.setSelected(True)


    def refreshwave(self, wave: str, colorcode:int=0):
        if wave in self.visibleWave:
            axes, lines, _, _, _, _ = self.visibleWave[wave]
            self.removewave(axes, lines)
            self.visibleWave.pop(wave, None)
            channelid = self.axes.index(axes)
            self.axesavailability[channelid] = True
            waveform, wavename, starttime, endtime, gaps = self.data.getwaveform(wave, self.starttime, self.endtime)
            axes, lines = self.displaywave(wavename, waveform, gaps)
            if axes is not None:
                self.visibleWave[wave] = (axes, lines, colorcode, starttime, endtime, gaps)

    def hidewave(self, wave: str, colorcode:int=0):
        if wave in self.visibleWave:
            axes, lines, _, _, _, _ = self.visibleWave[wave]
            self.removewave(axes, lines)
            self.visibleWave.pop(wave, None)
            channelid = self.axes.index(axes)
            self.axesavailability[channelid] = True
            if len(self.visibleWave)==0:
                self.starttime = None
                self.endtime = None
            return True

    def showwave(self, wave: str, starttime=None, endtime=None):
        if starttime is None or endtime is None:
            if wave in self.visibleWave:
                pass
            else:
                self.togglewave(wave)
        else:
            self.starttime = starttime
            self.endtime = endtime
            tmplist = self.visibleWave.copy()
            for wave in tmplist:
                self.refreshwave(wave, tmplist[wave][1])
            if wave not in self.visibleWave:
                self.togglewave(wave)




    def togglewave(self, wave: str, colorcode:int=0):
        if wave in self.visibleWave:
            axes, lines, _, _, _, _ = self.visibleWave[wave]
            self.removewave(axes, lines)
            self.visibleWave.pop(wave, None)
            channelid = self.axes.index(axes)
            self.axesavailability[channelid] = True
            if len(self.visibleWave)==0:
                self.starttime = None
                self.endtime = None
        else:
            # print(wave)

            waveform, wavename, starttime, endtime, gaps = self.data.getwaveform(wave, self.starttime, self.endtime)
            print((starttime, endtime))
            axes, lines = self.displaywave(wavename, waveform, gaps)
            if axes is not None:
                self.visibleWave[wave] = (axes, lines, colorcode, starttime, endtime, gaps)
                #print("togglewave:", starttime, endtime)


    def displaywave(self, wavename: str, waveform: np.array, gaps, colorcode: int=None):

        if True not in self.axesavailability:
            return None, None
        else:

            location = self.axesavailability.index(True)
            axes = self.axes[location]
            self.axesavailability[location] = False
            if wavename is not None and waveform is not None:
                if colorcode is None:
                    colorcode = 'C'+str(location%10)

                times = waveform[0,:]
                span = round(len(times)/4)

                if span<1:
                    span = 1

                axes.set_xticks(times[::span])
                axes.set_xticklabels([UTCDateTime(t).strftime("%Y-%m-%d %H:%M:%S") for t in times[::span]])

                lines = axes.plot(times, waveform[1,:],linestyle="-", label=wavename, color=colorcode)
                if self.showgap:
                    for g in gaps:

                        if g[4].timestamp>=times[0] and g[5].timestamp<times[-1]:
                            axes.axvspan(g[4],g[5],facecolor='0.2',alpha=0.5)
                axes.legend()

                self.canvas.draw()

                if self.endtime is not None and self.starttime is not None and len(times)>0:
                    timewindow = self.endtime-self.starttime
                    if abs(times[0]-times[-1]-timewindow)/timewindow<0.1:
                        self.starttime = UTCDateTime(times[0])
                        self.endtime = self.starttime + timewindow
                elif len(times)>0:
                    self.starttime = UTCDateTime(times[0])
                    self.endtime = UTCDateTime(times[-1])



                self.starttimechanged.emit(self.starttime.strftime("%Y-%m-%d %H:%M:%S"))
                self.endtimechanged.emit(self.endtime.strftime("%Y-%m-%d %H:%M:%S"))
                return axes, lines
            else:
                lines = None
                axes.legend([wavename])

            return axes, lines




    def removewave(self, axes: Axes, lines: Line2D):
        if lines is not None:
            lines.pop(0).remove()
        axes.relim()
        axes.autoscale_view(True, True, True)
        axes.clear()
        self.canvas.draw()

    def timeshift(self):
        if self.downxcoord is None or self.currentxdata is None:
            return
        shift = self.downxcoord-self.currentxdata
        if shift == 0:
            print('skipped')
            return

        if self.starttime is None:
            return

        starttime = self.starttime + shift
        endtime = self.endtime + shift

        for wave in self.visibleWave:
            if starttime<self.visibleWave[wave][3]:
                starttime = self.visibleWave[wave][3]
            if endtime>self.visibleWave[wave][4]:
                endtime = self.visibleWave[wave][4]


        if starttime!=self.starttime and endtime!=self.endtime:
            self.starttime = starttime
            self.endtime = endtime

            tmplist = self.visibleWave.copy()

            for wave in tmplist:
                self.refreshwave(wave, tmplist[wave][1])
                # self.togglewave(wave)
                # self.togglewave(wave, tmplist[wave][2])



        return

    def timescale(self, delta: float):
        if self.starttime is None:
            return

        shift = (self.endtime - self.starttime) * -delta*0.1

        starttime = self.starttime + shift
        endtime = self.endtime - shift


        for wave in self.visibleWave:
            if starttime<self.visibleWave[wave][3]:
                starttime = self.starttime
            if endtime>self.visibleWave[wave][4]:
                endtime = self.endtime


        if endtime-starttime<0.1:
            pass
        elif starttime==self.starttime and endtime==self.endtime:
            pass
        else:
            self.starttime = starttime
            self.endtime = endtime
            tmplist = self.visibleWave.copy()
            for wave in tmplist:
                self.refreshwave(wave, tmplist[wave][1])
                # self.togglewave(wave)
                # self.togglewave(wave, tmplist[wave][1])






    def button_press_event(self, event):

        if self.starttime is None:
            return
        self.downxcoord = event.xdata
        self.downx = event.x
        self.downbutton = event.button
        self.count = 0




    def motion_notify_event(self, event):
        # print(event.button, self.starttime, self.downbutton, self.downxcoord, event.xdata)
        self.count += 1
        self.currentxdata = event.xdata
        #print(self.currentxdata,"+" * 10)

        if self.starttime is None:
            return
        elif self.downxcoord is not None:
            if self.downbutton == 1 and self.timeline.currentTime()==0:
                self.state = 'busy'
                self.timeline.start()
            elif self.downbutton == 1:
                pass
            elif self.downbutton == 3:
                if self.rect is not None:
                    self.removeItem(self.rect)
                if self.downx < event.x:
                    self.rect = self.addRect(self.downx, 0, event.x - self.downx, self.height(), pen=QPen(Qt.red))
                else:
                    self.rect = self.addRect(event.x, 0, self.downx - event.x, self.height(), pen=QPen(Qt.red))

    def button_release_event(self, event):
        if self.starttime is None:
            return
        if event.button == 3:
            left = 225
            right = 1215
            if self.downxcoord < event.xdata:
                start = self.downxcoord
                end = event.xdata
            else:
                start = event.xdata
                end = self.downxcoord
            start = UTCDateTime(start)
            end = UTCDateTime(end)
            print((start,end,'================'))
            self.applytime(start, end)
        # self.downx = None
        self.downbutton = None
        self.removeItem(self.rect)
        self.rect = None
        self.downxcoord = None
        self.currentxdata = None
        #print(self.count,'count!!!!!!!!')
        self.count=0

    def scroll_event(self, event):

        delta = -event.step

        if self.wheelactive==False and event.xdata>= self.starttime and event.xdata<= self.endtime:
            self.wheelactive = True
            self.timescale(delta)
            self.wheelactive = False


    def exportmetadata(self, filename: tuple):
        wavelist = self.getlist()
        
        outfile =  open(filename[0]+'.txt','w')
        for network in wavelist:
            for station in wavelist[network]:
                for wave in wavelist[network][station]:
                    for w in wavelist[network][station][wave]:
                        outfile.write("%s\n\n" % w)

        outfile.close()





    def exportwaveform(self, filename: tuple):
        traces = []
        for wave in self.visibleWave:
            fill_value = 'last'
            waveform, wavename, starttime, endtime, gaps = self.data.readdisc(wave, self.starttime, self.endtime, resample=False, fill_value=fill_value)
            traces.append(waveform)

        stream = Stream(traces=traces)
        if 'MSEED' in filename[1]:
            stream.write(filename[0] + ".mseed", format='MSEED')
        elif 'txt' in filename[1]:
            stream.write(filename[0] + ".txt", format='TSPAIR')


    def gettimeboundary(self):
        return self.starttime, self.endtime



        return False
class CustomProxy(QGraphicsProxyWidget):
    def __init__(self, parent=None, wFlags=0):
        super(CustomProxy, self).__init__(parent, wFlags)

        self.popupShown = False
        self.currentPopup = None

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    clicked = pyqtSignal()

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

        self.resize(self.maximumSize())

        self.m_backgroundPixmap = QPixmap()

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

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

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

        self.m_timeline.frameChanged.connect(frameChanged)

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

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

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

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

    def slidePos(self):
        return self.m_slidePos

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

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

        super(SideSlideDecorator, self).paintEvent(_event)

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

        super(SideSlideDecorator, self).mousePressEvent(_event)

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

        :param tuple nx_node: Node info
        :param center_pos: The position of the center node
        :param nx_pos: Position of the nodes in the graph
        :param int steps: The steps from the center identity
        :param int steps_max: The steps max of the graph
        """
        super().__init__(nx_node, nx_pos)

        self.steps = steps
        self.steps_max = steps_max
        self.highlighted = False

        # text inside ellipse
        self.text_item = QGraphicsSimpleTextItem(self)
        self.text_item.setText(self.text)
        # center ellipse around text
        self.setRect(
            0,
            0,
            self.text_item.boundingRect().width() * 2,
            self.text_item.boundingRect().height() * 2
        )

        #  set anchor to the center
        self.setTransform(
            QTransform().translate(-self.boundingRect().width() / 2.0, -self.boundingRect().height() / 2.0))
        # center text in ellipse
        self.text_item.setPos(self.boundingRect().width() / 4.0, self.boundingRect().height() / 4.0)

        # cursor change on hover
        self.setAcceptHoverEvents(True)
        self.setZValue(1)

        # animation and moves
        self.timeline = None
        self.loading_timer = QTimer()
        self.loading_timer.timeout.connect(self.next_tick)
        self.loading_counter = 0
        self._refresh_colors()
        self.setPos(center_pos)
        self.move_to(nx_pos)

    def _refresh_colors(self):
        """
        Refresh elements in the node
        """
        # color around ellipse
        outline_color = QColor('black')
        outline_style = Qt.SolidLine
        outline_width = 1
        if self.status_wallet:
            outline_color = QColor('grey')
            outline_width = 2
        if not self.status_member:
            outline_color = QColor('red')
            outline_style = Qt.SolidLine
        self.setPen(QPen(outline_color, outline_width, outline_style))

        if self.highlighted:
            text_color = QColor('grey')
        else:
            text_color = QColor('black')

        if self.status_wallet == NodeStatus.HIGHLIGHTED:
            text_color = QColor('grey')
        self.text_item.setBrush(QBrush(text_color))

        # create gradient inside the ellipse
        gradient = QRadialGradient(QPointF(0, self.boundingRect().height() / 4), self.boundingRect().width())
        color = QColor()
        color.setHsv(120 - 60 / self.steps_max * self.steps,
                     180 + 50 / self.steps_max * self.steps,
                     60 + 170 / self.steps_max * self.steps)
        if self.highlighted:
            color = color.darker(200)
        color = color.lighter(math.fabs(math.sin(self.loading_counter / 100 * math.pi) * 100) + 100)
        gradient.setColorAt(0, color)
        gradient.setColorAt(1, color.darker(150))
        self.setBrush(QBrush(gradient))

    def move_to(self, nx_pos):
        """
        Move to corresponding position
        :param nx_pos:
        :return:
        """
        origin_x = self.x()
        origin_y = self.y()
        final_x = nx_pos[self.id][0]
        final_y = nx_pos[self.id][1]

        def frame_move(frame):
            value = self.timeline.valueForTime(self.timeline.currentTime())
            x = origin_x + (final_x - origin_x) * value
            y = origin_y + (final_y - origin_y) * value
            self.setPos(x, y)
            self.scene().node_moved.emit(self.id, x, y)

        def timeline_ends():
            self.setPos(final_x, final_y)
            self.timeline = None

        # Remember to hold the references to QTimeLine and QGraphicsItemAnimation instances.
        # They are not kept anywhere, even if you invoke QTimeLine.start().
        self.timeline = QTimeLine(1000)
        self.timeline.setFrameRange(0, 100)
        self.timeline.frameChanged.connect(frame_move)
        self.timeline.finished.connect(timeline_ends)

        self.timeline.start()

    def highlight(self):
        """
        Highlight the edge in the scene
        """
        self.highlighted = True
        self._refresh_colors()
        self.update(self.boundingRect())

    def neutralize(self):
        """
        Neutralize the edge in the scene
        """
        self.highlighted = False
        self._refresh_colors()
        self.update(self.boundingRect())

    def start_loading_animation(self):
        """
        Neutralize the edge in the scene
        """
        if not self.loading_timer.isActive():
            self.loading_timer.start(10)

    def stop_loading_animation(self):
        """
        Neutralize the edge in the scene
        """
        self.loading_timer.stop()
        self.loading_counter = 100
        self._refresh_colors()
        self.update(self.boundingRect())

    def next_tick(self):
        """
        Next tick
        :return:
        """
        self.loading_counter += 1
        self.loading_counter %= 100
        self._refresh_colors()
        self.update(self.boundingRect())
class Widget(Ui_CollectionsWidget, QWidget, ScreenWidget):
    name = "collectionSelection"

    def __init__(self):
        QWidget.__init__(self)
        self.setupUi(self)
        self.collections = None
        self.current_item = None
        self.last_item = None
        self.collectionList.itemClicked.connect(self.openItem)
        self.collectionList.currentItemChanged.connect(self.itemChanged)

    def fillCollections(self):
        self.collectionList.clear()
        selected = None
        for index, collection in enumerate(self.collections):
            self.addItem(collection)
            if ctx.installData.autoCollection  == collection:
                selected = index

        if not selected:
            selected = 0

        self.current_item = self.collectionList.item(selected)
        self.last_item = self.current_item
        self.collectionList.setCurrentRow(selected)

    def shown(self):
        self.collections = ctx.collections
        self.fillCollections()
        ctx.mainScreen.disableNext()
        if self.current_item:
            self.openItem(self.current_item)
        else:
            self.openItem(self.collectionList.item(0))
        self.check()

    def execute(self):
        ctx.installData.autoCollection = self.collectionList.itemWidget(self.current_item).collection
        return True

    def check(self):
        if self.current_item:
            ctx.mainScreen.enableNext()
        else:
            ctx.mainScreen.disableNext()

    def itemChanged(self, current, previous):
        self.current_item = current
        self.check()

    def addItem(self, collection):
        item = QListWidgetItem(self.collectionList)
        item.setSizeHint(QSize(36, CLOSED_SIZE))
        self.collectionList.addItem(item)
        self.collectionList.setItemWidget(item, CollectionItem(self, collection, item))

    def openItem(self, item):
        if item == self.last_item:
            return

        if self.last_item:
            self.closeItem(self.last_item)

        self.animation = QTimeLine(ANIMATE_TIME, self)
        self.animation.setFrameRange(36, EXPANDED_SIZE)
        self.animation.frameChanged.connect(lambda x: item.setSizeHint(QSize(32, x)))
        self.animation.start()
        self.last_item = item
        self.animation.finished.connect(lambda: self.collectionList.setCurrentItem(item))

    def closeItem(self, item):
        animation = QTimeLine(ANIMATE_TIME, self)
        animation.setFrameRange(146, CLOSED_SIZE)
        animation.frameChanged.connect(lambda x: item.setSizeHint(QSize(32, x)))
        animation.start()
Exemple #28
0
class startAiDialog(QDialog):
    
    def __init__(self, parent = None):
        super().__init__()
        self.timer = QTimeLine(2000, self)
        #self.address = parent.address
        #self.port = parent.port
        self.address = "127.0.0.1"
        self.port = "5577"
        
        h1 = QHBoxLayout(None)
        self.yourLabel = QLabel(_("Your color:"), self)
        self.blackStone = QRadioButton(_("Black"), self)
        self.blackStone.setChecked(True)
        self.whiteStone = QRadioButton(_("White"), self)
        h1.addWidget(self.yourLabel)
        h1.addWidget(self.blackStone)
        h1.addWidget(self.whiteStone)
        
        h2 = QHBoxLayout(None)
        self.levelLabel = QLabel(_("Gnugo level:"), self)
        self.gnuLevel = QSpinBox(self)
        self.gnuLevel.setRange(1, 10)
        self.gnuLevel.setValue(8)
        h2.addWidget(self.levelLabel)
        h2.addWidget(self.gnuLevel)
        
        h3 = QHBoxLayout(None)
        self.komiLabel = QLabel(_("Set komi:"), self)
        self.komi = QSpinBox(self)
        self.komi.setEnabled(False)
        self.komi.setRange(0, 9)
        self.komi.setValue(0)
        h3.addWidget(self.komiLabel)
        h3.addWidget(self.komi)
        
        h4 = QHBoxLayout(None)
        self.startButton = QPushButton(_("Start Server"), self)
        buttonBox = QDialogButtonBox(self)
        self.okButton = QPushButton(_("OK"))
        self.okButton.setEnabled(False)
        self.cancelButton = QPushButton(_("Cancel"))
        buttonBox.addButton(self.okButton, QDialogButtonBox.AcceptRole)
        buttonBox.addButton(self.cancelButton, QDialogButtonBox.RejectRole)
        h4.addWidget(self.startButton)
        h4.addWidget(buttonBox)
        
        mainLayout = QVBoxLayout(None)
        mainLayout.addLayout(h1)
        mainLayout.addLayout(h2)
        mainLayout.addLayout(h3)
        mainLayout.addLayout(h4)
        self.setLayout(mainLayout)
        
        buttonBox.accepted.connect(self.accept)
        buttonBox.rejected.connect(self.reject)
        self.startButton.clicked.connect(self.startServer)
        self.timer.finished.connect(self.serverStarted)
    
    def serverStarted(self):
        self.goSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.goSocket.connect(("127.0.0.1", int(self.port)))
        self.startButton.setText(_("Server started"))
        self.okButton.setEnabled(True)
    
    def startServer(self):
        self.startButton.setEnabled(False)
        self.startButton.setText(_("Starting..."))
        if self.blackStone.isChecked():
            cl = "black"
        else:
            cl = "white"
        args = "gnugo --mode gtp --boardsize 19 --color {0} --level {1} --gtp-listen {2}:{3}".format(cl, str(self.gnuLevel.value()), self.address, self.port)
        print(args)
        self.process = subprocess.Popen(args.split())
        self.timer.start()
Exemple #29
0
class QTreeWidget(CoreQTreeWidget):

    def __init__(self, tableWidget, icons, showHidden):

        super(QTreeWidget, self).__init__(tableWidget, icons, showHidden)
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

        self.setAcceptDrops(True)
        self.dragModSoon = False  # dragMod just starts after 0.1 sec
        self.started = 0  # to take the time of dragModSoon

        self.dragSource = None
        self.dragMod = False
        self.copyDrag = False
        self.lastp = QtCore.QPoint(0, 0)  # Last position of the dragged item

        # USED FOR PREVIEW #

        # idx of a temporary moved/inserted item (not Voiditem)
        self.callback = None
        # Used for the drag and drop preview
        self.stillInItem = None
        self.voididxlist = []

        # SIZES(some handeld automatically) #

        self.circleSize = 1.5/2.  # Scaling factor for the nodes
        self.rw = 0
        self.rh = 0
        self.minr = 0

        # ANIMATION HELP #

        self.lineList_old = []
        self.lineList_new = []

        self.nodeCopy = []  # dictionarys filled with information

        self.old_opacity = 1
        self.timeline = None
        self.animationDuration = 200
        self.needUpdate = False

    def getItemList(self):
        """Returns a list of the items (Depth-first search [preordering])"""
        itemlist = []
        self.rekursivHelp(self.topLevelItem(0), itemlist)
        return itemlist

    def rekursivHelp(self, item, list):
        """Recursive help for the getItemList method"""
        list.append(item)
        for i in range(item.childCount()):
            self.rekursivHelp(item.child(i), list)

    def tableChanged(self):
        super(QTreeWidget, self).tableChanged()
        self.needUpdate = True

    def paintEvent(self, event):
        """Painting the view, if there is a root item"""

        if self.itemAt(0, 0) is None:
            return

        painter = QPainter(self.viewport())

        self.makeImage(painter)

        # drawing the dragged item
        if (self.dragMod and self.dragSource == self.source and
                self.currentItem() is not None):
            pos = self.lastp - QtCore.QPoint(self.minr/4, self.minr/4)
            self.paintItem(self.currentItem(), pos,
                           painter, self.xml)
            if self.timeline is None:
                # paintItem saves the drawn node. But the dragged Node is not
                # fixed thats why I remove it again.
                del self.nodeCopy[-1]

        painter.end()

    def makeImage(self, painter):
        """
        This method draws the image to a given painter.
        The algorithm works like this:

        - Find out how the items have to be placed, relativly
        - Take the relativ height and width of the tree
        - Now, set the position with absolute values
        - Save the lines
        - Check if some transitions have to be made:
            - if there is no transition required at the moment
            - and the lines changed or needUpdate flag is set

        For the tranistion take a look at the methods
        'animate' and 'animationEnd'.
        """

        painter.setRenderHint(QPainter.TextAntialiasing, True)
        painter.setRenderHint(QPainter.Antialiasing, True)

        itemList = self.getItemList()

        wDSF = 1  # width Dependend Scaling Factor
        hDSF = 1  # height Dependend Scaling Factor

        width = self.width()
        height = self.height()

        # The depth of the Tree
        maxlevel = 4
        # Max width in a Tree level
        maxlevelwidth = 1

        # Setting up maxlevel & item.level values
        for item in itemList:
            item.pos = QtCore.QPoint(0, 0)
            if item.parent() is not None:
                if item.getType() not in ['PULSE']:
                    item.level = item.parent().level+1
                    if item.level > maxlevel:
                        maxlevel = item.level

        # List of the width in a tree level
        levelwidth = [0] * len(itemList)

        for item in itemList:
            if item.parent() is not None:
                # This way, we dont write a node over the child of another node
                for j in range(item.level, len(levelwidth)):
                    if levelwidth[item.level] < levelwidth[j]:
                        levelwidth[item.level] = levelwidth[j]
                # Setting up the Item position
                item.pos = QtCore.QPoint(levelwidth[item.level], item.level)

                # A child cant be on the left side of a parent node
                if item.pos.x() < item.parent().pos.x():
                    item.pos = QtCore.QPoint(item.parent().pos.x(),
                                             item.pos.y())
                    levelwidth[item.level] = item.pos.x()

                # PULSE nodes don't grow to the side
                if item.getType() not in ['PULSE']:
                    levelwidth[item.level] += 1

                # To handle multiply PULSE nodes, we take their parent node
                if item.getType() in ['ATOMICSEQUENCE']:
                    if item.childCount() != 0:
                        # Multiple PULSE nodes takes 1 width in a tree level
                        levelwidth[item.level+1] += 1
                    # Multiple PULES nodes increasing the tree depth
                    if (item.level + item.childCount()) > maxlevel:
                        maxlevel = (item.level + item.childCount())

        # Getting the maxlevelwidth
        maxlevelwidth = max(levelwidth)

        if maxlevelwidth == 0:
            maxlevelwidth = 1

        self.rw = width/(maxlevelwidth) * wDSF
        self.rh = height/(maxlevel+1) * hDSF  # +1 is needed, to make it fit

        self.minr = self.rw if self.rw < self.rh else self.rh

        # ------------------------------------------------------------------- #
        # Positioning #
        # ------------------------------------------------------------------- #

        for item in itemList:
            if item.getType() not in ['PULSE']:
                qpoint = QtCore.QPoint(self.minr/6 + 3, 3)
                item.pos = QtCore.QPoint(item.pos.x()*self.rw,
                                         item.pos.y()*self.rh) + qpoint
                if item.getType() in ['ATOMICSEQUENCE']:
                    for i in range(item.childCount()):
                        child = item.child(i)
                        child.pos = QtCore.QPoint(
                                item.pos.x(), item.pos.y() +
                                (i+1)*self.minr*self.circleSize)

        # ------------------------------------------------------------------- #
        # Save Lines #
        # ------------------------------------------------------------------- #

        painter.linePainter(item)

        self.lineList_new = [[]]
        for item in itemList:
            # No lines between ATOMIC... and PULSE
            if item.getType() not in ['ATOMICSEQUENCE', 'COILARRAY']:
                for i in range(item.childCount()):
                    if not item.child(i).visible:
                        continue
                    self.lineList_new += [[
                            item.pos +
                            QtCore.QPoint(self.minr*self.circleSize/2,
                                          self.minr*self.circleSize/2),
                            item.child(i).pos +
                            QtCore.QPoint(self.minr*self.circleSize/2,
                                          self.minr*self.circleSize/2)]]

        # ------------------------------------------------------------------- #
        # possible Animation start #
        # ------------------------------------------------------------------- #

        if (self.timeline is None and
                (self.lineList_new[:] != self.lineList_old[:] or
                 self.needUpdate)):
            self.needUpdate = False
            self.timeline = QTimeLine()
            self.timeline.valueChanged.connect(self.animate)
            self.timeline.finished.connect(self.animationEnd)
            self.timeline.setDuration(self.animationDuration)
            self.timeline.start()

        # ------------------------------------------------------------------- #
        # Drawing Lines #
        # ------------------------------------------------------------------- #

        painter.setOpacity(self.old_opacity)
        for line in self.lineList_old:
            if line != []:
                painter.drawLine(line[0], line[1])

        if self.old_opacity != 1:       # with Animation
            painter.setOpacity(1-self.old_opacity)
            for line in self.lineList_new:
                if line != []:
                    painter.drawLine(line[0], line[1])

        # ------------------------------------------------------------------- #
        # Drawing Nodes #
        # ------------------------------------------------------------------- #

        painter.setOpacity(1)
        if self.timeline is None:       # without Animation
            if len(self.nodeCopy) == 0:
                tmp = copy.deepcopy(self.xml)
                for item in itemList:     # drawing and saving new nodes
                    if item is not None and item.visible:
                        self.paintItem(item, item.pos, painter, tmp)
            else:
                for cp in self.nodeCopy:  # using old nodes for drawing
                    self.paintItem2(cp, painter)

        else:                           # with Animation
            painter.setOpacity(self.old_opacity)
            for cp in self.nodeCopy:
                self.paintItem2(cp, painter)
            painter.setOpacity(1-self.old_opacity)
            for item in itemList:
                if item is not None and item.visible:
                    self.paintItem(item, item.pos, painter, self.xml)

    def animationEnd(self):
        """
        AnimationEnd cleans up the animation. Called by QTimeLine.
        """
        self.lineList_old = self.lineList_new
        self.lineList_new = None
        self.old_opacity = 1.0
        self.nodeCopy = []      # removing old nodes
        self.timeline = None
        self.updateImage()

    def animate(self, value):
        """
        Animate makes a little change for the tranistion. Called by QTimeLine.
        """
        self.old_opacity = 1.0 - value
        self.updateImage()

    def calcVoidItems(self):
        """
        This method creates the Voiditems for the preview.
        """
        if not self.dragMod:
            return

        # ------------------------------------------------------------------- #
        # Calculating VoidItems indexes #
        # ------------------------------------------------------------------- #

        self.voididxlist = []
        for item in self.getItemList():
            if item.getType() not in ['PULSE']:
                idx = item.idx() + [item.childCount()]
                if self.checkVoidItem(idx):
                    self.voididxlist += [idx]

        dragIndex = None
        if self.currentItem() is not None:  # saving the current item idx
            dragIndex = self.currentItem().idx()

        # ------------------------------------------------------------------- #
        # Creation of Voiditems #
        # ------------------------------------------------------------------- #

        for voididx in self.voididxlist:
            if self.dragSource == self.source:  # not using button drag
                if self.callback is not None:       # item not moved/copyd
                    self.setCurrentItem(self.getItem(self.callback))
#
                    self.itemCopy.emit()
                    self.itemMoved.emit(self.callback, voididx)
                else:                               # item moved/copyd
                    if voididx is self.voididxlist[0]:
                        dragIndex[-1] += 1
                        self.itemCopy.emit()
                        self.itemMoved.emit(dragIndex, voididx)
                        dragIndex[-1] -= 1
                        self.setCurrentItem(self.getItem(dragIndex))
                    else:
                        self.setCurrentItem(self.getItem(self.voididxlist[0]))
                        self.itemCopy.emit()
                        self.itemMoved.emit(self.voididxlist[0], voididx)
            else:                                # using button drag
                if self.callback is None:       # item not inserted
                    if voididx is self.voididxlist[0]:
                        self.insertItem(voididx)
                    else:
                        self.setCurrentItem(self.getItem(self.voididxlist[0]))
                        self.itemCopy.emit()
                        self.itemMoved.emit(self.voididxlist[0], voididx)
                else:                           # item already inserted
                    self.setCurrentItem(self.getItem(self.callback))
                    self.itemCopy.emit()
                    self.itemMoved.emit(self.callback, voididx)

        if dragIndex is not None:       # setting the current item back
            self.setCurrentItem(self.getItem(dragIndex))

        self.markVoidItems()    # finishing void items

    def checkVoidItem(self, idx):
        """
        Checks, if an idx can be taken for a new VoidItem. First some special
        cases are caught and then the standard checkDrop function is used.
        """

        if self.callback is not None:
            if len(idx) == len(self.callback):
                numb = len(self.callback)-1
                if (idx[0:numb] == self.callback[0:numb] and
                        idx[numb] >= self.callback[numb]):
                    return False
            else:
                if len(idx) >= len(self.callback):
                    numb = len(self.callback)
                    if idx[0:numb] == self.callback[0:numb]:
                        return False
        return self.checkDrop(idx)

    def setBranchVoid(self, root, isVoid):
        """
        This Method sets the isVoid flag of a hole branch to the given
        boolean value in 'isVoid'.
        """

        change = [root]
        for node in change:
            node.isVoid = isVoid
            for i in range(node.childCount()):
                change += [node.child(i)]

    def checkDrop(self, dropidx):
        """
        This Methods checks, if a (copy)move/insertion of an item is
        legal.
        """

        dropIndex = dropidx[:]
        tmp = copy.deepcopy(self.xml)
        if self.dragSource == self.source:
            dragIndex = self.currentItem().idx()
            if self.copyDrag:
                tmp.copy(dragIndex)
                dragIndex[-1] += 1
            else:
                if len(dropIndex) >= len(dragIndex):
                    numb = len(dragIndex)
                    if dragIndex[0:numb] <= dropIndex[0:numb]:
                        if dropIndex[0:numb] == dragIndex[0:numb]:
                            return False
                        dropIndex[numb-1] -= 1
            try:
                tmp._move(dragIndex, dropIndex)
                status, msg = tmp.checkCommand(dropIndex)
                if msg is not None:
                    return False
            # exception caused, when tmp.checkCommand wont return 2 values
            except:
                return False
        else:
            tag = self.dragSource.text()
            idx = dropIndex[0:-1]

            if len(idx) == 0:
                return False

            tmp = copy.deepcopy(self.xml)
            msg = tmp._insert(idx, tag)
            if msg is not None:
                return False
        return True

    def deleteVoidItems(self):
        """
        Removs all Items, which are VoidItems.
        """

        savedidx = None
        if self.currentItem() is not None:
            savedidx = self.currentItem().idx()
        for idx in self.voididxlist:
            self.setCurrentItem(self.getItem(idx))
            self.treeItemDelete()
        if savedidx is not None:
            self.setCurrentItem(self.getItem(savedidx))
        self.voididxlist = []

    def paintItem(self, item, pos, painter, xml):
        """
        This method is a preparation for the item painting in 'paintItem2'.
        The infomation, which is required to draw an item, is saved if
        needed (for the animation).
        """

        informlist = {
                "pos": pos, "text": item.getName(),
                "backgroundColor": item.background(0).color(),
                "isVoid": item.isVoid,
                "type": item.getType(),
                "iscurrent": item is self.currentItem(),
                "idx": item.idx(),
                "xml": xml,
                "textcolor": item.foreground(0).color(),
                "font": item.font(0),
                "minr": self.minr}

        if self.timeline is None:
            self.nodeCopy.append(informlist)

        self.paintItem2(informlist, painter)

    def paintItem2(self, itemInfos, painter):
        """
        In this method, the items are painted. The attribute 'iteminfos'
        should contain a dictionary with the needed informtion.
        """

        minSizeForPulsPic = 25

        sIC = QtGui.QColor(0, 150, 200)  # selected item color

        sICBW = 2  # selected item color border width

        minr = itemInfos["minr"]

        # ------------------------------------------------------------------- #
        # Draw Form #
        # ------------------------------------------------------------------- #

        # drawshape = needed shape
        # rect = Postion + size of the shape

        if itemInfos["type"] in ['PULSE', 'COIL']:
            rect = QtCore.QRect(itemInfos["pos"].x()-minr/6,
                                itemInfos["pos"].y(),
                                minr*self.circleSize + self.minr/3,
                                minr*self.circleSize)
            drawshape = painter.drawRect
        else:
            rect = QtCore.QRect(itemInfos["pos"].x(), itemInfos["pos"].y(),
                                minr*self.circleSize,
                                minr*self.circleSize)
            drawshape = painter.drawEllipse

        # shape color
        colorB = itemInfos["backgroundColor"]
        if self.callback is not None:
            if ((self.dragSource == self.source and
                 itemInfos["idx"] == self.callback and
                 not itemInfos["iscurrent"]) or
                (self.dragSource != self.source and
                 itemInfos["iscurrent"])):
                colorB = QtGui.QColor(220, 220, 220)

        # alphaf(1) to overdraw the lines, which connects the nodes
        # TODO:
        colorB.setAlphaF(1)
        if itemInfos["iscurrent"]:  # draw a blue border for the currentItem
            painter.setBrush(sIC)
            drawshape(QtCore.QRect(rect.x() - sICBW,
                                   rect.y() - sICBW,
                                   rect.width() + 2*sICBW,
                                   rect.height() + 2*sICBW))

        if itemInfos["isVoid"]:     # VoidItems are drawn with orange
            colorB = QtGui.QColor('orange')
            painter.formPainter(rect, None, colorB, itemtype=itemInfos["type"])
        else:
            painter.formPainter(rect, None, colorB, itemtype=itemInfos["type"])

        drawshape(rect)  # Drawing the shape

        # ------------------------------------------------------------------- #
        # Draw Icon #
        # ------------------------------------------------------------------- #

        painter.iconPainter()
        icon = None

        if minr >= minSizeForPulsPic:
            xitem = itemInfos["xml"].read(itemInfos["idx"])
            if xitem.get('type') in ['PULSE', 'COIL']:
                icon = self.icons[xitem.tag]

                painter.drawPixmap(
                        itemInfos["pos"] + QtCore.QPoint(0, minr * 1/7),
                        icon, QtCore.QRect(0, 0, icon.width(), icon.height()))

        # ------------------------------------------------------------------- #
        # Draw Text #
        # ------------------------------------------------------------------- #

        painter.textPainter(textColor=itemInfos["textcolor"],
                            font=itemInfos["font"])

        if icon is not None:
            painter.drawText(itemInfos["pos"] + QtCore.QPoint(
                    icon.width(), icon.height() + minr*1/7), itemInfos["text"])
        else:
            painter.drawText(QtCore.QRectF(rect), QtCore.Qt.AlignCenter,
                             itemInfos["text"])

    def pointInItem(self, p, item):
        """
        Checks if a point is in the shape of an Item. This is used to
        detect, if a user clicks or hovers over an item (possible drop
        action).
        """

        m = self.minr
        if item.getType() in ['PULSE']:     # Checks if p is in a Rectangle
            return (p.x() > item.pos.x()-m/6 and
                    p.y() > item.pos.y() and
                    p.x() < item.pos.x()-m/6-2+m*self.circleSize+m/3 and
                    p.y() < item.pos.y()+m*self.circleSize)
        else:                               # Checks if p is in a Circle
            return (math.sqrt((p.x()-item.pos.x()-m*self.circleSize/2)**2 +
                              (p.y()-item.pos.y()-m*self.circleSize/2)**2) <
                    m*self.circleSize/2)

    def mousePressEvent(self, e):
        self.lastp = e.pos()
        for item in self.getItemList():
            if self.pointInItem(self.lastp, item):
                self.setCurrentItem(item)
                self.treeItemClicked()
                self.dragModSoon = True
                self.started = time.time()
                self.nodeCopy = []
                self.updateImage()
                break

    def mouseReleaseEvent(self, e):
        self.lastp = e.pos()

        if self.dragMod:
            dropevent = QtGui.QDropEvent(e.pos(), QtCore.Qt.DropAction(),
                                         QtCore.QMimeData(),
                                         QtCore.Qt.MouseButton(),
                                         QtCore.Qt.KeyboardModifiers(),
                                         QtCore.QEvent.Drop)
            dropevent.source = self.source
            if self.callback is not None and self.callback in self.voididxlist:
                self.voididxlist.remove(self.callback)
            self.deleteVoidItems()

            if self.callback is not None:
                if self.dragSource == self.source and not self.copyDrag:
                    self.treeItemDelete()
            self.callback = None
            self.dragMod = False
            self.needUpdate = True
            self.updateImage()
        self.dragModSoon = False

    def mouseMoveEvent(self, event):
        e = QtGui.QMouseEvent(event)
        self.lastp = e.pos()

        if self.dragModSoon and not self.dragMod:
            if time.time() - self.started > 0.1:
                self.dragMod = True
                self.dragSource = self.source
                self.calcVoidItems()

        if self.dragMod:
            self.previewManager(event)
            self.updateImage()

    def stillInItemFunc(self, p):
        """
        This Method detects, if the cursor is still hovering over the
        shape, which causes a change. By making a move/copy/insert preview,
        it is possible, that the new shapes don't matches the cursor
        position, so that a preview would be volatile without this method.
        """

        m = self.stillInItem[2]
        itempos = self.stillInItem[1]

        if self.stillInItem[0] in ['PULSE']:    # p in Rectangle
            return (p.x() > itempos.x()-m/6 and
                    p.y() > itempos.y() and
                    p.x() < itempos.x()-m/6-2+m*self.circleSize+m/3 and
                    p.y() < itempos.y()+m*self.circleSize)
        else:                                   # p in Circle
            return (math.sqrt((p.x()-itempos.x()-m*self.circleSize/2)**2 +
                              (p.y()-itempos.y()-m*self.circleSize/2)**2) <
                    m*self.circleSize/2)

    def setBranchVisible(self, item, visible):
        """
        Changes the visibility of a complete branch. The given item should be
        the root of the branch. This method is used in the move preview
        (without copy).
        """

        change = [item]
        for node in change:
            node.visible = visible
            for i in range(node.childCount()):
                change += [node.child(i)]

    def previewManager(self, event):
        """
        This method decides, if a (copy)move/insert preview has to be done.
        It can also delete a preview, if the dragged item is not over a shape
        anymore.
        """

        # Limiting the the calls of this method
        if time.time() - self.started > 0.1:
            self.started = time.time()

            dropIndex = self.calcDropIndex(event.pos())
            if dropIndex is not None:               # Cursor over shape
                if self.callback is None:           # There is no preview
                    self.makePreview(event, dropIndex)  # make move/copy/insert
            elif (self.callback is not None and
                  not self.stillInItemFunc(event.pos())):
                self.deletePreview()            # undo move/copy/insert
                self.stillInItem = None

    def deletePreview(self):
        """
        This method deletes a preview, that is caused by dragging an item over
        another item.
        """

        self.deleteVoidItems()
        if self.dragSource == self.source:      # not caused by a button drag
            item = self.getItem(self.callback)
            self.setCurrentItem(item)
            self.treeItemDelete()
            self.callback = None
            self.setCurrentItem(self.getItem(self.copyhelp))
            if not self.copyDrag:
                self.currentItem().visible = True
        else:                                   # caused by a button drag
            self.setCurrentItem(self.getItem(self.callback))
            self.treeItemDelete()
            self.callback = None
        self.calcVoidItems()
        self.needUpdate = True

    def makePreview(self, event, dropIndex):
        """
        Checks and creates a new (copy)move/insert preview.
        """

        if not self.checkDrop(dropIndex):   # We can't drop the Item here
            return

        if self.dragSource == self.source:  # not caused by a button
            self.makePreviewCopyDrag(event, dropIndex)  # (copy)move
        else:                               # caused by a button
            self.makePreviewInsert(event, dropIndex)    # insert
        self.needUpdate = True  # repainting the image of the widget

    def makePreviewCopyDrag(self, event, dropIndex):
        """
        This Method creates a preview of a (copy)move action.
        """

        self.deleteVoidItems()

        dragIndex = self.currentItem().idx()
        self.callback = dropIndex
        event.source = self.source
        self.copydropEvent(event, dropIndex)
        self.copyhelp = dragIndex[:]

        if len(dragIndex) >= len(dropIndex):
            numb = len(dropIndex)-1
            if (dropIndex[0:numb] == dragIndex[0:numb] and
                    dropIndex[numb] <= dragIndex[numb]):
                dragIndex[numb] += 1

        self.setCurrentItem(self.getItem(dragIndex))
        self.calcVoidItems()
        if not self.copyDrag:
            self.setBranchVisible(self.currentItem(), False)
        self.paintactivated = True

    def makePreviewInsert(self, event, dropIndex):
        """
        This method creates a preview of a button drag action.
        """

        if dropIndex == [0]:    # you can't drop anything on the root item
            return

        self.deleteVoidItems()

        self.insertItem(dropIndex)
        new = self.getItem(dropIndex)
        self.setCurrentItem(new)
        self.callback = dropIndex

        self.calcVoidItems()

    def insertItem(self, dropIndex):
        """
        Insert an item as a consequence of a button action.
        """

        idx = dropIndex[0:-1]
        prep = self.getItem(idx)
        self.setCurrentItem(prep)
        idx += [prep.childCount()]
        self.dragSource.sendInsertSignal()
        self.itemMoved.emit(idx, dropIndex)
#        self.emit(QtCore.SIGNAL('itemMoved'), idx, dropIndex)

    def markVoidItems(self, dropIndex=None):
        """
        This method marks all VoidItems, which are children of a VoidItem.
        """

        for voididx in self.voididxlist:
            if dropIndex is not None and len(voididx) >= len(dropIndex):
                numb = len(dropIndex)
                if (dropIndex[0:numb] <= voididx[0:numb]):
                    voididx[numb-1] += 1
                    self.setBranchVoid(self.getItem(voididx), True)
                    voididx[numb-1] -= 1
            else:
                self.setBranchVoid(self.getItem(voididx), True)

    def getItem(self, idx):
        """
        Returns the item at a given item index.
        """

        for item in self.getItemList():
            if item.idx() == idx:
                return item

    def source(self):
        # just for creating the dropevent
        return self

    def updateImage(self):
        # forcing this widget to create a paintEvent
        self.viewport().repaint()

    def calcDropIndex(self, pos):
        """
        This methods finds out, if a dragged item is hovering over another
        item.
        """

        idx = None
        for item in self.getItemList():
            if self.pointInItem(pos, item):
                searched = item
                idx = searched.idx()
                if searched.isVoid:
                    for voididx in self.voididxlist:
                        if len(idx) >= len(voididx):
                            numb = len(voididx)
                            if idx[0:numb] == voididx[0:numb]:
                                idx = voididx
                self.stillInItem = [searched.getType(),
                                    searched.pos, self.minr]
                break

        return idx

    def copydropEvent(self, event, dropIndex=None):
        """
        Make a copy of an Item and then move it to the given dropIndex.
        """

        if event.source() == self:

            dragIndex = self.currentItem().idx()

            if dropIndex is None:
                dropIndex = self.calcDropIndex(event.pos())

            if dropIndex is None:
                return

            tmp = copy.deepcopy(self.xml)
            tmp.copy(dragIndex)
            dragIndex[-1] += 1
            tmp._move(dragIndex, dropIndex)
            status, msg = tmp.checkCommand(dropIndex)

            if status:
                self.itemCopy.emit()
                self.itemMoved.emit(dragIndex, dropIndex)

    def dragEnterEvent(self, e):  # button drag is over the widget
        e.accept()
        self.dragSource = e.source()
        self.dragMod = True
        self.calcVoidItems()
        self.paintactivated = True
        self.updateImage()

    def dragLeaveEvent(self, e):  # button drag leaves the widget
        self.deleteVoidItems()
        self.dragMod = False
        self.dragSource = None
        self.paintactivated = True
        self.updateImage()

    def dragMoveEvent(self, e):
        """
        This method gets called, when the button drag function is used.
        """

        self.previewManager(e)

    def dropEvent(self, event):

        if event.source() == self:      # not a button

            item = self.currentItem()
            dragIndex = item.idx()
            dropIndex = self.calcDropIndex(event.pos())

            if dropIndex is None:
                return

            self.itemMoved.emit(dragIndex, dropIndex)

        else:                           # a button
            if self.callback is None:
                for item in self.getItemList():
                    if self.pointInItem(event.pos(), item):
                        self.setCurrentItem(item)
                        self.treeItemInsert()
                        break
            self.callback = None
            self.dragMod = False
            self.deleteVoidItems()
            self.paintactivated = True
        self.dragMod = False

    def keyPressEvent(self, event):
        """
        Detects if the CopyDrag gets enabled.
        """

        if not self.dragMod:
            super(QTreeWidget, self).keyPressEvent(event)

        if event.key() == QtCore.Qt.Key_Shift:
            if self.dragMod:
                if self.callback is not None:
                    dropIndex = self.callback[:]
                    self.deletePreview()
                    self.copyDrag = True
                    self.makePreview(event, dropIndex)
                else:
                    self.deleteVoidItems()
                    self.copyDrag = True
                    self.calcVoidItems()
                self.paintactivated = True
            else:
                self.nodeCopy = []
                self.copyDrag = True
        self.updateImage()

    def keyReleaseEvent(self, event):
        """
        Detects if the CopyDrag gets disabled.
        """

        if event.key() == QtCore.Qt.Key_Shift:
            if self.dragMod:
                if self.callback is not None:
                    dropIndex = self.callback[:]
                    self.deletePreview()
                    self.copyDrag = False
                    self.makePreview(event, dropIndex)
                else:
                    self.deleteVoidItems()
                    self.copyDrag = False
                    self.calcVoidItems()
                self.needUpdate = True
            else:
                self.copyDrag = False
                self.nodeCopy = []
        self.updateImage()
Exemple #30
0
        r = 0

        for i in range(self.m_digits):
            r = c % 10
            c = c // 10
            rect = QRectF(x + self.X_OFFSET, self.Y_OFFSET, w, h)
            self.m_svg.render(p, "d{}".format(r), rect)
            x -= w

        p.restore()

    def inicio(self):
        import analogwidgets_rc
        self.m_value = 0
        self.m_digits = 4
        self.m_svg = None
        self.setDigitsFile(":/default/resources/train_digits.svg")


if __name__ == '__main__':
    import sys
    from PyQt5.QtCore import QTimeLine

    app = QApplication(sys.argv)
    w = PyCounter()
    timeline = QTimeLine(10000)
    timeline.setFrameRange(0, 9999)
    timeline.frameChanged.connect(w.setValue)
    timeline.start()
    w.show()
    sys.exit(app.exec_())
Exemple #31
0
class CustomProxy(QGraphicsProxyWidget):
    def __init__(self, parent=None, wFlags=0):
        super(CustomProxy, self).__init__(parent, wFlags)

        self.popupShown = False
        self.currentPopup = None

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    def zoomOut(self):
        if self.timeLine.direction() != QTimeLine.Backward:
            self.timeLine.setDirection(QTimeLine.Backward)
        if self.timeLine.state() == QTimeLine.NotRunning:
            self.timeLine.start()
Exemple #32
0
class QPageWidget(QScrollArea):
    """ The QPageWidget provides a stack widget with animated page transitions. """

    #Emits
    currentChanged = pyqtSignal()

    def __init__(self, parent=None, direction="ltr", rtf=False):
        """ Creates a new QPageWidget on given parent object. 

        parent: QWidget parent
        direction: "ltr" -> Left To Right
                   "ttb" -> Top To Bottom
        rtf: Return to first, if its True it flips to the first page 
             when next page requested at the last page
        """

        # First initialize, QPageWidget is based on QScrollArea
        QScrollArea.__init__(self, parent)

        # Properties for QScrollArea
        self.setFrameShape(QFrame.NoFrame)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setWidgetResizable(True)

        # Main widget, which stores all Pages in it
        self.widget = QWidget(self)

        # Layout based on QBoxLayout which supports Vertical or Horizontal layout
        if direction == "ltr":
            self.layout = QBoxLayout(QBoxLayout.LeftToRight, self.widget)
            self.__scrollBar = self.horizontalScrollBar()
            self.__base_value = self.width
        else:
            self.layout = QBoxLayout(QBoxLayout.TopToBottom, self.widget)
            self.__scrollBar = self.verticalScrollBar()
            self.__base_value = self.height
        self.layout.setSpacing(0)

        #qboxlayout setmargin özelliği yok
        #self.layout.setMargin(0)

        # Return to first
        self.__return_to_first = rtf

        # TMP_PAGE, its using as last page in stack
        # A workaround for a QScrollArea bug
        self.__tmp_page = Page(QWidget(self.widget))
        self.__pages = [self.__tmp_page]
        self.__current = 0
        self.__last = 0

        # Set main widget
        self.setWidget(self.widget)

        # Animation TimeLine
        self.__timeline = QTimeLine()
        self.__timeline.setUpdateInterval(2)

        # Updates scrollbar position when frame changed
        self.__timeline.frameChanged.connect(
            lambda x: self.__scrollBar.setValue(x))

        # End of the animation
        self.__timeline.finished.connect(self._animateFinished)

        # Initialize animation
        self.setAnimation()
        self.setDuration()

    def _animateFinished(self):
        """ Its called by TimeLine when animation finished.

        It first runs the outMethod of last Page and then the inMethod of current Page
        Finally tt gives the focus to the current page and fixes the scrollBar
        """

        # Disable other widgets
        for page in self.__pages:
            if not page == self.__pages[self.__current]:
                page.widget.setEnabled(False)

        # Run last page's outMethod if exists
        if self.__pages[self.__last].outMethod:
            self.__pages[self.__last].outMethod()

        # Run new page's inMethod if exists
        if self.__pages[self.__current].inMethod:
            self.__pages[self.__current].inMethod()

        # Give focus to the current Page
        self.__pages[self.__current].widget.setFocus()

        # Update scrollbar position for current page
        self.__scrollBar.setValue(self.__current * self.__base_value())

        # Emit currentChanged SIGNAL
        self.currentChanged.emit()

    def event(self, event):
        """ Overrides the main event handler to catch resize events """
        # Catch Resize event
        if event.type() == QEvent.Resize:
            # Update each page size limits to mainwidget's new size
            for page in self.__pages:
                page.widget.setMinimumSize(self.size())
                page.widget.setMaximumSize(self.size())

            # Update viewport size limits to mainwidget's new size
            # It's a workaround for QScrollArea updateGeometry bug
            self.viewport().setMinimumSize(self.size())
            self.viewport().setMaximumSize(self.size())

            # Update scrollbar position for current page
            self.__scrollBar.setValue(self.__current * self.__base_value())

        # Return the Event
        return QScrollArea.event(self, event)

    def keyPressEvent(self, event):
        """ Overrides the keyPressEvent to ignore them """
        pass

    def wheelEvent(self, event):
        """ Overrides the wheelEvent to ignore them """
        pass

    def createPage(self, widget, inMethod=None, outMethod=None):
        """ Creates and adds new Page for given widget with given in/out methods.

        widget: A QWidget which is the mainwidget for this Page
        inMethod: (optional) QPageWidget triggers this method when the Page appear
        outMethod: (optional) QPageWidget triggers this method when the Page disappear
        """
        self.addPage(Page(widget, inMethod, outMethod))

    def addPage(self, page):
        """ Adds the given Page to the stack.

        page: A Page object
        """
        # First remove the last page; its __tmp_page
        self.__pages.pop()

        # Add new page
        self.__pages.append(page)
        self.layout.addWidget(page.widget)

        # Add __tmp_page to end
        self.__pages.append(self.__tmp_page)
        self.layout.addWidget(self.__tmp_page.widget)

        # Create connections for page navigation signals from new page
        try:
            page.widget.pageNext.connect(self.next)
            page.widget.pagePrevious.connect(self.prev)
            page.widget.setCurrent[int].connect(self.setCurrent)
        except:
            pass

    def __setCurrent(self, pageNumber):
        """ Internal method to set current page index. """
        self.__last = self.__current
        self.__current = min(max(0, pageNumber), len(self.__pages) - 2)
        if pageNumber == len(self.__pages) - 1 and self.__return_to_first:
            self.__current = 0

    def setCurrent(self, pageNumber=0):
        """ Set and flip the page with given pageNumber.

        pageNumber: index number of Page (default is 0)
        """
        self.__setCurrent(pageNumber)
        self.flipPage()

    def getCurrent(self):
        """ Returns current page index. """
        return self.__current

    def getCurrentWidget(self):
        """ Returns current page widget. """
        return self.getWidget(self.getCurrent())

    def getWidget(self, pageNumber):
        """ Returns widget for given page index 

        pageNumber: index number of Page
        """
        try:
            return self.__pages[pageNumber].widget
        except:
            return None

    def count(self):
        """ Returns number of pages. """
        return len(self.__pages) - 1

    def setAnimation(self, animation=35):
        """ Set the transition animation with the given animation.

        animation: the number represents predefined QEasingCurves
                   List of predefined QEasingCurves can be found from:
                   http://doc.qt.nokia.com/4/qeasingcurve.html#Type-enum

                   Default is QEasingCurve::InOutBack (35)
        """
        self.__animation = animation
        self.__timeline.setEasingCurve(QEasingCurve(self.__animation))

    def setDuration(self, duration=400):
        """ Set the transition duration.

        duration: duration time in ms
        """
        self.__duration = duration
        self.__timeline.setDuration(self.__duration)

    def flipPage(self, direction=0):
        """ Flip the page with given direction.

        direction: can be -1, 0 or +1
                   -1: previous page (if exists)
                    0: just flip to current page
                   +1: next page (if exists)
        """
        # Enable all widgets
        for page in self.__pages:
            page.widget.setEnabled(True)

        # Check given direction
        direction = direction if direction == 0 else max(min(1, direction), -1)

        # If direction is equal to zero no need to re-set current
        if not direction == 0:
            self.__setCurrent(self.__current + direction)

        # If last page is different from new page, flip it !
        if not self.__last == self.__current:
            self.__timeline.setFrameRange(self.__scrollBar.value(),
                                          self.__current * self.__base_value())
            self.__timeline.start()

    def next(self):
        """ Helper method to flip next page. """
        self.flipPage(1)

    def prev(self):
        """ Helper method to flip previous page. """
        self.flipPage(-1)
Exemple #33
0
class Window(QWidget):
    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)
        self.resize(600, 200)
        layout = QVBoxLayout(self)

        # 配置全局属性(也可以通过start方法里的参数配置单独的属性)
        CLoadingBar.config(height=2,
                           direction=CLoadingBar.TOP,
                           color='#2d8cf0',
                           failedColor='#ed4014')

        # 子控件顶部进度
        self.widget1 = QWidget(self)
        layout.addWidget(self.widget1)
        CLoadingBar.start(self.widget1, color='#19be6b', failedColor='#ff9900')

        widget = QWidget(self)
        layoutc = QHBoxLayout(widget)
        layoutc.addWidget(QPushButton('开始', self, clicked=self.doStart))
        layoutc.addWidget(QPushButton('结束', self, clicked=self.doFinish))
        layoutc.addWidget(QPushButton('错误', self, clicked=self.doError))
        layout.addWidget(widget)

        # 子控件底部进度
        self.widget2 = QWidget(self)
        layout.addWidget(self.widget2)
        CLoadingBar.start(self.widget2, direction=CLoadingBar.BOTTOM, height=6)

        # 模拟进度
        self.updateTimer = QTimeLine(10000,
                                     self,
                                     frameChanged=self.doUpdateProgress)
        self.updateTimer.setFrameRange(0, 100)
        # 设置数字变化曲线模拟进度的不规则变化
        self.updateTimer.setCurveShape(QTimeLine.EaseInOutCurve)

    def doStart(self):
        """模拟开始
        """
        self.updateTimer.stop()
        self.updateTimer.start()

    def doFinish(self):
        """模拟结束
        """
        self.updateTimer.stop()
        CLoadingBar.finish(self.widget1)
        CLoadingBar.finish(self.widget2)

    def doError(self):
        """模拟出错
        """
        self.updateTimer.stop()
        CLoadingBar.error(self.widget1)
        CLoadingBar.error(self.widget2)

    def doUpdateProgress(self, value):
        """模拟进度值变化
        :param value:
        """
        CLoadingBar.update(self.widget1, value)
        CLoadingBar.update(self.widget2, value)
        if value == 100:
            self.updateTimer.stop()
            self.doFinish()
Exemple #34
0
class QPageWidget(QScrollArea):
    """ The QPageWidget provides a stack widget with animated page transitions. """

    #Emits
    currentChanged = pyqtSignal()
    
    def __init__(self, parent = None, direction = "ltr", rtf = False):
        """ Creates a new QPageWidget on given parent object. 

        parent: QWidget parent
        direction: "ltr" -> Left To Right
                   "ttb" -> Top To Bottom
        rtf: Return to first, if its True it flips to the first page 
             when next page requested at the last page
        """
                
        # First initialize, QPageWidget is based on QScrollArea
        QScrollArea.__init__(self, parent)

        # Properties for QScrollArea
        self.setFrameShape(QFrame.NoFrame)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setWidgetResizable(True)

        # Main widget, which stores all Pages in it
        self.widget = QWidget(self)

        # Layout based on QBoxLayout which supports Vertical or Horizontal layout
        if direction == "ltr":
            self.layout = QBoxLayout(QBoxLayout.LeftToRight, self.widget)
            self.__scrollBar = self.horizontalScrollBar()
            self.__base_value = self.width
        else:
            self.layout = QBoxLayout(QBoxLayout.TopToBottom, self.widget)
            self.__scrollBar = self.verticalScrollBar()
            self.__base_value = self.height
        self.layout.setSpacing(0)
        
        #qboxlayout setmargin özelliği yok
        #self.layout.setMargin(0)

        # Return to first
        self.__return_to_first = rtf

        # TMP_PAGE, its using as last page in stack
        # A workaround for a QScrollArea bug
        self.__tmp_page = Page(QWidget(self.widget))
        self.__pages = [self.__tmp_page]
        self.__current = 0
        self.__last = 0

        # Set main widget
        self.setWidget(self.widget)

        # Animation TimeLine
        self.__timeline = QTimeLine()
        self.__timeline.setUpdateInterval(2)

        # Updates scrollbar position when frame changed
        self.__timeline.frameChanged.connect(lambda x: self.__scrollBar.setValue(x))

        # End of the animation
        self.__timeline.finished.connect(self._animateFinished)

        # Initialize animation
        self.setAnimation()
        self.setDuration()

    def _animateFinished(self):
        """ Its called by TimeLine when animation finished.

        It first runs the outMethod of last Page and then the inMethod of current Page
        Finally tt gives the focus to the current page and fixes the scrollBar
        """

        # Disable other widgets
        for page in self.__pages:
            if not page == self.__pages[self.__current]:
                page.widget.setEnabled(False)

        # Run last page's outMethod if exists
        if self.__pages[self.__last].outMethod:
            self.__pages[self.__last].outMethod()

        # Run new page's inMethod if exists
        if self.__pages[self.__current].inMethod:
            self.__pages[self.__current].inMethod()

        # Give focus to the current Page
        self.__pages[self.__current].widget.setFocus()

        # Update scrollbar position for current page
        self.__scrollBar.setValue(self.__current * self.__base_value())

        # Emit currentChanged SIGNAL
        self.currentChanged.emit()

    def event(self, event):
        """ Overrides the main event handler to catch resize events """
        # Catch Resize event
        if event.type() == QEvent.Resize:
            # Update each page size limits to mainwidget's new size
            for page in self.__pages:
                page.widget.setMinimumSize(self.size())
                page.widget.setMaximumSize(self.size())

            # Update viewport size limits to mainwidget's new size
            # It's a workaround for QScrollArea updateGeometry bug
            self.viewport().setMinimumSize(self.size())
            self.viewport().setMaximumSize(self.size())

            # Update scrollbar position for current page
            self.__scrollBar.setValue(self.__current * self.__base_value())

        # Return the Event
        return QScrollArea.event(self, event)

    def keyPressEvent(self, event):
        """ Overrides the keyPressEvent to ignore them """
        pass

    def wheelEvent(self, event):
        """ Overrides the wheelEvent to ignore them """
        pass

    def createPage(self, widget, inMethod = None, outMethod = None):
        """ Creates and adds new Page for given widget with given in/out methods.

        widget: A QWidget which is the mainwidget for this Page
        inMethod: (optional) QPageWidget triggers this method when the Page appear
        outMethod: (optional) QPageWidget triggers this method when the Page disappear
        """
        self.addPage(Page(widget, inMethod, outMethod))

    def addPage(self, page):
        """ Adds the given Page to the stack.

        page: A Page object
        """
        # First remove the last page; its __tmp_page
        self.__pages.pop()

        # Add new page
        self.__pages.append(page)
        self.layout.addWidget(page.widget)

        # Add __tmp_page to end
        self.__pages.append(self.__tmp_page)
        self.layout.addWidget(self.__tmp_page.widget)

        # Create connections for page navigation signals from new page
        try:
            page.widget.pageNext.connect(self.next)
            page.widget.pagePrevious.connect(self.prev)
            page.widget.setCurrent[int].connect(self.setCurrent)
        except:
            pass

    def __setCurrent(self, pageNumber):
        """ Internal method to set current page index. """
        self.__last = self.__current
        self.__current = min(max(0, pageNumber), len(self.__pages) - 2)
        if pageNumber == len(self.__pages) - 1 and self.__return_to_first:
            self.__current = 0

    def setCurrent(self, pageNumber = 0):
        """ Set and flip the page with given pageNumber.

        pageNumber: index number of Page (default is 0)
        """
        self.__setCurrent(pageNumber)
        self.flipPage()

    def getCurrent(self):
        """ Returns current page index. """
        return self.__current

    def getCurrentWidget(self):
        """ Returns current page widget. """
        return self.getWidget(self.getCurrent())

    def getWidget(self, pageNumber):
        """ Returns widget for given page index 

        pageNumber: index number of Page
        """
        try:
            return self.__pages[pageNumber].widget
        except:
            return None

    def count(self):
        """ Returns number of pages. """
        return len(self.__pages) - 1

    def setAnimation(self, animation = 35):
        """ Set the transition animation with the given animation.

        animation: the number represents predefined QEasingCurves
                   List of predefined QEasingCurves can be found from:
                   http://doc.qt.nokia.com/4/qeasingcurve.html#Type-enum

                   Default is QEasingCurve::InOutBack (35)
        """
        self.__animation = animation
        self.__timeline.setEasingCurve(QEasingCurve(self.__animation))

    def setDuration(self, duration = 400):
        """ Set the transition duration.

        duration: duration time in ms
        """
        self.__duration = duration
        self.__timeline.setDuration(self.__duration)

    def flipPage(self, direction=0):
        """ Flip the page with given direction.

        direction: can be -1, 0 or +1
                   -1: previous page (if exists)
                    0: just flip to current page
                   +1: next page (if exists)
        """
        # Enable all widgets
        for page in self.__pages:
            page.widget.setEnabled(True)

        # Check given direction
        direction = direction if direction == 0 else max(min(1, direction), -1)

        # If direction is equal to zero no need to re-set current
        if not direction == 0:
            self.__setCurrent(self.__current + direction)

        # If last page is different from new page, flip it !
        if not self.__last == self.__current:
            self.__timeline.setFrameRange(self.__scrollBar.value(), self.__current * self.__base_value())
            self.__timeline.start()

    def next(self):
        """ Helper method to flip next page. """
        self.flipPage(1)

    def prev(self):
        """ Helper method to flip previous page. """
        self.flipPage(-1)
 def closeItem(self, item):
     animation = QTimeLine(ANIMATE_TIME, self)
     animation.setFrameRange(146, CLOSED_SIZE)
     animation.frameChanged.connect(lambda x: item.setSizeHint(QSize(32, x)))
     animation.start()
Exemple #36
0
class ExplorerNode(BaseNode):
    def __init__(self, nx_node, center_pos, nx_pos, steps, steps_max, small):
        """
        Create node in the graph scene

        :param tuple nx_node: Node info
        :param center_pos: The position of the center node
        :param nx_pos: Position of the nodes in the graph
        :param int steps: The steps from the center identity
        :param int steps_max: The steps max of the graph
        :param bool small: Small dots for big networks
        """
        super().__init__(nx_node, nx_pos)

        self.steps = steps
        self.steps_max = steps_max
        self.highlighted = False
        self.status_sentry = False

        if small:
            self.setRect(0, 0, 10, 10)
            self.text_item = None
        else:
            # text inside ellipse
            self.text_item = QGraphicsSimpleTextItem(self)
            self.text_item.setText(self.text)
            # center ellipse around text
            self.setRect(0, 0,
                         self.text_item.boundingRect().width() * 2,
                         self.text_item.boundingRect().height() * 2)
            # center text in ellipse
            self.text_item.setPos(self.boundingRect().width() / 4.0,
                                  self.boundingRect().height() / 4.0)

        #  set anchor to the center
        self.setTransform(QTransform().translate(
            -self.boundingRect().width() / 2.0,
            -self.boundingRect().height() / 2.0))

        # cursor change on hover
        self.setAcceptHoverEvents(True)
        self.setZValue(1)

        # animation and moves
        self.timeline = None
        self.loading_timer = QTimer()
        self.loading_timer.timeout.connect(self.next_tick)
        self.loading_counter = 0
        self._refresh_colors()
        self.setPos(center_pos)
        self.move_to(nx_pos)

    def update_metadata(self, metadata):
        super().update_metadata(metadata)
        self.status_sentry = self.metadata[
            'is_sentry'] if 'is_sentry' in self.metadata else False
        self._refresh_colors()

    def _refresh_colors(self):
        """
        Refresh elements in the node
        """
        # color around ellipse
        outline_color = QColor('grey')
        outline_style = Qt.SolidLine
        outline_width = 1
        if self.status_wallet:
            outline_width = 2
        if not self.status_member:
            outline_color = QColor('red')

        if self.status_sentry:
            outline_color = QColor('black')
            outline_width = 3

        self.setPen(QPen(outline_color, outline_width, outline_style))

        if self.highlighted:
            text_color = QColor('grey')
        else:
            text_color = QColor('black')

        if self.status_wallet == NodeStatus.HIGHLIGHTED:
            text_color = QColor('grey')

        if self.text_item:
            self.text_item.setBrush(QBrush(text_color))

        # create gradient inside the ellipse
        gradient = QRadialGradient(
            QPointF(0,
                    self.boundingRect().height() / 4),
            self.boundingRect().width())
        color = QColor()
        color.setHsv(120 - 60 / self.steps_max * self.steps,
                     180 + 50 / self.steps_max * self.steps,
                     60 + 170 / self.steps_max * self.steps)
        if self.highlighted:
            color = color.darker(200)
        color = color.lighter(
            math.fabs(math.sin(self.loading_counter / 100 * math.pi) * 100) +
            100)
        gradient.setColorAt(0, color)
        gradient.setColorAt(1, color.darker(150))
        self.setBrush(QBrush(gradient))

    def move_to(self, nx_pos):
        """
        Move to corresponding position
        :param nx_pos:
        :return:
        """
        origin_x = self.x()
        origin_y = self.y()
        final_x = nx_pos[self.id][0]
        final_y = nx_pos[self.id][1]

        def frame_move(frame):
            value = self.timeline.valueForTime(self.timeline.currentTime())
            x = origin_x + (final_x - origin_x) * value
            y = origin_y + (final_y - origin_y) * value
            self.setPos(x, y)
            if self.scene():
                self.scene().node_moved.emit(self.id, x, y)

        def timeline_ends():
            self.setPos(final_x, final_y)
            self.timeline = None

        # Remember to hold the references to QTimeLine and QGraphicsItemAnimation instances.
        # They are not kept anywhere, even if you invoke QTimeLine.start().
        self.timeline = QTimeLine(1000)
        self.timeline.setFrameRange(0, 100)
        self.timeline.frameChanged.connect(frame_move)
        self.timeline.finished.connect(timeline_ends)

        self.timeline.start()

    def highlight(self):
        """
        Highlight the edge in the scene
        """
        self.highlighted = True
        self._refresh_colors()
        self.update(self.boundingRect())

    def neutralize(self):
        """
        Neutralize the edge in the scene
        """
        self.highlighted = False
        self._refresh_colors()
        self.update(self.boundingRect())

    def start_loading_animation(self):
        """
        Neutralize the edge in the scene
        """
        if not self.loading_timer.isActive():
            self.loading_timer.start(10)

    def stop_loading_animation(self):
        """
        Neutralize the edge in the scene
        """
        self.loading_timer.stop()
        self.loading_counter = 100
        self._refresh_colors()
        self.update(self.boundingRect())

    def next_tick(self):
        """
        Next tick
        :return:
        """
        self.loading_counter += 1
        self.loading_counter %= 100
        self._refresh_colors()
        self.update(self.boundingRect())
Exemple #37
0
class Widget(Ui_CollectionsWidget, QWidget, ScreenWidget):
    name = "collectionSelection"

    def __init__(self):
        QWidget.__init__(self)
        self.setupUi(self)
        self.collections = None
        self.current_item = None
        self.last_item = None
        self.collectionList.itemClicked.connect(self.openItem)
        self.collectionList.currentItemChanged.connect(self.itemChanged)

    def fillCollections(self):
        self.collectionList.clear()
        selected = None
        for index, collection in enumerate(self.collections):
            self.addItem(collection)
            if ctx.installData.autoCollection == collection:
                selected = index

        if not selected:
            selected = 0

        self.current_item = self.collectionList.item(selected)
        self.last_item = self.current_item
        self.collectionList.setCurrentRow(selected)

    def shown(self):
        self.collections = ctx.collections
        self.fillCollections()
        ctx.mainScreen.disableNext()
        if self.current_item:
            self.openItem(self.current_item)
        else:
            self.openItem(self.collectionList.item(0))
        self.check()

    def execute(self):
        ctx.installData.autoCollection = self.collectionList.itemWidget(
            self.current_item).collection
        return True

    def check(self):
        if self.current_item:
            ctx.mainScreen.enableNext()
        else:
            ctx.mainScreen.disableNext()

    def itemChanged(self, current, previous):
        self.current_item = current
        self.check()

    def addItem(self, collection):
        item = QListWidgetItem(self.collectionList)
        item.setSizeHint(QSize(36, CLOSED_SIZE))
        self.collectionList.addItem(item)
        self.collectionList.setItemWidget(
            item, CollectionItem(self, collection, item))

    def openItem(self, item):
        if item == self.last_item:
            return

        if self.last_item:
            self.closeItem(self.last_item)

        self.animation = QTimeLine(ANIMATE_TIME, self)
        self.animation.setFrameRange(36, EXPANDED_SIZE)
        self.animation.frameChanged.connect(
            lambda x: item.setSizeHint(QSize(32, x)))
        self.animation.start()
        self.last_item = item
        self.animation.finished.connect(
            lambda: self.collectionList.setCurrentItem(item))

    def closeItem(self, item):
        animation = QTimeLine(ANIMATE_TIME, self)
        animation.setFrameRange(146, CLOSED_SIZE)
        animation.frameChanged.connect(
            lambda x: item.setSizeHint(QSize(32, x)))
        animation.start()
Exemple #38
0
class Widget(QWidget, ScreenWidget):
    name = "accounts"

    def __init__(self):
        super(Widget, self).__init__()
        self.ui = Ui_SetupUsersWidget()
        self.ui.setupUi(self)

        self.edititemindex = None

        self.time_line = QTimeLine(400, self)
        self.time_line.setFrameRange(0, 220)
        self.time_line.frameChanged[int].connect(self.animate)

        self.ui.scrollArea.setFixedHeight(0)

        # User Icons
        self.normal_user_icon = QPixmap(":/gui/pics/users.png")
        self.super_user_icon = QPixmap(":/gui/pics/users.png")

        # Set disabled the create Button
        self.ui.createButton.setEnabled(False)

        # Connections
        self.ui.pass1.textChanged[str].connect(self.slotTextChanged)
        self.ui.pass2.textChanged[str].connect(self.slotTextChanged)
        self.ui.username.textChanged[str].connect(self.slotTextChanged)
        self.ui.realname.textChanged[str].connect(self.slotTextChanged)
        self.ui.username.textEdited[str].connect(self.slotUserNameChanged)
        self.ui.realname.textEdited[str].connect(self.slotRealNameChanged)
        self.ui.userID.valueChanged[int].connect(self.slotTextChanged)
        self.ui.userIDCheck.stateChanged[int].connect(self.slotuserIDCheck)
        self.ui.createButton.clicked.connect(self.slotCreateUser)
        self.ui.cancelButton.clicked.connect(self.resetWidgets)
        self.ui.deleteButton.clicked.connect(self.slotDeleteUser)
        self.ui.editButton.clicked.connect(self.slotEditUser)
        self.ui.addMoreUsers.clicked.connect(self.slotAdvanced)
        self.ui.userList.itemDoubleClicked[QListWidgetItem].connect(self.slotEditUser)
        self.ui.pass2.returnPressed.connect(self.slotReturnPressed)

        # focusInEvent is not a signal
        # self.ui.pass1.focusInEvent[QFocusEvent].connect(self.checkCapsLock)
        # self.ui.pass2.focusInEvent[QFocusEvent].connect(self.checkCapsLock)
        # self.ui.username.focusInEvent[QFocusEvent].connect(self.checkCapsLock)
        # self.ui.realname.focusInEvent[QFocusEvent].connect(self.checkCapsLock)

        ctx.installData.users = []
        ctx.installData.autoLoginUser = None
        self.user_name_changed = False
        self.used_ids = []

    def eventFilter(self, obj, event):
        if event.type() == QEvent.FocusIn:  # even.type() ==...
            if obj == self.ui.pass1 or obj == self.ui.pass2 or \
                    obj == self.ui.username or obj == self.ui.realname:
                self.checkCapsLock()

    def shown(self):
        self.ui.cancelButton.hide()
        self.ui.realname.setFocus()
        if len(yali.users.PENDING_USERS) > 0 and self.ui.userList.count() == 0:
            for u in yali.users.PENDING_USERS:
                pix = self.normal_user_icon
                if "wheel" in u.groups:
                    pix = self.super_user_icon
                UserItem(self.ui.userList, pix, user=u)
                self.ui.autoLogin.addItem(u.username)
        if len(yali.users.PENDING_USERS) == 1:
            self.slotEditUser(self.ui.userList.item(0))
        elif len(yali.users.PENDING_USERS) > 1:
            self.ui.addMoreUsers.setChecked(True)
        self.checkUsers()
        self.checkCapsLock()

    def backCheck(self):
        self.refill()
        self.ui.cancelButton.hide()
        return True

    def refill(self):
        # reset and fill PENDING_USERS
        yali.users.reset_pending_users()
        for index in range(self.ui.userList.count()):
            user = self.ui.userList.item(index).getUser()
            ctx.installData.users.append(user)
            yali.users.PENDING_USERS.append(user)

    def execute(self):
        if self.checkUsers():
            ctx.installData.autoLoginUser = str(self.ui.autoLogin.currentText())
            if self.ui.createButton.text() == _("General", "Update"):
                return self.slotCreateUser()
            return True

        if not self.slotCreateUser():
            ctx.mainScreen.step_increment = 0
            return True

        self.refill()
        ctx.interface.informationWindow.hide()
        ctx.installData.autoLoginUser = str(self.ui.autoLogin.currentText())

        return True

    def setCapsLockIcon(self, child):
        if type(child) == QLineEdit:
            if pardus.xorg.capslock.isOn():
                child.setStyleSheet("""QLineEdit {
                        background-image: url(:/gui/pics/caps.png);
                        background-repeat: no-repeat;
                        background-position: right;
                        padding-right: 35px;
                        }""")
            else:
                child.setStyleSheet("""QLineEdit {
                        background-image: none;
                        padding-right: 0px;
                        }""")


    def checkCapsLock(self):
        for child in self.ui.groupBox.children():
            self.setCapsLockIcon(child)
        for child in self.ui.groupBox_2.children():
            self.setCapsLockIcon(child)

    def keyReleaseEvent(self, e):
        self.checkCapsLock()

    def showError(self, message):
        ctx.interface.informationWindow.update(message, type="error")
        ctx.mainScreen.disableNext()

    def animate(self, value):
        self.ui.scrollArea.setFixedHeight(int(value))
        self.ui.frame.setMinimumHeight(250)

        if self.ui.scrollArea.height() == 0:
            self.ui.scrollArea.hide()
        else:
            self.ui.scrollArea.show()

        if self.ui.scrollArea.height() == 220:
            self.time_line.setDirection(1)
            self.ui.frame.setMinimumHeight(420)
        if self.ui.scrollArea.height() == 0:
            self.time_line.setDirection(0)

    def slotuserIDCheck(self, state):
        if state:
            self.ui.userID.setEnabled(True)
        else:
            self.ui.userID.setEnabled(False)

    def slotAdvanced(self):
        icon_path = None
        if self.ui.scrollArea.isVisible():
            icon_path = ":/gui/pics/expand.png"
            self.time_line.start()
        else:
            self.ui.scrollArea.show()
            icon_path = ":/gui/pics/collapse.png"
            self.time_line.start()

        icon = QIcon()
        icon.addPixmap(QPixmap(icon_path), QIcon.Normal, QIcon.Off)
        self.ui.addMoreUsers.setIcon(icon)
        self.checkUsers()

    def slotTextChanged(self):
        username = str(self.ui.username.text())
        realname = unicode(self.ui.realname.text())
        password = unicode(self.ui.pass1.text())
        password_confirm = unicode(self.ui.pass2.text())

        if not password == '' and (password.lower() == username.lower() or
                                   password.lower() == realname.lower()):
            self.showError(_("General", 'Don\'t use your user name or name as a password'))
            return
        elif password_confirm != password and password_confirm:
            self.showError(_("General", 'Passwords do not match'))
            return
        elif len(password) == len(password_confirm) and len(password_confirm) < 4 and not password =='':
            self.showError(_("General", 'Password is too short'))
            return
        else:
            ctx.interface.informationWindow.hide()

        if self.ui.username.text() and password and password_confirm:
            self.ui.createButton.setEnabled(True)
            if not self.ui.addMoreUsers.isChecked():
                ctx.mainScreen.enableNext()
                ctx.mainScreen.enableBack()
        else:
            self.ui.createButton.setEnabled(False)
            if not self.ui.addMoreUsers.isChecked():
                ctx.mainScreen.disableNext()

    def currentUsers(self):
        users = []
        for index in range(self.ui.userList.count()):
            users.append(self.ui.userList.item(index).getUser().username)
        return users

    def slotUserNameChanged(self):
        self.user_name_changed = True

    def slotRealNameChanged(self):
        if not self.user_name_changed:
            used_users = yali.users.get_users()
            used_users.extend(self.currentUsers())
            self.ui.username.setText(yali.users.nick_guess(self.ui.realname.text(), used_users))

    def slotCreateUser(self):
        user = yali.users.User()
        user.username = str(self.ui.username.text())
        # ignore last character. see bug #887
        user.realname = unicode(self.ui.realname.text())
        user.passwd = unicode(self.ui.pass1.text())
        user.groups = ["users", "pnp", "disk", "audio", "video", "power",
                     "dialout", "lp", "lpadmin", "cdrom", "floppy"]
        pix = self.normal_user_icon
        if self.ui.admin.isChecked():
            user.groups.append("wheel")
            pix = self.super_user_icon
        user.no_password = self.ui.noPass.isChecked()

        # check user validity
        if user.exists() or (user.username in self.currentUsers() and self.edititemindex == None):
            self.showError(_("General", "This user name is already taken, please choose another one."))
            return False
        elif not user.usernameIsValid():
            # FIXME: Mention about what are the invalid characters!
            self.showError(_("General", "The user name contains invalid characters."))
            return False
        elif not user.realnameIsValid():
            self.showError(_("General", "The real name contains invalid characters."))
            return False

        # Dont check in edit mode
        if self.ui.addMoreUsers.isChecked() and self.ui.userIDCheck.isChecked():
            uid = self.ui.userID.value()
            if self.edititemindex == None:
                if uid in self.used_ids:
                    self.showError(_("General", 'User ID used before, choose another one!'))
                    return False
            self.used_ids.append(uid)
            user.uid = uid

        self.ui.createButton.setText(_("General", "Add"))
        self.ui.cancelButton.hide()
        update_item = None

        try:
            self.ui.userList.takeItem(self.edititemindex)
            self.ui.autoLogin.removeItem(self.edititemindex + 1)
        except:
            update_item = self.edititemindex
            # nothing wrong. just adding a new user...
            pass

        item = UserItem(self.ui.userList, pix, user=user)

        # add user to auto-login list.
        self.ui.autoLogin.addItem(user.username)

        if update_item:
            self.ui.autoLogin.setCurrentIndex(self.ui.autoLogin.count())

        # clear form
        self.resetWidgets()

        ctx.logger.debug("slotCreateUser :: user (%s) '%s (%s)' added/updated" % (user.uid, user.realname, user.username))
        ctx.logger.debug("slotCreateUser :: user groups are %s" % str(','.join(user.groups)))

        # give focus to realname widget for a new user. #3280
        #self.ui.realname.setFocus()
        self.checkUsers()
        self.user_name_changed = False
        self.refill()
        return True

    def slotDeleteUser(self):
        if self.ui.userList.currentRow() == self.edititemindex:
            self.resetWidgets()
            self.ui.autoLogin.setCurrentIndex(0)
        _cur = self.ui.userList.currentRow()
        item = self.ui.userList.item(_cur).getUser()
        if item.uid in self.used_ids:
            self.used_ids.remove(item.uid)
        self.ui.userList.takeItem(_cur)
        self.ui.autoLogin.removeItem(_cur + 1)
        self.ui.createButton.setText(_("General", "Add"))

        icon = QIcon()
        icon.addPixmap(QPixmap(":/gui/pics/user-group-new.png"), QIcon.Normal, QIcon.Off)
        self.ui.createButton.setIcon(icon)

        self.ui.cancelButton.hide()
        self.checkUsers()

    def slotEditUser(self, item=None):
        if not item:
            item = self.ui.userList.currentItem()
        self.ui.userList.setCurrentItem(item)
        user = item.getUser()
        if user.uid > -1:
            self.ui.userIDCheck.setChecked(True)
            self.ui.userID.setValue(user.uid)
        self.ui.username.setText(user.username)
        self.ui.realname.setText(user.realname)
        self.ui.pass1.setText(user.passwd)
        self.ui.pass2.setText(user.passwd)

        if "wheel" in user.groups:
            self.ui.admin.setChecked(True)
        else:
            self.ui.admin.setChecked(False)

        self.ui.noPass.setChecked(user.no_password)

        self.edititemindex = self.ui.userList.currentRow()
        self.ui.createButton.setText(_("General", "Update"))
        icon = QIcon()
        icon.addPixmap(QPixmap(":/gui/pics/tick.png"), QIcon.Normal, QIcon.Off)
        self.ui.createButton.setIcon(icon)
        self.ui.cancelButton.setVisible(self.ui.createButton.isVisible())

    def checkUserFields(self):
        username = unicode(self.ui.username.text())
        realname = unicode(self.ui.realname.text())
        password = unicode(self.ui.pass1.text())
        password_confirm = unicode(self.ui.pass2.text())
        if username and realname and password and password_confirm and \
        (password == password_confirm) and \
        (password.lower() != username.lower() and password.lower() != realname.lower()):
            return True
        else:
            return False

    def checkUsers(self):
        if self.ui.userList.count() > 0:
            self.ui.userList.setCurrentRow(0)
            self.ui.deleteButton.setEnabled(True)
            self.ui.editButton.setEnabled(True)
            self.ui.autoLogin.setEnabled(True)
            ctx.mainScreen.enableNext()
            ctx.mainScreen.enableBack()
            return True
        else:
            if self.checkUserFields():
                ctx.mainScreen.enableNext()
            else:
                ctx.mainScreen.disableNext()

        # there is no user in list so noting to delete
        self.ui.deleteButton.setEnabled(False)
        self.ui.editButton.setEnabled(False)
        self.ui.autoLogin.setEnabled(False)
        return False


    def resetWidgets(self):
        # clear all
        self.edititemindex = None
        self.ui.username.clear()
        self.ui.realname.clear()
        self.ui.pass1.clear()
        self.ui.pass2.clear()
        self.ui.admin.setChecked(False)
        self.ui.noPass.setChecked(False)
        self.ui.userIDCheck.setChecked(False)
        self.ui.createButton.setEnabled(False)
        if self.ui.cancelButton.isVisible():
            self.ui.cancelButton.setHidden(self.sender() == self.ui.cancelButton)
            self.checkUsers()
        self.ui.createButton.setText(_("General", "Add"))
        icon = QIcon()
        icon.addPixmap(QPixmap(":/gui/pics/user-group-new.png"), QIcon.Normal, QIcon.Off)
        self.ui.createButton.setIcon(icon)


    def slotReturnPressed(self):
        if self.ui.createButton.isEnabled() and self.ui.addMoreUsers.isChecked():
            self.slotCreateUser()