def update_label_with_slider(label: QLabel, slider: QSlider):
    if label.display_as_percentage:
        min_value = slider.minimum()
        percentage = (slider.value() - min_value) / (slider.maximum() - min_value)
        label.setText(f"{percentage * 100: 3.0f}%")
    else:
        label.setText(str(slider.value()))
Ejemplo n.º 2
0
class Controller(QWidget):
    def __init__(self, parent=None):
        super(Controller, self).__init__(parent)

        self.resourcePath = os.path.normpath(os.path.join(fileDir,
                                                          "resource")).replace(
                                                              "\\", "/")

        self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setAttribute(Qt.WA_Hover)
        self.setMouseTracking(True)
        self.setAcceptDrops(True)

        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)

        self.fillColor = QColor(127, 127, 127, 2)
        self.penColor = QColor(127, 127, 127, 2)

        self.onTop = False
        self.visible = False
        self.drawDrag = False
        self.isPaused = False
        self.lastMove = datetime.now()
        self.lastButton = Qt.MouseButton.NoButton

        self.setupWidget()
        self.setupRightClick()
        if parent:
            self.player = parent
            self.setupSignal()
        self.toggleVisibility(False)

    def setParent(self, parent):
        self.player = parent
        return super(Controller, self).setParent(parent)

    def setupWidget(self):
        # Top
        self.pinBtn = ButtonIcon(icon=f"{self.resourcePath}/pin.svg",
                                 iconsize=15)
        self.closeBtn = ButtonIcon(icon=f"{self.resourcePath}/cancel.svg",
                                   iconsize=15)
        self.topLayout = QHBoxLayout()
        self.topLayout.setContentsMargins(5, 5, 5, 5)
        self.topLayout.addWidget(self.pinBtn)
        self.topLayout.addStretch()
        self.topLayout.addWidget(self.closeBtn)

        # Middle
        self.playBtn = ButtonIcon(icon=f"{self.resourcePath}/play.svg",
                                  iconsize=100)
        self.volumeSlider = QSlider(Qt.Vertical, self)
        self.volumeSlider.setMaximum(100)
        self.volumeSlider.setValue(100)
        self.volumeBtn = ButtonIcon(icon=f"{self.resourcePath}/speaker.svg",
                                    iconsize=15)
        self.volumeLayout = QVBoxLayout()
        self.volumeLayout.setContentsMargins(0, 0, 0, 0)
        for w in (self.volumeSlider, self.volumeBtn):
            self.volumeLayout.addWidget(w)

        self.playLayout = QHBoxLayout()
        self.playLayout.addStretch()
        self.playLayout.addWidget(self.playBtn)
        self.playLayout.addStretch()
        self.playLayout.addLayout(self.volumeLayout)

        # Bottom
        self.addBtn = ButtonIcon(icon=f"{self.resourcePath}/plus.svg",
                                 iconsize=15)
        self.timeSlider = TimeSlider(Qt.Horizontal, self)
        self.volumeSlider.setStyleSheet(self.timeSlider.qss())
        self.repeatBtn = ButtonIcon(icon=f"{self.resourcePath}/replay.svg",
                                    iconsize=15)
        self.listBtn = ButtonIcon(icon=f"{self.resourcePath}/list.svg",
                                  iconsize=15)
        self.bottomLayout = QHBoxLayout()
        self.bottomLayout.setContentsMargins(0, 0, 0, 0)
        self.bottomLayout.addWidget(self.addBtn)
        self.bottomLayout.addWidget(self.listBtn)
        self.bottomLayout.addWidget(self.timeSlider)
        self.bottomLayout.addWidget(self.repeatBtn)

        self.layout().addLayout(self.topLayout)
        self.layout().addStretch()
        self.layout().addLayout(self.playLayout)
        self.layout().addStretch()
        self.layout().addLayout(self.bottomLayout)

        self.timer = QTimer()
        self.timer.setInterval(50)
        self.timer.timeout.connect(self.toggleCursor)
        self.timer.start()

        self.opacFX = []
        for w in (self.pinBtn, self.closeBtn, self.playBtn, self.volumeSlider,
                  self.volumeBtn, self.addBtn, self.repeatBtn, self.listBtn):
            w.setFocusProxy(self)
            fx = QGraphicsOpacityEffect(w)
            fx.setOpacity(0)
            w.setGraphicsEffect(fx)
            self.opacFX.append(fx)
        self.timeSlider.setHeight(1)
        self.timeSlider.setFocusProxy(self)

    def setupRightClick(self):
        self.popMenu = QMenu(self)
        self.openAct = QAction('Open File', self)
        self.fullAct = QAction('Fullscreen', self)
        self.atopAct = QAction('Pin on Top', self)
        self.listAct = QAction('Playlist', self)
        self.helpAct = QAction('Help', self)
        self.exitAct = QAction('Exit', self)

        for act in (self.openAct, self.fullAct, self.listAct, self.helpAct):
            self.popMenu.addAction(act)
        self.popMenu.addSeparator()
        self.popMenu.addAction(self.exitAct)

        # Initial
        self.fullAct.setCheckable(True)
        self.listAct.setCheckable(True)

        # Temp
        self.listAct.setDisabled(True)
        self.helpAct.setDisabled(True)

    def opacityAnimation(self, end, duration, callback):
        anims = []
        for fx in self.opacFX:
            ani = QPropertyAnimation(fx, b"opacity")
            ani.setStartValue(fx.opacity())
            ani.setEndValue(end)
            a = max(fx.opacity(), end)
            i = min(fx.opacity(), end)
            ani.setDuration((a - i) * duration)
            ani.stateChanged.connect(callback)
            anims.append(ani)
        return anims

    def heightAnimation(self, target, height, duration, callback):
        ani = QPropertyAnimation(target, b"Height")
        ani.setStartValue(target.getHeight())
        ani.setEndValue(height)
        a = max(target.getHeight(), height)
        i = min(target.getHeight(), height)
        ani.setDuration((a - i) / a * duration)
        # ani.finished.connect(callback)
        return ani

    def setupSignal(self):
        # Controller
        self.closeBtn.clicked.connect(self.player.close)
        self.playBtn.clicked.connect(self.togglePlay)
        self.volumeSlider.valueChanged.connect(self.player.setVolume)
        self.addBtn.clicked.connect(self.openFile)
        self.timeSlider.sliderMoved.connect(self.seek)

        # Player
        self.player.stateChanged.connect(self.onStateChanged)
        self.player.lengthChanged.connect(self.onLengthChanged)
        self.player.timeChanged.connect(self.onTimeChanged)

        # Right click
        self.openAct.triggered.connect(self.openFile)
        self.fullAct.triggered.connect(self.toggleFullscreen)
        self.exitAct.triggered.connect(self.player.close)

    def event(self, event):
        if event.type() == QEvent.Type.Enter:
            self.lastMove = datetime.now()
            self.toggleVisibility(True)
        elif event.type() == QEvent.Type.Leave:
            self.toggleVisibility(False)
        return super(Controller, self).event(event)

    def paintEvent(self, event):
        s = self.size()
        qp = QPainter()
        qp.begin(self)
        qp.setRenderHint(QPainter.Antialiasing, True)
        qp.setPen(self.penColor)
        qp.setBrush(self.fillColor)
        qp.drawRect(0, 0, s.width(), s.height())

        if self.drawDrag:
            pen = QPen(Qt.white, 5)
            pen.setCapStyle(Qt.RoundCap)
            qp.setPen(pen)
            qp.setBrush(self.fillColor)

            outerWidth = s.width() - 60
            outerHeight = s.height() - 60

            ow = int(s.width() / 2 - outerWidth / 2)
            oh = int(s.height() / 2 - outerHeight / 2)
            qp.drawRoundedRect(ow, oh, outerWidth, outerHeight, 5, 5)

            qp.setBrush(Qt.white)
            thickness = 12
            length = 50
            roundness = thickness / 2

            vS = int(s.width() / 2 - thickness / 2)
            vE = int(s.height() / 2 - length / 2)
            qp.drawRoundedRect(vS, vE, thickness, length, roundness, roundness)
            hS = int(s.width() / 2 - length / 2)
            hE = int(s.height() / 2 - thickness / 2)
            qp.drawRoundedRect(hS, hE, length, thickness, roundness, roundness)

        qp.end()

    def mousePressEvent(self, event):
        self.lastButton = event.button()
        if event.button() == Qt.MouseButton.LeftButton:
            self.startPos = event.pos()
            self.lastClick = datetime.now()
        elif event.button() == Qt.MouseButton.MiddleButton:
            self.startFrame = self.timeSlider.value()
            self.startPos = event.pos()
        return super(Controller, self).mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.MouseButton.LeftButton:
            if hasattr(self, "startPos"):
                if (datetime.now() - self.lastClick).microseconds / 1000 < 300:
                    self.togglePlay()
                delattr(self, "startPos")

        elif event.button() == Qt.MouseButton.RightButton:
            self.onRightClick(event.pos())

        elif self.lastButton == Qt.MouseButton.MiddleButton:
            if hasattr(self, "startPos"): delattr(self, "startPos")
            if hasattr(self, "startFrame"): delattr(self, "startFrame")

        self.lastButton = None
        return super(Controller, self).mouseReleaseEvent(event)

    def mouseMoveEvent(self, event):
        self.lastMove = datetime.now()
        self.toggleVisibility(True)

        if self.lastButton == Qt.MouseButton.LeftButton:
            if not self.player.isFullScreen():
                if hasattr(self, "startPos"):
                    delta = event.pos() - self.startPos
                    self.move(self.pos() + delta)
                    self.player.move(self.player.pos() + delta)
        elif self.lastButton == Qt.MouseButton.MiddleButton:
            if hasattr(self, "startFrame"):
                self.player.pause()

                delta = event.pos() - self.startPos
                percent = delta.x() / self.width()

                m = self.timeSlider.maximum()
                final = int(self.startFrame + (percent * m))

                self.timeSlider.setValue(final)
                self.seek()

        return super(Controller, self).mouseMoveEvent(event)

    def mouseDoubleClickEvent(self, event):
        if event.button() == Qt.MouseButton.LeftButton:
            self.toggleFullscreen()

        return super(Controller, self).mouseDoubleClickEvent(event)

    def wheelEvent(self, event):
        increment = int(self.volumeSlider.maximum() / 10)
        if (event.angleDelta().y()) > 0:
            self.volumeSlider.setValue(self.volumeSlider.value() + increment)
        elif (event.angleDelta().y()) < 0:
            self.volumeSlider.setValue(self.volumeSlider.value() - increment)
        return super(Controller, self).wheelEvent(event)

    def dragEnterEvent(self, event):
        self.drawDrag = True
        self.update()
        if event.mimeData().hasUrls():
            event.accept()
        elif event.mimeData().hasText():
            event.accept()
        else:
            event.ignore()

    def dragLeaveEvent(self, event):
        self.drawDrag = False
        self.update()
        return super(Controller, self).dragLeaveEvent(event)

    def dropEvent(self, event):
        self.drawDrag = False
        self.update()
        if event.mimeData().hasUrls():
            url = event.mimeData().urls()[0].toString()
            self.player.createMedia(url)
            self.player.play()
        elif event.mimeData().hasText():
            url = event.mimeData().text()
            if os.path.isfile(url):
                self.player.createMedia(url)
                self.player.play()

    def keyPressEvent(self, event):
        self.lastMove = datetime.now()
        self.toggleVisibility(True)
        if event.key() in [Qt.Key_Left, Qt.Key_A, Qt.Key_Less, Qt.Key_Comma]:
            self.player.pause()
            self.timeSlider.setValue(self.timeSlider.value() - 1)
            self.seek()
        elif event.key() in [
                Qt.Key_Right, Qt.Key_D, Qt.Key_Greater, Qt.Key_Period
        ]:
            self.player.pause()
            self.timeSlider.setValue(self.timeSlider.value() + 1)
            self.seek()
        elif event.key() in [Qt.Key_Up, Qt.Key_Plus]:
            self.volumeSlider.setValue(self.volumeSlider.value() + 5)
        elif event.key() in [Qt.Key_Down, Qt.Key_Minus]:
            self.volumeSlider.setValue(self.volumeSlider.value() - 5)
        elif event.key() in [Qt.Key_Space]:
            self.togglePlay()
        elif event.key() in [Qt.Key_Return, Qt.Key_Enter, Qt.Key_O]:
            self.openFile()
        elif event.key() in [Qt.Key_F11, Qt.Key_F]:
            self.toggleFullscreen()
        elif event.key() in [Qt.Key_Tab, Qt.Key_L]:
            print("Open Playlist")
        elif event.key() in [Qt.Key_Slash, Qt.Key_Question]:
            print("Open Help")
        elif event.key() in [Qt.Key_Menu]:
            self.onRightClick(QPoint(0, 0))
        elif event.key() in [Qt.Key_Escape]:
            self.player.close()
        elif QKeySequence(event.key() +
                          int(event.modifiers())) == QKeySequence("Ctrl+V"):
            url = QApplication.clipboard().text()
            if "youtube.com" in url.lower():
                video = pafy.new(url)
                best = video.getbest()
                playurl = best.url
                while not playurl:
                    pass
            else:
                playurl = url
            self.player.createMedia(playurl)
            self.player.play()

        return super(Controller, self).keyPressEvent(event)

    def onLengthChanged(self, length):
        self.timeSlider.setMaxTime(length)
        self.timeSlider.setMaximum(int(length / 1000 * self.player.fps))

    def onTimeChanged(self, pos):
        sliderPos = int(pos * self.timeSlider.maximum())
        self.timeSlider.setValue(sliderPos)

    def onStateChanged(self, state):
        if state == 'NothingSpecial':
            return
        elif state == 'Opening':
            return
        elif state == 'Buffering':
            return
        elif state == 'Playing':
            self.playBtn.changeIcon(f"{self.resourcePath}/pause.svg")
        elif state == 'Paused':
            self.playBtn.changeIcon(f"{self.resourcePath}/play.svg")
        elif state == 'Stopped':
            self.playBtn.changeIcon(f"{self.resourcePath}/replay.svg")
            mediaPath = self.player.media.get_mrl()
            self.player.createMedia(mediaPath)
            self.player.pause()
            self.slide(.99)

        elif state == 'Ended':
            self.timeSlider.setValue(self.timeSlider.maximum())
        elif state == 'Error':
            return

    def onRightClick(self, point):
        self.fullAct.setChecked(self.player.isFullScreen())
        self.popMenu.exec_(self.mapToGlobal(point))

    def openFile(self):
        fileName, _ = QFileDialog.getOpenFileName(self, "Open Movie", fileDir,
                                                  "All (*.*)")
        if fileName != '':
            self.player.createMedia(fileName)
            self.player.play()

    def toggleWidget(self, state):
        if (self.sender().endValue() > 0
                and state == QAbstractAnimation.State.Running):
            self.sender().targetObject().parent().show()
        elif (self.sender().endValue() <= 0
              and state == QAbstractAnimation.State.Stopped):
            self.sender().targetObject().parent().hide()

    def toggleVisibility(self, visible=True):
        if self.visible == visible:
            return
        self.visible = visible
        if visible:
            self.setCursor(Qt.ArrowCursor)

        self.move(self.player.pos().x() + self.player.gripSize,
                  self.player.pos().y() + self.player.gripSize)
        self.resize(self.player.width() - (self.player.gripSize * 2),
                    self.player.height() - (self.player.gripSize * 2))

        self.anims = self.opacityAnimation(1 if visible else 0, 300,
                                           self.toggleWidget)
        self.anims += [
            self.heightAnimation(w, 20 if visible else 1, 300,
                                 self.toggleWidget)
            for w in (self.addBtn, self.timeSlider, self.listBtn,
                      self.repeatBtn)
        ]
        for a in self.anims:
            a.start()

        self.timeSlider.setTipVisibility(visible)

    def toggleOnTop(self):
        # self.onTop = not self.onTop
        self.player.onTop(not self.player.isOnTop())
        self.player.update()
        self.setWindowFlag(Qt.WindowStaysOnBottomHint,
                           not self.player.isOnTop())
        self.player.update()

    def toggleCursor(self):
        if (datetime.now() - self.lastMove).seconds >= 5:
            self.setCursor(Qt.BlankCursor)
            self.toggleVisibility(False)
        else:
            self.setCursor(Qt.ArrowCursor)

    def toggleFullscreen(self):
        if self.player.isFullScreen():
            self.player.showNormal()
        else:
            self.player.showFullScreen()
        self.player.resizeController()

    def togglePlay(self):
        if not self.player.media:
            self.openFile()

        if self.player.isPlaying():
            self.player.pause()
        else:
            self.player.play()

    def seek(self):
        self.player.setPosition(self.timeSlider.value() /
                                self.timeSlider.maximum())

    def slide(self, pos):
        self.player.setPosition(pos)
Ejemplo n.º 3
0
class MainWindow(QDialog):
    def onModeIndexChanged(self):
        self.OpenGLWidget.setMode(self.modeComboBox.currentIndex())
    # onModeIndexChanged

    def onAlphaChanged(self):
        self.OpenGLWidget.setAlphaTest(self.alphaComboBox.currentIndex(), self.alphaSlider.value() / 100)
    # onAlphaChanged

    def onBlendChange(self):
        self.OpenGLWidget.setBlendTest(self.blendSComboBox.currentIndex(), self.blendDComboBox.currentIndex())
    # onBlendChange
    
    def onSpinPointsChanged(self):
        self.OpenGLWidget.setPointsAmount(self.amountSpinBox.value())
        self.amountSlider.setValue(self.amountSpinBox.value())
    # onSpinPointsChanged

    def onSliderPointsChanged(self):
        self.OpenGLWidget.setPointsAmount(self.amountSpinBox.value())
        self.amountSpinBox.setValue(self.amountSlider.value())
    # onSliderPointsChanged

    def onScissorChanged(self):
        self.OpenGLWidget.setScissor(self.scissorX.value(), self.scissorY.value(), self.scissorW.value(),
                                     self.scissorH.value())
    # onScissorChanged

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setFixedSize(1200, 620)
        self.setWindowTitle("Vlasov Roman lr1-2")
        # OpenGL widget
        glWidgetW = 800
        glWidgetH = 600
        self.OpenGLWidget = OpenGLView()
        self.OpenGLWidget.setFixedSize(glWidgetW, glWidgetH)
        self.OpenGLWidget.setMode(0)
        # mode
        self.modeLabel = QLabel("Mode: ")
        self.modeComboBox = QComboBox()
        modes = {
            0: "GL_POINTS",
            1: "GL_LINES",
            2: "GL_LINE_STRIP",
            3: "GL_LINE_LOOP",
            4: "GL_TRIANGLES",
            5: "GL_TRIANGLE_STRIP",
            6: "GL_TRIANGLE_FAN",
            7: "GL_QUADS",
            8: "GL_QUAD_STRIP",
            9: "GL_POLYGON"
        }
        for mode in modes:
            self.modeComboBox.addItem(modes.get(mode))
        self.modeComboBox.currentIndexChanged.connect(self.onModeIndexChanged)
        # number of points
        self.amountLabel = QLabel("Number of points: ")
        self.amountSpinBox = QSpinBox()
        self.amountSpinBox.setMinimum(4)
        self.amountSpinBox.setMaximum(100)
        self.amountSpinBox.valueChanged.connect(self.onSpinPointsChanged)
        self.amountSlider = QSlider(QtCore.Qt.Horizontal)
        self.amountSlider.setMinimum(4)
        self.amountSlider.setMaximum(100)
        self.amountSlider.valueChanged.connect(self.onSliderPointsChanged)
        self.amountMinLabel = QLabel("Min: 4")
        self.amountMinLabel.setFixedWidth(40)
        self.amountMaxLabel = QLabel("Max: 100")
        self.amountMaxLabel.setFixedWidth(60)
        line1 = QFrame()
        line1.setFrameShape(QFrame.HLine)
        layoutAmount = QHBoxLayout()
        layoutAmount.addWidget(self.amountMinLabel)
        layoutAmount.addWidget(self.amountSpinBox)
        layoutAmount.addWidget(self.amountMaxLabel)
        # GL_SCISSOR_TEST
        self.scissorLabel = QLabel("GL_SCISSOR_TEST")
        self.xLabel = QLabel("x")
        self.yLabel = QLabel("y")
        self.wLabel = QLabel("width")
        self.hLabel = QLabel("height")
        line2 = QFrame()
        line2.setFrameShape(QFrame.HLine)
        self.scissorX = QSlider(QtCore.Qt.Horizontal)
        self.scissorY = QSlider(QtCore.Qt.Horizontal)
        self.scissorW = QSlider(QtCore.Qt.Horizontal)
        self.scissorH = QSlider(QtCore.Qt.Horizontal)
        self.scissorX.setMinimum(0)
        self.scissorY.setMinimum(0)
        self.scissorW.setMinimum(0)
        self.scissorH.setMinimum(0)
        self.scissorX.setMaximum(glWidgetW)
        self.scissorY.setMaximum(glWidgetH)
        self.scissorW.setMaximum(glWidgetW)
        self.scissorH.setMaximum(glWidgetH)
        self.scissorX.valueChanged.connect(self.onScissorChanged)
        self.scissorY.valueChanged.connect(self.onScissorChanged)
        self.scissorW.valueChanged.connect(self.onScissorChanged)
        self.scissorH.valueChanged.connect(self.onScissorChanged)
        self.scissorH.setValue(self.scissorH.maximum())
        self.scissorW.setValue(self.scissorW.maximum())
        # GL_ALPHA_TEST
        self.alphaTestLabel = QLabel("GL_ALPHA_TEST")
        self.alphaLabel = QLabel("Function: ")
        self.alphaValueLabel = QLabel("Value: ")
        line3 = QFrame()
        line3.setFrameShape(QFrame.HLine)
        self.alphaComboBox = QComboBox()
        alpha = {
            0: "GL_NEVER",
            1: "GL_LESS",
            2: "GL_EQUAL",
            3: "GL_LEQUAL",
            4: "GL_GREATER",
            5: "GL_NOTEQUAL",
            6: "GL_GEQUAL",
            7: "GL_ALWAYS"
        }
        for mode in alpha:
            self.alphaComboBox.addItem(alpha.get(mode))
        self.alphaComboBox.setCurrentIndex(7)
        self.alphaSlider = QSlider(QtCore.Qt.Horizontal)
        self.alphaSlider.setMinimum(0)
        self.alphaSlider.setMaximum(100)
        self.alphaComboBox.currentIndexChanged.connect(self.onAlphaChanged)
        self.alphaSlider.valueChanged.connect(self.onAlphaChanged)
        # GL_BLEND
        self.blendTestLabel = QLabel("GL_BLEND")
        self.sfactorLabel = QLabel("sfactor: ")
        self.dfactorLabel = QLabel("dfactor: ")
        line4 = QFrame()
        line4.setFrameShape(QFrame.HLine)
        self.blendSComboBox = QComboBox()
        self.blendDComboBox = QComboBox()
        sfactor = {
            0: "GL_ZERO",
            1: "GL_ONE",
            2: "GL_DST_COLOR",
            3: "GL_ONE_MINUS_DST_COLOR",
            4: "GL_SRC_ALPHA",
            5: "GL_ONE_MINUS_SRC_ALPHA",
            6: "GL_DST_ALPHA",
            7: "GL_ONE_MINUS_DST_ALPHA",
            8: "GL_SRC_ALPHA_SATURATE"
        }
        dfactor = {
            0: "GL_ZERO",
            1: "GL_ONE",
            2: "GL_SRC_COLOR",
            3: "GL_ONE_MINUS_SRC_COLOR",
            4: "GL_SRC_ALPHA",
            5: "GL_ONE_MINUS_SRC_ALPHA",
            6: "GL_DST_ALPHA",
            7: "GL_ONE_MINUS_DST_ALPHA"
        }
        for mode in sfactor:
            self.blendSComboBox.addItem(sfactor.get(mode))
        for mode in dfactor:
            self.blendDComboBox.addItem(dfactor.get(mode))
        self.blendSComboBox.currentIndexChanged.connect(self.onBlendChange)
        self.blendDComboBox.currentIndexChanged.connect(self.onBlendChange)
        self.blendSComboBox.setCurrentIndex(1)
        # tools panel layout
        layoutTools = QVBoxLayout()
        layoutTools.addWidget(self.amountLabel)
        layoutTools.addLayout(layoutAmount)
        layoutTools.addWidget(self.amountSlider)
        layoutTools.addWidget(line1)
        layoutTools.addWidget(self.modeLabel)
        layoutTools.addWidget(self.modeComboBox)
        layoutTools.addWidget(line2)
        layoutTools.addWidget(self.scissorLabel)
        layoutTools.addWidget(self.xLabel)
        layoutTools.addWidget(self.scissorX)
        layoutTools.addWidget(self.yLabel)
        layoutTools.addWidget(self.scissorY)
        layoutTools.addWidget(self.wLabel)
        layoutTools.addWidget(self.scissorW)
        layoutTools.addWidget(self.hLabel)
        layoutTools.addWidget(self.scissorH)
        layoutTools.addWidget(line3)
        layoutTools.addWidget(self.alphaTestLabel)
        layoutTools.addWidget(self.alphaLabel)
        layoutTools.addWidget(self.alphaComboBox)
        layoutTools.addWidget(self.alphaValueLabel)
        layoutTools.addWidget(self.alphaSlider)
        layoutTools.addWidget(line4)
        layoutTools.addWidget(self.blendTestLabel)
        layoutTools.addWidget(self.sfactorLabel)
        layoutTools.addWidget(self.blendSComboBox)
        layoutTools.addWidget(self.dfactorLabel)
        layoutTools.addWidget(self.blendDComboBox)
        verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        layoutTools.addItem(verticalSpacer)
        # window layout
        layout = QHBoxLayout()
        layout.addWidget(self.OpenGLWidget)
        layout.addLayout(layoutTools)
        self.setLayout(layout)
Ejemplo n.º 4
0
class ApplicationWindow(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)

        self.column_names = ["Column A", "Column B", "Column C"]

        # Central widget
        self._main = QWidget()
        self.setCentralWidget(self._main)

        # Main menu bar
        self.menu = self.menuBar()
        self.menu_file = self.menu.addMenu("File")
        exit = QAction("Exit", self, triggered=qApp.quit)
        self.menu_file.addAction(exit)

        self.menu_about = self.menu.addMenu("&About")
        about = QAction("About Qt", self, shortcut=QKeySequence(QKeySequence.HelpContents),
                        triggered=qApp.aboutQt)
        self.menu_about.addAction(about)

        # Figure (Left)
        self.fig = Figure(figsize=(5, 3))
        self.canvas = FigureCanvas(self.fig)

        # Sliders (Left)
        self.slider_azim = QSlider(minimum=0, maximum=360, orientation=Qt.Horizontal)
        self.slider_elev = QSlider(minimum=0, maximum=360, orientation=Qt.Horizontal)

        self.slider_azim_layout = QHBoxLayout()
        self.slider_azim_layout.addWidget(QLabel("{}".format(self.slider_azim.minimum())))
        self.slider_azim_layout.addWidget(self.slider_azim)
        self.slider_azim_layout.addWidget(QLabel("{}".format(self.slider_azim.maximum())))

        self.slider_elev_layout = QHBoxLayout()
        self.slider_elev_layout.addWidget(QLabel("{}".format(self.slider_elev.minimum())))
        self.slider_elev_layout.addWidget(self.slider_elev)
        self.slider_elev_layout.addWidget(QLabel("{}".format(self.slider_elev.maximum())))

        # Table (Right)
        self.table = QTableWidget()
        header = self.table.horizontalHeader()
        header.setSectionResizeMode(QHeaderView.Stretch)

        # ComboBox (Right)
        self.combo = QComboBox()
        self.combo.addItems(["Wired", "Surface", "Triangular Surface", "Sphere"])

        # Right layout
        rlayout = QVBoxLayout()
        rlayout.setContentsMargins(1, 1, 1, 1)
        rlayout.addWidget(QLabel("Plot type:"))
        rlayout.addWidget(self.combo)
        rlayout.addWidget(self.table)

        # Left layout
        llayout = QVBoxLayout()
        rlayout.setContentsMargins(1, 1, 1, 1)
        llayout.addWidget(self.canvas, 88)
        llayout.addWidget(QLabel("Azimuth:"), 1)
        llayout.addLayout(self.slider_azim_layout, 5)
        llayout.addWidget(QLabel("Elevation:"), 1)
        llayout.addLayout(self.slider_elev_layout, 5)

        # Main layout
        layout = QHBoxLayout(self._main)
        layout.addLayout(llayout, 70)
        layout.addLayout(rlayout, 30)

        # Signal and Slots connections
        self.combo.currentTextChanged.connect(self.combo_option)
        self.slider_azim.valueChanged.connect(self.rotate_azim)
        self.slider_elev.valueChanged.connect(self.rotate_elev)

        # Initial setup
        self.plot_wire()
        self._ax.view_init(30, 30)
        self.slider_azim.setValue(30)
        self.slider_elev.setValue(30)
        self.fig.canvas.mpl_connect("button_release_event", self.on_click)

    # Matplotlib slot method
    def on_click(self, event):
        azim, elev = self._ax.azim, self._ax.elev
        self.slider_azim.setValue(azim + 180)
        self.slider_elev.setValue(elev + 180)

    # Utils methods

    def set_table_data(self, X, Y, Z):
        for i in range(len(X)):
            self.table.setItem(i, 0, QTableWidgetItem("{:.2f}".format(X[i])))
            self.table.setItem(i, 1, QTableWidgetItem("{:.2f}".format(Y[i])))
            self.table.setItem(i, 2, QTableWidgetItem("{:.2f}".format(Z[i])))

    def set_canvas_table_configuration(self, row_count, data):
        self.fig.set_canvas(self.canvas)
        self._ax = self.canvas.figure.add_subplot(projection="3d")

        self._ax.set_xlabel(self.column_names[0])
        self._ax.set_ylabel(self.column_names[1])
        self._ax.set_zlabel(self.column_names[2])

        self.table.setRowCount(row_count)
        self.table.setColumnCount(3)
        self.table.setHorizontalHeaderLabels(self.column_names)
        self.set_table_data(data[0], data[1], data[2])

    # Plot methods

    def plot_wire(self):
        # Data
        self.X, self.Y, self.Z = axes3d.get_test_data(0.03)

        self.set_canvas_table_configuration(len(self.X[0]), (self.X[0], self.Y[0], self.Z[0]))
        self._ax.plot_wireframe(self.X, self.Y, self.Z, rstride=10, cstride=10, cmap="viridis")
        self.canvas.draw()

    def plot_surface(self):
        # Data
        self.X, self.Y = np.meshgrid(np.linspace(-6, 6, 30), np.linspace(-6, 6, 30))
        self.Z = np.sin(np.sqrt(self.X ** 2 + self.Y ** 2))

        self.set_canvas_table_configuration(len(self.X[0]), (self.X[0], self.Y[0], self.Z[0]))
        self._ax.plot_surface(self.X, self.Y, self.Z,
                              rstride=1, cstride=1, cmap="viridis", edgecolor="none")
        self.canvas.draw()

    def plot_triangular_surface(self):
        # Data
        radii = np.linspace(0.125, 1.0, 8)
        angles = np.linspace(0, 2 * np.pi, 36, endpoint=False)[..., np.newaxis]
        self.X = np.append(0, (radii * np.cos(angles)).flatten())
        self.Y = np.append(0, (radii * np.sin(angles)).flatten())
        self.Z = np.sin(-self.X * self.Y)

        self.set_canvas_table_configuration(len(self.X), (self.X, self.Y, self.Z))
        self._ax.plot_trisurf(self.X, self.Y, self.Z, linewidth=0.2, antialiased=True)
        self.canvas.draw()

    def plot_sphere(self):
        # Data
        u = np.linspace(0, 2 * np.pi, 100)
        v = np.linspace(0, np.pi, 100)
        self.X = 10 * np.outer(np.cos(u), np.sin(v))
        self.Y = 10 * np.outer(np.sin(u), np.sin(v))
        self.Z = 9 * np.outer(np.ones(np.size(u)), np.cos(v))

        self.set_canvas_table_configuration(len(self.X), (self.X[0], self.Y[0], self.Z[0]))
        self._ax.plot_surface(self.X, self.Y, self.Z)
        self.canvas.draw()

    # Slots

    @Slot()
    def combo_option(self, text):
        if text == "Wired":
            self.plot_wire()
        elif text == "Surface":
            self.plot_surface()
        elif text == "Triangular Surface":
            self.plot_triangular_surface()
        elif text == "Sphere":
            self.plot_sphere()

    @Slot()
    def rotate_azim(self, value):
        self._ax.view_init(self._ax.elev, value)
        self.fig.set_canvas(self.canvas)
        self.canvas.draw()

    @Slot()
    def rotate_elev(self, value):
        self._ax.view_init(value, self._ax.azim)
        self.fig.set_canvas(self.canvas)
        self.canvas.draw()
Ejemplo n.º 5
0
class _InputHeader(QGroupBox):
    def __init__(self, parent, header):
        super().__init__(parent)
        self.header = header
        self.header_index, _ = self.parent().table.model_c.metadata_c.get_header_meta(self.header["name"])

        self.setStyleSheet(styles.filter_line_edit)

        # LAYOUTS
        self.grid = QGridLayout()
        self.v_layout = QVBoxLayout()
        self.h_layout = QHBoxLayout()

        # FIELDS
        self.header_label = QLabel(f'{self.header["name"]} : ', self)
        self.header_label.setFixedWidth(100)

        self.input = QLineEdit(self)
        self.input.setMaxLength(self.header["data_type"]["max_value"])
        self.input.setPlaceholderText(str(self.parent().table.model_c.get_common_values(header["name"])))

        self.exact = QCheckBox("Exact", self)
        self.exact.setToolTip(f"Value in '{self.header['name']}' must be exacly '{self.input.text()}'")
        self.exact.stateChanged.connect(self.exact_checked)

        # SLIDER SET UP
        self.slider = None

        if self.header["data_type"]["type"] == "int":
            self.slider = QSlider(Qt.Horizontal, self)
            (self.slider.min_v, self.slider.max_v) = self.parent().table.get_min_max(self.header["name"])
            self.slider.setMinimum(self.slider.min_v)
            self.slider.setMaximum(self.slider.max_v)
            self.slider.valueChanged.connect(self.slider_value_changed)
            self.slider.hint = QLabel(f'{self.slider.minimum()} - {self.slider.value()}', self)

        # SET UP
        self.h_layout.addWidget(self.input)
        self.h_layout.addWidget(self.exact)

        self.v_layout.addLayout(self.h_layout)
        if self.slider is not None:
            self.v_layout.addWidget(self.slider.hint)
            self.v_layout.addWidget(self.slider)

        self.grid.addWidget(self.header_label, 0, 0)
        self.grid.addLayout(self.v_layout, 0, 1)

        self.setLayout(self.grid)

    def get_condition(self):
        if self.input.text() == "" and self.slider is None:
            return None

        if self.slider is not None:
            if self.input.text() == "" and \
                    (self.slider.value() == self.slider.maximum() or
                     self.slider.value() == self.slider.minimum()):
                return None

        return {
            "header_name": self.header["name"],
            "value": self.input.text(),
            "exact": self.exact.isChecked(),
            "header_meta": {
                "index": self.header_index,
                "meta": self.header
            },
            "value_additional_info": {
                "contains": not self.exact.isChecked(),
                "min_value": self.slider.min_v if self.slider is not None else "",
                "max_value": self.slider.value() if self.slider is not None else ""
            }
        }

    def exact_checked(self):
        if self.slider is None:
            return
        self.slider.hide() if self.exact.isChecked() else self.slider.show()

    def slider_value_changed(self):
        self.slider.hint.setText(f'{self.slider.minimum()} - {self.slider.value()}')
Ejemplo n.º 6
0
class ImageSeriesToolbar(QWidget):
    def __init__(self, name, parent=None):
        super(ImageSeriesToolbar, self).__init__(parent)

        self.ims = HexrdConfig().imageseries(name)
        self.slider = None
        self.frame = None
        self.layout = None
        self.widget = None

        self.show = False
        self.name = name

        self.create_widget()
        self.set_range()

        self.setup_connections()

    def setup_connections(self):
        self.slider.valueChanged.connect(self.val_changed)
        self.slider.valueChanged.connect(self.frame.setValue)
        self.frame.valueChanged.connect(self.slider.setSliderPosition)

    def create_widget(self):
        self.slider = QSlider(Qt.Horizontal, self.parent())
        self.frame = QSpinBox(self.parent())

        self.widget = QWidget(self.parent())

        self.layout = QGridLayout(self.widget)
        self.layout.addWidget(self.slider, 0, 0, 1, 9)
        self.layout.addWidget(self.frame, 0, 9, 1, 1)

        self.widget.setLayout(self.layout)

        if self.ims and len(self.ims) > 1:
            self.show = True
        self.widget.setVisible(self.show)

    def set_range(self, current_tab=False):
        if self.ims:
            size = len(self.ims) - 1
            if (not size or not current_tab) and self.show:
                self.show = False
            elif size and not self.show and current_tab:
                self.show = True
            self.widget.setVisible(self.show)
            self.slider.setMinimumWidth(self.parent().width() / 2)
            if not size == self.slider.maximum():
                self.slider.setMaximum(size)
                self.frame.setMaximum(size)
                self.slider.setValue(0)
                self.frame.setValue(self.slider.value())
        else:
            self.show = False
            self.widget.setVisible(self.show)

    def update_range(self, current_tab):
        self.ims = HexrdConfig().imageseries(self.name)
        self.set_range(current_tab)

        if self.slider.value() != HexrdConfig().current_imageseries_idx:
            self.val_changed(self.slider.value())

    def update_name(self, name):
        if not name == self.name:
            self.name = name

    def set_visible(self, b=False):
        self.widget.setVisible(b and len(self.ims) > 1)

    def val_changed(self, pos):
        self.parent().change_ims_image(pos)