Пример #1
0
class Window(QLabel):

    def __init__(self, parent = None):
    
        QLabel.__init__(self, parent)
        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.origin = QPoint()
        self.end = QPoint()
        self.title = 'Select the region of interest and close the window'
        self.setWindowTitle(self.title)
        
    def mousePressEvent(self, event):
    
        if event.button() == Qt.LeftButton:
        
            self.origin = QPoint(event.pos())
            self.rubberBand.setGeometry(QRect(self.origin, QSize()))
            self.rubberBand.show()
    
    def mouseMoveEvent(self, event):
    
        if not self.origin.isNull():
            self.rubberBand.setGeometry(QRect(self.origin, event.pos()).normalized())
    
    def mouseReleaseEvent(self, event):
    
        if event.button() == Qt.LeftButton:
            #self.rubberBand.hide()
            self.end = QPoint(event.pos())
Пример #2
0
class QExampleLabel(QLabel):
    def __init__(self, parentQWidget=None):
        super(QExampleLabel, self).__init__(parentQWidget)
        self.initUI()

    def initUI(self):
        self.setPixmap(QtGui.QPixmap('input.png'))

    def mousePressEvent(self, eventQMouseEvent):
        self.originQPoint = eventQMouseEvent.pos()
        self.currentQRubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.currentQRubberBand.setGeometry(
            QtCore.QRect(self.originQPoint, QtCore.QSize()))
        self.currentQRubberBand.show()

    def mouseMoveEvent(self, eventQMouseEvent):
        self.currentQRubberBand.setGeometry(
            QtCore.QRect(self.originQPoint,
                         eventQMouseEvent.pos()).normalized())

    def mouseReleaseEvent(self, eventQMouseEvent):
        self.currentQRubberBand.hide()
        currentQRect = self.currentQRubberBand.geometry()
        self.currentQRubberBand.deleteLater()
        cropQPixmap = self.pixmap().copy(currentQRect)
        cropQPixmap.save('output.png')
Пример #3
0
class Label(QtWidgets.QLabel):
    def __init__(self):
        super().__init__()
        self.origin = QPoint()
        self.rubberBand = None


#    def paintEvent(self, event):
#        qp = QtGui.QPainter(self)
#        br = QtGui.QBrush(QtGui.QColor(100, 10, 10, 40))
#        qp.setBrush(br)
#        qp.drawRect(QtCore.QRect(self.begin, self.end))

    def mousePressEvent(self, event):
        super(Label, self).mousePressEvent(event)
        self.origin = event.pos()

        if not self.rubberBand:
            self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
            print("Rubber!")
        self.rubberBand.setGeometry(QRect(self.origin, QSize()))
        self.rubberBand.show()

        #self.update()

    def mouseMoveEvent(self, event):
        self.rubberBand.setGeometry(
            QRect(self.origin, event.pos()).normalized())

    def mouseReleaseEvent(self, event):
        if self.rubberBand:
            self.rubberBand.hide()
Пример #4
0
class Window(QLabel):
    def __init__(self, pixmap, parent=None):
        QLabel.__init__(self, parent)
        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.origin = QPoint()
        self.pixmap = pixmap

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.origin = QPoint(event.pos())
            self.rubberBand.setGeometry(QRect(self.origin, QSize()))
            self.rubberBand.show()

    def mouseMoveEvent(self, event):
        if not self.origin.isNull():
            self.rubberBand.setGeometry(
                QRect(self.origin, event.pos()).normalized())

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.rubberBand.hide()
            print(self.rubberBand.geometry())

    def resizeEvent(self, event):
        self.updateScreenshotLabel()
        # scaledSize = self.pixmap.size()
        # scaledSize.scale(self.screenshotLabel.size(), Qt.KeepAspectRatio)
        # if not self.screenshotLabel.pixmap() or scaledSize != self.screenshotLabel.pixmap().size():
        #     self.updateScreenshotLabel()

    def updateScreenshotLabel(self):
        self.setPixmap(
            self.pixmap.scaled(self.size(), Qt.KeepAspectRatio,
                               Qt.SmoothTransformation))
Пример #5
0
class Label(QLabel):
    selection_changed = pyqtSignal(QRect, name="selectionChanged")

    def __init__(self):
        QLabel.__init__(self)
        self.rb = QRubberBand(QRubberBand.Rectangle, self)
        self.setMouseTracking(True)

    def mousePressEvent(self, event: QMouseEvent):
        self.origin = event.pos()
        self.rb.setGeometry(QRect(self.origin, QSize()))
        self.rb.show()
        QLabel.mousePressEvent(self, event)

    def mouseMoveEvent(self, event: QMouseEvent):
        if self.rb.isVisible():
            self.rb.setGeometry(
                QRect(self.origin, event.pos()).normalized())
        QWidget.mouseMoveEvent(self, event)

    def mouseReleaseEvent(self, event):
        if self.rb.isVisible():
            self.rb.hide()
        self.selection_changed.emit(self.rb.geometry())
        QLabel.mouseReleaseEvent(self, event)
Пример #6
0
class WidgetPicker(QWidget):
    """Widget for letting user point at another widget."""

    selected = Signal()

    def __init__(self):
        super(WidgetPicker, self).__init__()
        self.band = QRubberBand(QRubberBand.Rectangle)
        self.setMouseTracking(True)
        self.el = QEventLoop()

    def mousePressEvent(self, ev):
        self.el.quit()
        self.widget = QApplication.widgetAt(ev.globalPos())
        self.band.hide()

    def mouseMoveEvent(self, ev):
        widget = QApplication.widgetAt(ev.globalPos())
        if widget:
            rect = widget.frameGeometry()
            if widget.parent():
                rect.moveTo(widget.parent().mapToGlobal(rect.topLeft()))
            self.band.setGeometry(rect)
            self.band.show()
        else:
            self.band.hide()

    def run(self):
        self.grabMouse()
        try:
            self.el.exec_()
        finally:
            self.releaseMouse()
        return self.widget
Пример #7
0
class SelectAreaWidget(QLabel):
    areaSelected = pyqtSignal()

    def __init__(self):
        super(SelectAreaWidget, self).__init__()
        self.rubberBand = None
        pixmap = QApplication.primaryScreen().grabWindow(0)
        self.setPixmap(pixmap)
        self.showFullScreen()
        self.show()

    def mousePressEvent(self, event):
        if event.button() == Qt.RightButton:
            if self.rubberBand:
                self.rubberBand.hide()
            self.close()
        if event.button() == Qt.LeftButton:
            self.origin = event.pos()
            if not self.rubberBand:
                self.rubberBand = QRubberBand(QRubberBand.Rectangle, None)
            self.rubberBand.setGeometry(QRect(self.origin, QSize()))
            self.rubberBand.show()

    def mouseMoveEvent(self, event):
        if self.rubberBand:
            self.rubberBand.setGeometry(
                QRect(self.origin, event.pos()).normalized())

    def mouseReleaseEvent(self, event):
        if self.rubberBand:
            self.destination = event.pos()
            self.areaSelected.emit()
Пример #8
0
class MiniMapGraphicsView(QGraphicsView):
    def __init__(self, parent):
        super().__init__(parent)

        self._drag_start_pos = None

        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.setFixedSize(200, 200)
        self.viewport().setFixedSize(self.contentsRect().size())
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setInteractive(False)
        self.setFocusProxy(parent)

        self.band = QRubberBand(QRubberBand.Rectangle, self)
        self.band.hide()

    def centerOn(self, pos):
        if self.band.isVisible():
            self.parent().centerOn(self.mapToScene(pos))
            rect = self.band.geometry()
            rect.moveCenter(pos)
            self.band.setGeometry(rect)

    def mousePressEvent(self, event):
        if self.band.isVisible() and event.button() == Qt.LeftButton:
            rect = self.band.geometry()
            if event.pos() in rect:
                self._drag_start_pos = event.pos()
            else:
                self.centerOn(event.pos())

    def mouseMoveEvent(self, event):
        if self.band.isVisible() and event.buttons() == Qt.MouseButtons(
                Qt.LeftButton) and self._drag_start_pos is not None:
            self.centerOn(event.pos())

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton and self.band.isVisible():
            self.viewport().unsetCursor()
            self._drag_start_pos = None

    def adjustRubberband(self):
        scene = self.scene()
        if scene is None:
            return

        rect = self.parent().mapToScene(self.parent().rect()).boundingRect()
        if not rect.contains(scene.sceneRect()):
            rect = self.mapFromScene(rect).boundingRect()
            self.band.setGeometry(rect)
            self.band.show()
        else:
            self.band.hide()

    def zoomToFit(self):
        self.fitInView(self.scene().sceneRect().adjusted(-20, -20, 20, 20),
                       Qt.KeepAspectRatio)
class QImageEdit(QLabel):
    def __init__(self, parentQWidget=None):
        super(QImageEdit, self).__init__(parentQWidget)
        self.rubberBand = None
        self.move_rubberBand = False
        self.rubberBand_offset = None
        self.originPoint = None

    def setImage(self, image: QPixmap):
        self.setPixmap(image)

    def getImage(self) -> QPixmap:
        if self.rubberBand is not None:
            currentRect = self.rubberBand.geometry()
            return self.pixmap().copy(currentRect)
        else:
            return self.pixmap()

    def clear(self):
        super(QImageEdit, self).clear()
        if self.rubberBand is not None:
            self.rubberBand.deleteLater()
        self.rubberBand = None
        self.move_rubberBand = False
        self.rubberBand_offset = None
        self.originPoint = None

    def mousePressEvent(self, event):
        self.originPoint = event.pos()

        if self.rubberBand is None:
            self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
            self.rubberBand.setGeometry(QRect(self.originPoint, QSize()))
            self.rubberBand.show()
        else:
            if self.rubberBand.geometry().contains(self.originPoint):
                self.rubberBand_offset = \
                    self.originPoint - self.rubberBand.pos()
                self.move_rubberBand = True
            else:
                self.rubberBand.hide()
                self.rubberBand.deleteLater()
                self.rubberBand = None
                self.move_rubberBand = False
                self.rubberBand_offset = None
                self.mousePressEvent(event)

    def mouseMoveEvent(self, event):
        newPoint = event.pos()
        if self.move_rubberBand:
            self.rubberBand.move(newPoint - self.rubberBand_offset)
        else:
            self.rubberBand.setGeometry(
                QRect(self.originPoint, newPoint).normalized())

    def mouseReleaseEvent(self, event):
        self.move_rubberBand = False
Пример #10
0
class SelectWidget(QWidget, Ui_Form2):

    select = [0,0,0,0]

    def __init__(self, parent=None):
        super(SelectWidget, self).__init__(parent)
        self.setWindowOpacity(0.5)
        self.setupUi(self)
        desktop = QtWidgets.QDesktopWidget()
        self.resize(desktop.availableGeometry().width(), desktop.availableGeometry().height())
        self.rubberband = QRubberBand(
            QRubberBand.Rectangle, self)
        self.setMouseTracking(True)

    def mousePressEvent(self, event):
        self.select[0] = event.screenPos().x()
        self.select[1] = event.screenPos().y()
        self.origin = event.pos()
        self.rubberband.setGeometry(
            QtCore.QRect(self.origin, QtCore.QSize()))
        self.rubberband.show()
        QWidget.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        if self.rubberband.isVisible():
            self.rubberband.setGeometry(
                QtCore.QRect(self.origin, event.pos()).normalized())
        QWidget.mouseMoveEvent(self, event)

    def mouseReleaseEvent(self, event):
        self.select[2] = event.screenPos().x()
        self.select[3] = event.screenPos().y()
        if self.rubberband.isVisible():
            self.rubberband.hide()
            rect = self.rubberband.geometry()

        # ポインタ座標を左上→右下に揃える
        if self.select[0] > self.select[2]:
            tmp = self.select[0]
            self.select[0] = self.select[2]
            self.select[2] = tmp
        if self.select[1] > self.select[3]:
            tmp = self.select[1]
            self.select[1] = self.select[3]
            self.select[3] = tmp
        # 選択した面積がゼロの場合は何もしないで関数を終わる
        if self.select[0]==self.select[2] or self.select[1]==self.select[3]:
            QWidget.mouseReleaseEvent(self, event)
            self.close()
            return
        # ポインタ座標をメインウインドウに設定する
        area = ''
        for point in self.select:
            area = area + str(int(point)) + ','
        main_window.lineEdit.setText(area[0:-1])
        self.close()
        QWidget.mouseReleaseEvent(self, event)
Пример #11
0
class MyLabel(QLabel):
    def __init__(self, parent=None, func=None):

        self.func = func
        QLabel.__init__(self, parent)
        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.origin = QPoint()
        self.slitpos = 250
        self.focus = (333, 666, 333, 666)  #xs,xe,ys,ye
        self.geometry = (0, 0, 1000, 1000)  #x,y,w,h

    def paintEvent(self, event):
        QLabel.paintEvent(self, event)
        painter = QPainter(self)
        painter.setPen(Qt.red)
        x, y, w, h = self.geometry
        d = 20
        painter.drawLine(x + w // 2 - self.slitpos * w // 1000, y,
                         x + w // 2 - self.slitpos * w // 1000, y + h)
        painter.drawLine(x + w // 2 - self.slitpos * w // 1000 - d, y + h / 2,
                         x + w // 2 - self.slitpos * w // 1000, y + h / 2 - d)
        painter.drawLine(x + w // 2 - self.slitpos * w // 1000 - d, y + h / 2,
                         x + w // 2 - self.slitpos * w // 1000, y + h / 2 + d)
        painter.drawLine(x + w // 2 + self.slitpos * w // 1000, y,
                         x + w // 2 + self.slitpos * w // 1000, y + h)
        painter.drawLine(x + w // 2 + self.slitpos * w // 1000 + d, y + h // 2,
                         x + w // 2 + self.slitpos * w // 1000, y + h // 2 - d)
        painter.drawLine(x + w // 2 + self.slitpos * w // 1000 + d, y + h // 2,
                         x + w // 2 + self.slitpos * w // 1000, y + h // 2 + d)
        painter.setPen(Qt.green)
        painter.drawRect(x + w * self.focus[0] // 1000,
                         y + h * self.focus[2] // 1000,
                         w * (self.focus[1] - self.focus[0]) // 1000,
                         h * (self.focus[3] - self.focus[2]) // 1000)

    def mousePressEvent(self, event):

        if event.button() == Qt.LeftButton:

            self.origin = QPoint(event.pos())
            self.rubberBand.setGeometry(QRect(self.origin, QSize()))
            self.rubberBand.show()

    def mouseMoveEvent(self, event):

        if not self.origin.isNull():
            self.rubberBand.setGeometry(
                QRect(self.origin, event.pos()).normalized())

    def mouseReleaseEvent(self, event):

        if event.button() == Qt.LeftButton:
            self.rubberBand.hide()
            self.region = QRect(self.origin, event.pos()).normalized()
            if self.func is not None:
                self.func(self.region)
Пример #12
0
class ImageView(QGraphicsView):
    def __init__(self, parent=None):
        QGraphicsView.__init__(self, parent)

        self.go_prev_img = parent.go_prev_img
        self.go_next_img = parent.go_next_img

        pal = self.palette()
        pal.setColor(self.backgroundRole(), Qt.black)
        self.setPalette(pal)
        self.setFrameShape(QFrame.NoFrame)

    def mousePressEvent(self, event):
        """Go to the next / previous image, or be able to drag the image with a hand."""
        if event.button() == Qt.LeftButton:
            x = event.x()
            if x < 100:
                self.go_prev_img()
            elif x > self.width() - 100:
                self.go_next_img()
            else:
                self.setDragMode(QGraphicsView.ScrollHandDrag)
        QGraphicsView.mousePressEvent(self, event)

    def mouseReleaseEvent(self, event):
        self.setDragMode(QGraphicsView.NoDrag)
        QGraphicsView.mouseReleaseEvent(self, event)

    def zoom(self, zoomratio):
        self.scale(zoomratio, zoomratio)

    def wheelEvent(self, event):
        zoomratio = 1.1
        if event.angleDelta().y() < 0:
            zoomratio = 1.0 / zoomratio
        self.scale(zoomratio, zoomratio)

    def setup_crop(self, width, height):
        self.rband = QRubberBand(QRubberBand.Rectangle, self)
        coords = self.mapFromScene(0, 0, width, height)
        self.rband.setGeometry(QRect(coords.boundingRect()))
        self.rband.show()

    def crop_draw(self, x, y, width, height):
        coords = self.mapFromScene(x, y, width, height)
        self.rband.setGeometry(QRect(coords.boundingRect()))

    def get_coords(self):
        rect = self.rband.geometry()
        size = self.mapToScene(rect).boundingRect()
        x = int(size.x())
        y = int(size.y())
        width = int(size.width())
        height = int(size.height())
        return (x, y, width, height)
Пример #13
0
class ImageView(QGraphicsView):
    def __init__(self, parent=None):
        QGraphicsView.__init__(self, parent)

        self.go_prev_img = parent.go_prev_img
        self.go_next_img = parent.go_next_img

        pal = self.palette()
        pal.setColor(self.backgroundRole(), Qt.black)
        self.setPalette(pal)
        self.setFrameShape(QFrame.NoFrame)

    def mousePressEvent(self, event):
        """Go to the next / previous image, or be able to drag the image with a hand."""
        if event.button() == Qt.LeftButton:
            x = event.x()
            if x < 100:
                self.go_prev_img()
            elif x > self.width() - 100:
                self.go_next_img()
            else:
                self.setDragMode(QGraphicsView.ScrollHandDrag)
        QGraphicsView.mousePressEvent(self, event)

    def mouseReleaseEvent(self, event):
        self.setDragMode(QGraphicsView.NoDrag)
        QGraphicsView.mouseReleaseEvent(self, event)

    def zoom(self, zoomratio):
        self.scale(zoomratio, zoomratio)

    def wheelEvent(self, event):
        zoomratio = 1.1
        if event.angleDelta().y() < 0:
            zoomratio = 1.0 / zoomratio
        self.scale(zoomratio, zoomratio)

    def setup_crop(self, width, height):
        self.rband = QRubberBand(QRubberBand.Rectangle, self)
        coords = self.mapFromScene(0, 0, width, height)
        self.rband.setGeometry(QRect(coords.boundingRect()))
        self.rband.show()

    def crop_draw(self, x, y, width, height):
        coords = self.mapFromScene(x, y, width, height)
        self.rband.setGeometry(QRect(coords.boundingRect()))

    def get_coords(self):
        rect = self.rband.geometry()
        size = self.mapToScene(rect).boundingRect()
        x = int(size.x())
        y = int(size.y())
        width = int(size.width())
        height = int(size.height())
        return (x, y, width, height)
Пример #14
0
class MyLabel(QLabel):

    def __init__(self, parent = None, func=None):

        self.func = func
        QLabel.__init__(self, parent)
        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.origin = QPoint()
        self.slitpos = 250
        self.focus = (333,666,333,666)  #xs,xe,ys,ye
        self.geometry = (0,0,1000,1000) #x,y,w,h

    def paintEvent(self, event):
        QLabel.paintEvent(self, event)
        painter = QPainter(self)
        painter.setPen(Qt.red)
        x,y,w,h = self.geometry
        d = 20
        painter.drawLine(x+w//2-self.slitpos*w//1000,y,
                         x+w//2-self.slitpos*w//1000,y+h)
        painter.drawLine(x+w//2-self.slitpos*w//1000-d,y+h/2,
                         x+w//2-self.slitpos*w//1000,  y+h/2-d)
        painter.drawLine(x+w//2-self.slitpos*w//1000-d,y+h/2,
                         x+w//2-self.slitpos*w//1000,  y+h/2+d)
        painter.drawLine(x+w//2+self.slitpos*w//1000,y,
                         x+w//2+self.slitpos*w//1000,y+h)
        painter.drawLine(x+w//2+self.slitpos*w//1000+d,y+h//2,
                         x+w//2+self.slitpos*w//1000,  y+h//2-d)
        painter.drawLine(x+w//2+self.slitpos*w//1000+d,y+h//2,
                         x+w//2+self.slitpos*w//1000,  y+h//2+d)
        painter.setPen(Qt.green)
        painter.drawRect(x+w*self.focus[0]//1000,y+h*self.focus[2]//1000,w*(self.focus[1]-self.focus[0])//1000,h*(self.focus[3]-self.focus[2])//1000)
        
    def mousePressEvent(self, event):
    
        if event.button() == Qt.LeftButton:
        
            self.origin = QPoint(event.pos())
            self.rubberBand.setGeometry(QRect(self.origin, QSize()))
            self.rubberBand.show()
    
    def mouseMoveEvent(self, event):
    
        if not self.origin.isNull():
            self.rubberBand.setGeometry(QRect(self.origin, event.pos()).normalized())
    
    def mouseReleaseEvent(self, event):
    
        if event.button() == Qt.LeftButton:
            self.rubberBand.hide()
            self.region = QRect(self.origin, event.pos()).normalized()
            if self.func is not None:
                self.func(self.region)
Пример #15
0
class QLabelSelectable(QLabel):
    selectionFinished = pyqtSignal()

    def __init__(self, parent=None):
        QLabel.__init__(self, parent)
        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.origin = QPoint()

        self.startSelection = False
        self.endSelection = False

    def reset(self):
        self.startSelection = False
        self.endSelection = False

    def mousePressEvent(self, event):
        if event.button(
        ) == Qt.LeftButton and self.startSelection and not self.endSelection:
            self.origin = QPoint(event.pos())
        self.rubberBand.setGeometry(QRect(self.origin, QSize()))
        self.rubberBand.show()

    def mouseMoveEvent(self, event):
        if not self.origin.isNull(
        ) and self.startSelection and not self.endSelection:
            self.rubberBand.setGeometry(
                QRect(self.origin, event.pos()).normalized())

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton and self.startSelection:
            #print(self.rubberBand.geometry())

            self.drawRectangle()

            self.rubberBand.hide()

            self.endSelection = True

    def drawRectangle(self):
        # create painter instance with pixmap
        self.painterInstance = QPainter(self.pixmap())

        # set rectangle color and thickness
        self.penRectangle = QPen(Qt.red)
        self.penRectangle.setWidth(3)

        # draw rectangle on painter
        self.painterInstance.setPen(self.penRectangle)
        self.painterInstance.drawRect(self.rubberBand.geometry())
        self.selectionFinished.emit()
Пример #16
0
class ImageWidget(QLabel):

    areaSelected = pyqtSignal(float, float, float, float, QPixmap)

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

    def mousePressEvent(self, event):
        self.origin = event.pos()
        if self.rubberBand is None:
            self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.rubberBand.setGeometry(QRect(self.origin, QSize()))
        self.rubberBand.show()

    def mouseMoveEvent(self, event):
        self.rubberBand.setGeometry(QRect(self.origin, event.pos()).normalized())


    def mouseReleaseEvent(self, event):
        self.rubberBand.hide()
        zoreRect = QRect(self.origin, event.pos()).normalized()
        pixmapSize = self.pixmap().size()
        pixX1 = zoreRect.x()
        pixX2 = zoreRect.x() + zoreRect.width()
        pixY1 = zoreRect.y()
        pixY2 = zoreRect.y() + zoreRect.height()
        width  = pixmapSize.width()
        height = pixmapSize.height()

        x1 = pixX1/width 
        x1 = x1 if x1 >= 0.0 else 0.0
        x1 = x1 if x1 <= 1.0 else 1.0
        y1 = pixY1/height 
        y1 = y1 if y1 >= 0.0 else 0.0
        y1 = y1 if y1 <= 1.0 else 1.0
        x2 = pixX2/width 
        x2 = x2 if x2 >= 0.0 else 0.0
        x2 = x2 if x2 <= 1.0 else 1.0
        y2 = pixY2/height 
        y2 = y2 if y2 >= 0.0 else 0.0
        y2 = y2 if y2 <= 1.0 else 1.0

        rect = QRect(min(pixX1, pixX2), min(pixY1, pixY2), abs(pixX1- pixX2), abs(pixY1- pixY2))
        selectedImg = self.pixmap().copy(rect)
        
        self.areaSelected.emit(min(x1, x2), min(y1, y2), np.abs(x1-x2), np.abs(y1-y2), selectedImg)
Пример #17
0
class BandMixin(object):
	def __init__(self, **kwargs):
		super(BandMixin, self).__init__(**kwargs)
		self.__band = None

	def showBand(self, *geom):
		if not self.__band:
			self.__band = QRubberBand(QRubberBand.Rectangle, parent=self)
		self.__band.setGeometry(*geom)
		self.__band.show()

	def hideBand(self):
		if self.__band:
			self.__band.hide()
			self.__band.setParent(None)
			self.__band = None
Пример #18
0
class screen(QWidget):
    close_signal = pyqtSignal()

    def __init__(self, image_path):
        super().__init__()

        # self.close_signal.connect(self.ocr)
        self.image_path = image_path
        self.cut = False
        self.setMouseTracking(True)
        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        # print("=======")
        self.showFullScreen()
        self.setWindowOpacity(0.5)

    def mousePressEvent(self, event):
        self.cut = True
        self.start_x = event.x()
        self.start_y = event.y()

    def mouseReleaseEvent(self, event):
        self.cut = False
        r = self.rubberBand.geometry()
        print(r.getRect())

        self.setWindowOpacity(0)
        self.screen = QApplication.primaryScreen()
        screenshot = self.screen.grabWindow(QApplication.desktop().winId(),
                                            r.x(), r.y(), r.width(),
                                            r.height())
        screenshot.save(self.image_path)
        # screenshot.save(r"C:\temp\png\a.jpg")
        # text = pytesseract.image_to_string(self.image_path)
        # print(text)
        self.close_signal.emit()
        self.close()

    def mouseMoveEvent(self, event):

        if self.cut:
            end_x = event.x()
            end_y = event.y()

            self.rect = QRect(QPoint(self.start_x, self.start_y),
                              QPoint(end_x, end_y))
            self.rubberBand.setGeometry(self.rect)
            self.rubberBand.show()
Пример #19
0
class TimeView(QGraphicsView):

    time_clicked = pyqtSignal(float)
    time_selected = pyqtSignal(float, float)

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.initialClick = QPoint()
        self.selectionBand = QRubberBand(QRubberBand.Rectangle, self)
        self.selecting = False

    def mouseReleaseEvent(self, event):
        clicked_x = self.mapToScene(event.pos()).x()
        self.selectionBand.hide()
        if clicked_x == self.mapToScene(self.initialClick).x():
            self.time_clicked.emit(clicked_x)
        else:
            if self.initialClick.x() < clicked_x:
                self.time_selected.emit(
                    self.mapToScene(self.initialClick).x(), clicked_x)
            else:
                self.time_selected.emit(clicked_x,
                                        self.mapToScene(self.initialClick).x())

        self.selecting = False

    def mousePressEvent(self, event):
        self.selecting = True
        self.initialClick = event.pos()
        self.selectionBand.setGeometry(
            QRect(self.initialClick.x(), 0, 1, self.height()))
        self.selectionBand.show()

    def mouseMoveEvent(self, event):
        if self.selecting:
            current_pos = event.pos()
            if current_pos.x() < self.initialClick.x():
                start_x = current_pos.x()
                width = self.initialClick.x() - start_x
            else:
                start_x = self.initialClick.x()
                width = current_pos.x() - self.initialClick.x()
            self.selectionBand.setGeometry(
                QRect(start_x, 0, width, self.height()))
Пример #20
0
class PageScrollArea(QScrollArea):
    reachbottom = pyqtSignal()
    reachtop = pyqtSignal()
    areaSelected = pyqtSignal(QRect)

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

    def wheelEvent(self, event):
        super().wheelEvent(event)
        if self.verticalScrollBar().value() == self.verticalScrollBar(
        ).maximum() and event.angleDelta().y() == -120:
            self.reachbottom.emit()

        if self.verticalScrollBar().value() == 0 and event.angleDelta().y(
        ) == 120:
            self.reachtop.emit()

    def mousePressEvent(self, event):
        self.rubberorigin = event.pos()

        self.rubberband = QRubberBand(QRubberBand.Rectangle, self)
        self.rubberband.setGeometry(QRect(self.rubberorigin, QSize()))
        self.rubberband.show()
      

    def mouseReleaseEvent(self, event):
        rect = QRect(self.rubberband.pos(), self.rubberband.size())
        self.areaSelected.emit(rect)
        self.rubberband.hide()

    def mouseMoveEvent(self, event):
        super().mouseMoveEvent(event)
        self.rubberband.setGeometry(
            QRect(self.rubberorigin, event.pos()).normalized())

    def keyPressEvent(self, event):
        super().keyPressEvent(event)
        if self.verticalScrollBar().value() == self.verticalScrollBar(
        ).maximum() and (event.key() == 16777237 or event.key() == 16777239):
            self.reachbottom.emit()
        if self.verticalScrollBar().value() == 0 and (
                event.key() == 16777235 or event.key() == 16777238):
            self.reachtop.emit()
Пример #21
0
class Image_Display(RawImageWidget, QWidget):
    def __init__(self, parent=None, **kargs):
        RawImageWidget.__init__(self, parent=parent, scaled=True)
        super(QWidget, self).__init__(parent)
        self.setWindowTitle("image")
        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.mousePressPosition = QPoint(0, 0)
        self.mouseReleasePosition = QPoint(0, 0)
        self.clientCallback = None
        self.mousePressed = False
        self.okToClose = False
        self.setGeometry(QRect(10, 300, 600, 600))

    def closeEvent(self, event):
        if not self.okToClose:
            self.hide()
            return

    def display(self, image, pixelLevels):
        self.setImage(image, levels=pixelLevels)
        self.show()

    def mousePressEvent(self, event):
        self.mousePressPosition = QPoint(event.pos())
        self.rubberBand.setGeometry(QRect(self.mousePressPosition, QSize()))
        self.rubberBand.show()
        self.mousePressed = True

    def mouseMoveEvent(self, event):
        if not self.mousePressed: return
        self.rubberBand.setGeometry(
            QRect(self.mousePressPosition, event.pos()).normalized())

    def mouseReleaseEvent(self, event):
        if not self.mousePressed: return
        self.mouseReleasePosition = QPoint(event.pos())
        if not self.clientCallback == None:
            self.clientCallback(self.mousePressPosition,
                                self.mouseReleasePosition)
        self.rubberBand.hide()
        self.mousePressed = False

    def clientReleaseEvent(self, clientCallback):
        self.clientCallback = clientCallback
Пример #22
0
class Window(QLabel):
    def __int__(self, parent=None):
        QLabel.__init__(self, parent)

        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.origin = QPoint()

    def mousePressEvent(self, event: QMouseEvent):
        if event.button() == Qt.LeftButton:
            self.origin = QPoint(event.pos())
            self.rubberBand.setGeometry(QRect(self.origin, QSize()))
            self.rubberBand.show()

    def mouseMoveEvent(self, event: QMouseEvent):
        if not self.origin.isNull():
            self.rubberBand.setGeometry(
                QRect(self.origin, event.pos()).normalized())

    def mouseReleaseEvent(self, event: QMouseEvent):
        if event.button() == Qt.LeftButton:
            self.rubberBand.hide()
Пример #23
0
class ImageLabel(QLabel):

    refresh = pyqtSignal()

    def __init__(self, parent=None):

        QLabel.__init__(self, parent)
        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.origin = QPoint()
        self.coords = (0, 0, 0, 0)

    def mousePressEvent(self, event):

        if event.button() == Qt.LeftButton:

            self.origin = QPoint(event.pos())
            self.rubberBand.setGeometry(QRect(self.origin, QSize()))
            self.rubberBand.show()

    def mouseMoveEvent(self, event):

        if not self.origin.isNull():
            self.rubberBand.setGeometry(
                QRect(self.origin, event.pos()).normalized())

    def mouseReleaseEvent(self, event):

        if event.button() == Qt.LeftButton:
            #self.rubberBand.hide()

            x0 = self.origin.x()
            x1 = event.pos().x()
            y0 = self.origin.y()
            y1 = event.pos().y()

            self.coords = (x0, x1, y0, y1)
            self.refresh.emit()

    def getCoords(self):
        return self.coords
Пример #24
0
class Image(QLabel):
    # taken from https://wiki.python.org/moin/PyQt/Selecting%20a%20region%20of%20a%20widget
    def __init__(self, parent=None):
        QLabel.__init__(self, parent)
        self.selection = QRubberBand(QRubberBand.Rectangle, self)
        self.selection_origin = None
        self.selection_end = None
        self.image_path = None

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.selection_origin = QPoint(event.pos())
            self.selection.setGeometry(QRect(self.selection_origin, QSize()))
            self.selection.show()

    def mouseMoveEvent(self, event):
        if not self.selection_origin.isNull():
            self.selection.setGeometry(QRect(self.selection_origin, event.pos()).normalized())

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.selection_end = QPoint(event.pos())
Пример #25
0
class Mylabel(QLabel):
    def __init__(self, parent=None):
        super(Mylabel, self).__init__(parent)
        self.rubber = None
        self.origin = None
        self.parent = parent

    def mousePressEvent(self, a0: QtGui.QMouseEvent) -> None:
        super().mousePressEvent(a0)
        self.origin = a0.pos()
        print(self.origin)

        if self.rubber is None:
            self.rubber = QRubberBand(QRubberBand.Line, self)
        self.rubber.setGeometry(QRect(self.origin, QSize()))
        self.rubber.show()

    def mouseMoveEvent(self, a0: QtGui.QMouseEvent) -> None:
        super().mouseMoveEvent(a0)
        if self.rubber:
            self.rubber.setGeometry(QRect(self.origin, a0.pos()).normalized())

    def mouseReleaseEvent(self, a0: QtGui.QMouseEvent) -> None:
        super().mouseReleaseEvent(a0)
Пример #26
0
class VideoArea(QLabel):
    def __init__(self, parent=None, main=None):
        QLabel.__init__(self, parent)
        self.selection = QRubberBand(QRubberBand.Rectangle, self)
        self.main = main

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:

            position = QPoint(event.pos())
            if self.selection.isVisible():
                if (self.upper_left - position).manhattanLength() < 20:
                    self.mode = "UL"
                elif (self.lower_right - position).manhattanLength() < 20:
                    self.mode = "LR"
                else:
                    self.selection.hide()
            else:
                self.upper_left = position
                self.lower_right = position
                self.mode = "LR"
                self.selection.show()

    def mouseMoveEvent(self, event):
        if self.selection.isVisible():
            if self.mode == "LR":
                self.lower_right = QPoint(event.pos())
            elif self.mode == "UL":
                self.upper_left = QPoint(event.pos())
            self.selection.setGeometry(
                QRect(self.upper_left, self.lower_right).normalized())

    def mouseReleaseEvent(self, event):
        self.main.controller.set_coordinates(
            *self.selection.geometry().getCoords())
        self.selection.hide()
Пример #27
0
class App(QWidget):
    """Class App is the base class for the whole Screenshot Tool.
    """
    def __init__(self, save_path):
        super().__init__()

        self.save_path = save_path
        # Destkop Screenshot
        desktop_capture = ImageGrab.grab()
        desktop_capture.save('desktop_capture_temp.png')
        self.screen_size = QDesktopWidget().screenGeometry()
        QApplication.setOverrideCursor(QCursor(QtCore.Qt.CrossCursor))
        self.setWindowFlag(QtCore.Qt.WindowStaysOnTopHint)
        self.area_defined = False
        self.imageName = None
        self.selected_area_center = None
        # Start the Qt UI
        self.initUI()

    def initUI(self):
        """Init the Qt UI
        """
        # Create widget
        self.image_label = QLabel(self)
        # Screen capture of primary screen
        pixmap = QPixmap('desktop_capture_temp.png')
        # Set the image on the widget
        self.image_label.setPixmap(pixmap)
        # Transparent overlay
        self.overlay_label = QLabel(self)
        self.overlay_label.setStyleSheet(
            'background-color: rgba(0, 0, 0, 40);')
        self.overlay_label.setGeometry(self.screen_size)
        # Green X when clicking the offset
        self.offset_label = QLabel(self)
        self.offset_label.setText('<font color="green" size=5>x</font>')
        # Red Text when screen snipping is in progress
        self.help_text = QLabel(self)
        self.help_text.setGeometry(
            QtCore.QRect(((self.screen_size.width() - 350) / 2), 0, 350, 100))
        self.help_text.setText(
            '<font color="red" size=14>Screen Snipping In Progress...</font>')
        # Display app fullscreen
        self.showFullScreen()

    def keyPressEvent(self, keyPressed):
        """Handle key press events.
        Save image or close everything withouth save.
        """
        key = keyPressed.key()
        # If enter or return is pressed save the image and offset data and ask for image name
        if key == QtCore.Qt.Key_Return or key == QtCore.Qt.Key_Enter:
            self.hide()
            self.getImageName()

            if self.save_path == 'None':
                self.cropQPixmap.save(os.path.normpath(self.imageName +
                                                       '.png'))
            else:
                self.cropQPixmap.save(
                    os.path.normpath(self.save_path + '/' + self.imageName +
                                     '.png'))

            try:
                self.offset_pos
            # If there is not offset set. Set the offset to 0, 0
            except AttributeError:
                if self.save_path == 'None':
                    with open(os.path.normpath(self.imageName + '.json'),
                              'w') as outfile:
                        image_data = {'clickOffset': [0, 0]}
                        json.dump(image_data, outfile, indent=4)
                else:
                    with open(
                            os.path.normpath(self.save_path + '/' +
                                             self.imageName + '.json'),
                            'w') as outfile:
                        image_data = {'clickOffset': [0, 0]}
                        json.dump(image_data, outfile, indent=4)
            # If there is a offset set. Savet the offset.
            else:
                if self.save_path == 'None':
                    with open(os.path.normpath(self.imageName + '.json'),
                              'w') as outfile:
                        image_data = {
                            'clickOffset':
                            [self.offset_pos[0], self.offset_pos[1]]
                        }
                        json.dump(image_data, outfile, indent=4)
                else:
                    with open(
                            os.path.normpath(self.save_path + '/' +
                                             self.imageName + '.json'),
                            'w') as outfile:
                        image_data = {
                            'clickOffset':
                            [self.offset_pos[0], self.offset_pos[1]]
                        }
                        json.dump(image_data, outfile, indent=4)
            self.close()
        # If escape is pressed exit screenshot tool without saving
        elif key == QtCore.Qt.Key_Escape:
            self.close()

    def mousePressEvent(self, eventQMouseEvent):
        # If area is not defined for snipping, start the selection
        if self.area_defined == False:
            self.originQPoint = eventQMouseEvent.pos()
            self.currentQRubberBand = QRubberBand(QRubberBand.Rectangle, self)
            self.currentQRubberBand.setGeometry(
                QtCore.QRect(self.originQPoint, QtCore.QSize()))
            self.currentQRubberBand.show()
        # If are is defined for snipping, show the green x for the offset
        elif self.area_defined == True:
            self.offset_label.move((eventQMouseEvent.pos().x() -
                                    self.offset_label.geometry().width()),
                                   (eventQMouseEvent.pos().y() -
                                    self.offset_label.geometry().height()))
            click_location = [
                eventQMouseEvent.pos().x(),
                eventQMouseEvent.pos().y()
            ]
            self.offset_pos = [
                (click_location[0] - self.selected_area_center[0]),
                (click_location[1] - self.selected_area_center[1])
            ]

    def mouseMoveEvent(self, eventQMouseEvent):
        # If area not defined for snipping read the current mouse pointer position and redraw selection box
        if self.area_defined == False:
            self.currentQRubberBand.setGeometry(
                QtCore.QRect(self.originQPoint,
                             eventQMouseEvent.pos()).normalized())

    def mouseReleaseEvent(self, eventQMouseEvent):
        # If area is not defined crop the image to the defined selection box
        if self.area_defined == False:
            currentQRect = self.currentQRubberBand.geometry()
            self.selected_area_center = [
                currentQRect.center().x(),
                currentQRect.center().y()
            ]
            self.cropQPixmap = self.image_label.pixmap().copy(currentQRect)
            self.area_defined = True

    def getImageName(self):
        """Pop up box with text input for the user to enter the new image's name.
        """
        text, okPressed = QInputDialog.getText(self, "Get Image Name",
                                               "Type Image Name:",
                                               QLineEdit.Normal, "")
        if okPressed and text != '':
            self.imageName = text
Пример #28
0
class SlideViewer(QWidget):
    eventSignal = pyqtSignal(PyQt5.QtCore.QEvent)

    def __init__(self, parent: QWidget = None, viewer_top_else_left=True):
        super().__init__(parent)
        self.init_view()
        self.init_labels(word_wrap=viewer_top_else_left)
        self.init_layout(viewer_top_else_left)

    def init_view(self):
        self.scene = MyGraphicsScene()
        self.view = QGraphicsView()
        self.view.setScene(self.scene)
        self.view.setTransformationAnchor(QGraphicsView.NoAnchor)
        self.view.viewport().installEventFilter(self)

        self.rubber_band = QRubberBand(QRubberBand.Rectangle, self)
        self.mouse_press_view = QPoint()

        self.view.horizontalScrollBar().sliderMoved.connect(
            self.on_view_changed)
        self.view.verticalScrollBar().sliderMoved.connect(self.on_view_changed)
        self.scale_initializer_deffered_function = None
        self.slide_view_params = None
        self.slide_helper = None

    def init_labels(self, word_wrap):
        # word_wrap = True
        self.level_downsample_label = QLabel()
        self.level_downsample_label.setWordWrap(word_wrap)
        self.level_size_label = QLabel()
        self.level_size_label.setWordWrap(word_wrap)
        self.selected_rect_label = QLabel()
        self.selected_rect_label.setWordWrap(word_wrap)
        self.mouse_pos_scene_label = QLabel()
        self.mouse_pos_scene_label.setWordWrap(word_wrap)
        self.view_rect_scene_label = QLabel()
        self.view_rect_scene_label.setWordWrap(word_wrap)
        self.labels_layout = QVBoxLayout()
        self.labels_layout.setAlignment(Qt.AlignTop)
        self.labels_layout.addWidget(self.level_downsample_label)
        self.labels_layout.addWidget(self.level_size_label)
        self.labels_layout.addWidget(self.mouse_pos_scene_label)
        # self.labels_layout.addWidget(self.selected_rect_label)
        self.labels_layout.addWidget(self.view_rect_scene_label)

    def init_layout(self, viewer_top_else_left=True):
        main_layout = QVBoxLayout(
            self) if viewer_top_else_left else QHBoxLayout(self)
        main_layout.addWidget(self.view, )
        main_layout.addLayout(self.labels_layout)
        # main_layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(main_layout)

    """
    If you want to start view frome some point at some level, specify <level> and <level_rect> params. 
    level_rect : rect in dimensions of slide at level=level. If None - fits the whole size of slide
    """

    def load(self,
             slide_view_params: SlideViewParams,
             preffered_rects_count=2000,
             zoom_step=1.15):
        self.zoom_step = zoom_step
        self.slide_view_params = slide_view_params
        self.slide_helper = SlideHelper(slide_view_params.slide_path)

        self.slide_graphics = SlideGraphicsGroup(slide_view_params,
                                                 preffered_rects_count)
        self.scene.clear()
        self.scene.addItem(self.slide_graphics)

        if self.slide_view_params.level == -1 or self.slide_view_params.level is None:
            self.slide_view_params.level = self.slide_helper.get_max_level()

        self.slide_graphics.update_visible_level(self.slide_view_params.level)
        self.scene.setSceneRect(
            self.slide_helper.get_rect_for_level(self.slide_view_params.level))

        def scale_initializer_deffered_function():
            self.view.resetTransform()
            # print("size when loading: ", self.view.viewport().size())
            if self.slide_view_params.level_rect:
                # self.view.fitInView(QRectF(*self.slide_view_params.level_rect), Qt.KeepAspectRatioByExpanding)
                self.view.fitInView(QRectF(*self.slide_view_params.level_rect),
                                    Qt.KeepAspectRatio)
                # print("after fit: ", self.get_current_view_scene_rect())
            else:
                start_margins = QMarginsF(200, 200, 200, 200)
                start_image_rect_ = self.slide_helper.get_rect_for_level(
                    self.slide_view_params.level)
                self.view.fitInView(start_image_rect_ + start_margins,
                                    Qt.KeepAspectRatio)

        self.scale_initializer_deffered_function = scale_initializer_deffered_function

    def eventFilter(self, qobj: 'QObject', event: QEvent):
        self.eventSignal.emit(event)
        event_processed = False
        # print("size when event: ", event, event.type(), self.view.viewport().size())
        if isinstance(event, QShowEvent):
            """
            we need it deffered because fitInView logic depends on current viewport size. Expecting at this point widget is finally resized before being shown at first
            """
            if self.scale_initializer_deffered_function:
                # TODO labels start to occupy some space after view was already fitted, and labels will reduce size of viewport
                # self.update_labels()
                self.scale_initializer_deffered_function()
                self.on_view_changed()
                self.scale_initializer_deffered_function = None
        elif isinstance(event, QWheelEvent):
            event_processed = self.process_viewport_wheel_event(event)
            # we handle wheel event to prevent GraphicsView interpret it as scrolling
        elif isinstance(event, QMouseEvent):
            event_processed = self.process_mouse_event(event)

        return event_processed

    def process_viewport_wheel_event(self, event: QWheelEvent):
        # print("size when wheeling: ", self.view.viewport().size())
        zoom_in = self.zoom_step
        zoom_out = 1 / zoom_in
        zoom_ = zoom_in if event.angleDelta().y() > 0 else zoom_out
        self.update_scale(event.pos(), zoom_)
        event.accept()
        self.on_view_changed()
        return True

    def process_mouse_event(self, event: QMouseEvent):
        if self.slide_helper is None:
            return False

        if event.button() == Qt.MiddleButton:
            if event.type() == QEvent.MouseButtonPress:
                self.slide_graphics.update_grid_visibility(
                    not self.slide_graphics.slide_view_params.grid_visible)
                # items=self.scene.items()
                # QMessageBox.information(None, "Items", str(items))
                return True
            # self.update_scale(QPoint(), 1.15)
        elif event.button() == Qt.LeftButton:
            if event.type() == QEvent.MouseButtonPress:
                self.mouse_press_view = QPoint(event.pos())
                self.rubber_band.setGeometry(
                    QRect(self.mouse_press_view, QSize()))
                self.rubber_band.show()
                return True
            elif event.type() == QEvent.MouseButtonRelease:
                self.rubber_band.hide()
                self.remember_selected_rect_params()
                self.slide_graphics.update_selected_rect_0_level(
                    self.slide_view_params.selected_rect_0_level)
                self.update_labels()
                self.scene.invalidate()
                return True
        elif event.type() == QEvent.MouseMove:
            self.mouse_pos_scene_label.setText(
                "mouse_scene: " +
                point_to_str(self.view.mapToScene(event.pos())))
            if not self.mouse_press_view.isNull():
                self.rubber_band.setGeometry(
                    QRect(self.mouse_press_view, event.pos()).normalized())
            return True

        return False

    def remember_selected_rect_params(self):
        pos_scene = self.view.mapToScene(self.rubber_band.pos())
        rect_scene = self.view.mapToScene(
            self.rubber_band.rect()).boundingRect()
        downsample = self.slide_helper.get_downsample_for_level(
            self.slide_view_params.level)
        selected_qrectf_0_level = QRectF(pos_scene * downsample,
                                         rect_scene.size() * downsample)
        self.slide_view_params.selected_rect_0_level = selected_qrectf_0_level.getRect(
        )

    def update_scale(self, mouse_pos: QPoint, zoom):
        old_mouse_pos_scene = self.view.mapToScene(mouse_pos)
        old_view_scene_rect = self.view.mapToScene(
            self.view.viewport().rect()).boundingRect()

        old_level = self.get_best_level_for_scale(
            self.get_current_view_scale())
        old_level_downsample = self.slide_helper.get_downsample_for_level(
            old_level)
        new_level = self.get_best_level_for_scale(
            self.get_current_view_scale() * zoom)
        new_level_downsample = self.slide_helper.get_downsample_for_level(
            new_level)

        level_scale_delta = 1 / (new_level_downsample / old_level_downsample)

        r = old_view_scene_rect.topLeft()
        m = old_mouse_pos_scene
        new_view_scene_rect_top_left = (m - (m - r) / zoom) * level_scale_delta
        new_view_scene_rect = QRectF(
            new_view_scene_rect_top_left,
            old_view_scene_rect.size() * level_scale_delta / zoom)

        new_scale = self.get_current_view_scale(
        ) * zoom * new_level_downsample / old_level_downsample
        transform = QTransform().scale(new_scale, new_scale).translate(
            -new_view_scene_rect.x(), -new_view_scene_rect.y())

        new_rect = self.slide_helper.get_rect_for_level(new_level)
        self.scene.setSceneRect(new_rect)
        self.slide_view_params.level = new_level
        self.reset_view_transform()
        self.view.setTransform(transform, False)
        self.slide_graphics.update_visible_level(new_level)
        self.update_labels()

    def get_best_level_for_scale(self, scale):
        scene_width = self.scene.sceneRect().size().width()
        candidates = [0]
        for level in self.slide_helper.get_levels():
            w, h = self.slide_helper.get_level_size(level)
            if scene_width * scale <= w:
                candidates.append(level)
        best_level = max(candidates)
        return best_level

    def update_labels(self):
        level_downsample = self.slide_helper.get_downsample_for_level(
            self.slide_view_params.level)
        level_size = self.slide_helper.get_level_size(
            self.slide_view_params.level)
        self.level_downsample_label.setText(
            "level, downsample: {}, {:.0f}".format(
                self.slide_view_params.level, level_downsample))
        self.level_size_label.setText(
            "level_size: ({}, {})".format(*level_size))
        self.view_rect_scene_label.setText(
            "view_scene: ({:.0f},{:.0f},{:.0f},{:.0f})".format(
                *self.get_current_view_scene_rect().getRect()))
        if self.slide_view_params.selected_rect_0_level:
            self.selected_rect_label.setText(
                "selected rect (0-level): ({:.0f},{:.0f},{:.0f},{:.0f})".
                format(*self.slide_view_params.selected_rect_0_level))

    def on_view_changed(self):
        if self.scale_initializer_deffered_function is None and self.slide_view_params:
            self.slide_view_params.level_rect = self.get_current_view_scene_rect(
            ).getRect()
        self.update_labels()

    def reset_view_transform(self):
        self.view.resetTransform()
        self.view.horizontalScrollBar().setValue(0)
        self.view.verticalScrollBar().setValue(0)

    def get_current_view_scene_rect(self):
        return self.view.mapToScene(self.view.viewport().rect()).boundingRect()

    def get_current_view_scale(self):
        scale = self.view.transform().m11()
        return scale
Пример #29
0
class PieView(QAbstractItemView):
    def __init__(self, parent=None):
        super(PieView, self).__init__(parent)

        self.horizontalScrollBar().setRange(0, 0)
        self.verticalScrollBar().setRange(0, 0)

        self.margin = 8
        self.totalSize = 300
        self.pieSize = self.totalSize - 2 * self.margin
        self.validItems = 0
        self.totalValue = 0.0
        self.origin = QPoint()
        self.rubberBand = None

    def dataChanged(self, topLeft, bottomRight, roles):
        super(PieView, self).dataChanged(topLeft, bottomRight, roles)

        self.validItems = 0
        self.totalValue = 0.0

        for row in range(self.model().rowCount(self.rootIndex())):

            index = self.model().index(row, 1, self.rootIndex())
            value = self.model().data(index)

            if value is not None and value > 0.0:
                self.totalValue += value
                self.validItems += 1

        self.viewport().update()

    def edit(self, index, trigger, event):
        if index.column() == 0:
            return super(PieView, self).edit(index, trigger, event)
        else:
            return False

    def indexAt(self, point):
        if self.validItems == 0:
            return QModelIndex()

        # Transform the view coordinates into contents widget coordinates.
        wx = point.x() + self.horizontalScrollBar().value()
        wy = point.y() + self.verticalScrollBar().value()

        if wx < self.totalSize:
            cx = wx - self.totalSize / 2
            cy = self.totalSize / 2 - wy
            # positive cy for items above the center

            # Determine the distance from the center point of the pie chart.
            d = (cx**2 + cy**2)**0.5

            if d == 0 or d > self.pieSize / 2:
                return QModelIndex()

            # Determine the angle of the point.
            angle = (180 / math.pi) * math.acos(cx / d)
            if cy < 0:
                angle = 360 - angle

            # Find the relevant slice of the pie.
            startAngle = 0.0

            for row in range(self.model().rowCount(self.rootIndex())):

                index = self.model().index(row, 1, self.rootIndex())
                value = self.model().data(index)

                if value > 0.0:
                    sliceAngle = 360 * value / self.totalValue

                    if angle >= startAngle and angle < (startAngle +
                                                        sliceAngle):
                        return self.model().index(row, 1, self.rootIndex())

                    startAngle += sliceAngle

        else:
            itemHeight = QFontMetrics(self.viewOptions().font).height()
            listItem = int((wy - self.margin) / itemHeight)
            validRow = 0

            for row in range(self.model().rowCount(self.rootIndex())):

                index = self.model().index(row, 1, self.rootIndex())
                if self.model().data(index) > 0.0:

                    if listItem == validRow:
                        return self.model().index(row, 0, self.rootIndex())

                    # Update the list index that corresponds to the next valid
                    # row.
                    validRow += 1

        return QModelIndex()

    def isIndexHidden(self, index):
        return False

    def itemRect(self, index):
        if not index.isValid():
            return QRect()

        # Check whether the index's row is in the list of rows represented
        # by slices.

        if index.column() != 1:
            valueIndex = self.model().index(index.row(), 1, self.rootIndex())
        else:
            valueIndex = index

        if self.model().data(valueIndex) > 0.0:

            listItem = 0
            for row in range(index.row() - 1, -1, -1):
                if self.model().data(self.model().index(
                        row, 1, self.rootIndex())) > 0.0:
                    listItem += 1

            if index.column() == 0:

                itemHeight = QFontMetrics(self.viewOptions().font).height()
                return QRect(self.totalSize,
                             int(self.margin + listItem * itemHeight),
                             self.totalSize - self.margin, int(itemHeight))
            elif index.column() == 1:
                return self.viewport().rect()

        return QRect()

    def itemRegion(self, index):
        if not index.isValid():
            return QRegion()

        if index.column() != 1:
            return QRegion(self.itemRect(index))

        if self.model().data(index) <= 0.0:
            return QRegion()

        startAngle = 0.0
        for row in range(self.model().rowCount(self.rootIndex())):

            sliceIndex = self.model().index(row, 1, self.rootIndex())
            value = self.model().data(sliceIndex)

            if value > 0.0:
                angle = 360 * value / self.totalValue

                if sliceIndex == index:
                    slicePath = QPainterPath()
                    slicePath.moveTo(self.totalSize / 2, self.totalSize / 2)
                    slicePath.arcTo(self.margin, self.margin,
                                    self.margin + self.pieSize,
                                    self.margin + self.pieSize, startAngle,
                                    angle)
                    slicePath.closeSubpath()

                    return QRegion(slicePath.toFillPolygon().toPolygon())

                startAngle += angle

        return QRegion()

    def horizontalOffset(self):
        return self.horizontalScrollBar().value()

    def mousePressEvent(self, event):
        super(PieView, self).mousePressEvent(event)

        self.origin = event.pos()
        if not self.rubberBand:
            self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.rubberBand.setGeometry(QRect(self.origin, QSize()))
        self.rubberBand.show()

    def mouseMoveEvent(self, event):
        if self.rubberBand:
            self.rubberBand.setGeometry(
                QRect(self.origin, event.pos()).normalized())

        super(PieView, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        super(PieView, self).mouseReleaseEvent(event)

        if self.rubberBand:
            self.rubberBand.hide()

        self.viewport().update()

    def moveCursor(self, cursorAction, modifiers):
        current = self.currentIndex()

        if cursorAction in (QAbstractItemView.MoveLeft,
                            QAbstractItemView.MoveUp):

            if current.row() > 0:
                current = self.model().index(current.row() - 1,
                                             current.column(),
                                             self.rootIndex())
            else:
                current = self.model().index(0, current.column(),
                                             self.rootIndex())

        elif cursorAction in (QAbstractItemView.MoveRight,
                              QAbstractItemView.MoveDown):

            if current.row() < self.rows(current) - 1:
                current = self.model().index(current.row() + 1,
                                             current.column(),
                                             self.rootIndex())
            else:
                current = self.model().index(
                    self.rows(current) - 1, current.column(), self.rootIndex())

        self.viewport().update()
        return current

    def paintEvent(self, event):
        selections = self.selectionModel()
        option = self.viewOptions()
        state = option.state

        background = option.palette.base()
        foreground = QPen(option.palette.color(QPalette.WindowText))
        textPen = QPen(option.palette.color(QPalette.Text))
        highlightedPen = QPen(option.palette.color(QPalette.HighlightedText))

        painter = QPainter(self.viewport())
        painter.setRenderHint(QPainter.Antialiasing)

        painter.fillRect(event.rect(), background)
        painter.setPen(foreground)

        # Viewport rectangles
        pieRect = QRect(self.margin, self.margin, self.pieSize, self.pieSize)
        keyPoint = QPoint(self.totalSize - self.horizontalScrollBar().value(),
                          self.margin - self.verticalScrollBar().value())

        if self.validItems > 0:
            painter.save()
            painter.translate(pieRect.x() - self.horizontalScrollBar().value(),
                              pieRect.y() - self.verticalScrollBar().value())
            painter.drawEllipse(0, 0, self.pieSize, self.pieSize)
            startAngle = 0.0

            for row in range(self.model().rowCount(self.rootIndex())):

                index = self.model().index(row, 1, self.rootIndex())
                value = self.model().data(index)

                if value > 0.0:
                    angle = 360 * value / self.totalValue

                    colorIndex = self.model().index(row, 0, self.rootIndex())
                    color = self.model().data(colorIndex, Qt.DecorationRole)

                    if self.currentIndex() == index:
                        painter.setBrush(QBrush(color, Qt.Dense4Pattern))
                    elif selections.isSelected(index):
                        painter.setBrush(QBrush(color, Qt.Dense3Pattern))
                    else:
                        painter.setBrush(QBrush(color))

                    painter.drawPie(0, 0, self.pieSize, self.pieSize,
                                    int(startAngle * 16), int(angle * 16))

                    startAngle += angle

            painter.restore()

            keyNumber = 0

            for row in range(self.model().rowCount(self.rootIndex())):
                index = self.model().index(row, 1, self.rootIndex())
                value = self.model().data(index)

                if value > 0.0:
                    labelIndex = self.model().index(row, 0, self.rootIndex())

                    option = self.viewOptions()
                    option.rect = self.visualRect(labelIndex)
                    if selections.isSelected(labelIndex):
                        option.state |= QStyle.State_Selected
                    if self.currentIndex() == labelIndex:
                        option.state |= QStyle.State_HasFocus
                    self.itemDelegate().paint(painter, option, labelIndex)

                    keyNumber += 1

    def resizeEvent(self, event):
        self.updateGeometries()

    def rows(self, index):
        return self.model().rowCount(self.model().parent(index))

    def rowsInserted(self, parent, start, end):
        for row in range(start, end + 1):
            index = self.model().index(row, 1, self.rootIndex())
            value = self.model().data(index)

            if value is not None and value > 0.0:
                self.totalValue += value
                self.validItems += 1

        super(PieView, self).rowsInserted(parent, start, end)

    def rowsAboutToBeRemoved(self, parent, start, end):
        for row in range(start, end + 1):
            index = self.model().index(row, 1, self.rootIndex())
            value = self.model().data(index)

            if value is not None and value > 0.0:
                self.totalValue -= value
                self.validItems -= 1

        super(PieView, self).rowsAboutToBeRemoved(parent, start, end)

    def scrollContentsBy(self, dx, dy):
        self.viewport().scroll(dx, dy)

    def scrollTo(self, index, ScrollHint):
        area = self.viewport().rect()
        rect = self.visualRect(index)

        if rect.left() < area.left():
            self.horizontalScrollBar().setValue(
                self.horizontalScrollBar().value() + rect.left() - area.left())
        elif rect.right() > area.right():
            self.horizontalScrollBar().setValue(
                self.horizontalScrollBar().value() +
                min(rect.right() - area.right(),
                    rect.left() - area.left()))

        if rect.top() < area.top():
            self.verticalScrollBar().setValue(
                self.verticalScrollBar().value() + rect.top() - area.top())
        elif rect.bottom() > area.bottom():
            self.verticalScrollBar().setValue(
                self.verticalScrollBar().value() +
                min(rect.bottom() - area.bottom(),
                    rect.top() - area.top()))

    def setSelection(self, rect, command):
        # Use content widget coordinates because we will use the itemRegion()
        # function to check for intersections.

        contentsRect = rect.translated(
            self.horizontalScrollBar().value(),
            self.verticalScrollBar().value()).normalized()

        rows = self.model().rowCount(self.rootIndex())
        columns = self.model().columnCount(self.rootIndex())
        indexes = []

        for row in range(rows):
            for column in range(columns):
                index = self.model().index(row, column, self.rootIndex())
                region = self.itemRegion(index)
                if not region.intersect(QRegion(contentsRect)).isEmpty():
                    indexes.append(index)

        if len(indexes) > 0:
            firstRow = indexes[0].row()
            lastRow = indexes[0].row()
            firstColumn = indexes[0].column()
            lastColumn = indexes[0].column()

            for i in range(1, len(indexes)):
                firstRow = min(firstRow, indexes[i].row())
                lastRow = max(lastRow, indexes[i].row())
                firstColumn = min(firstColumn, indexes[i].column())
                lastColumn = max(lastColumn, indexes[i].column())

            selection = QItemSelection(
                self.model().index(firstRow, firstColumn, self.rootIndex()),
                self.model().index(lastRow, lastColumn, self.rootIndex()))
            self.selectionModel().select(selection, command)
        else:
            noIndex = QModelIndex()
            selection = QItemSelection(noIndex, noIndex)
            self.selectionModel().select(selection, command)

        self.update()

    def updateGeometries(self):
        self.horizontalScrollBar().setPageStep(self.viewport().width())
        self.horizontalScrollBar().setRange(
            0, max(0, 2 * self.totalSize - self.viewport().width()))
        self.verticalScrollBar().setPageStep(self.viewport().height())
        self.verticalScrollBar().setRange(
            0, max(0, self.totalSize - self.viewport().height()))

    def verticalOffset(self):
        return self.verticalScrollBar().value()

    def visualRect(self, index):
        rect = self.itemRect(index)
        if rect.isValid():
            return QRect(rect.left() - self.horizontalScrollBar().value(),
                         rect.top() - self.verticalScrollBar().value(),
                         rect.width(), rect.height())
        else:
            return rect

    def visualRegionForSelection(self, selection):
        region = QRegion()

        for span in selection:
            for row in range(span.top(), span.bottom() + 1):
                for col in range(span.left(), span.right() + 1):
                    index = self.model().index(row, col, self.rootIndex())
                    region += self.visualRect(index)

        return region
Пример #30
0
class ResizableRubberBand(QWidget):
    def __init__(self, parent=None):
        super(ResizableRubberBand, self).__init__(parent)

        self.draggable = True
        self.dragging_threshold = 0
        self.mousePressPos = None
        self.mouseMovePos = None
        self.borderRadius = 5

        self.setWindowFlags(Qt.SubWindow)
        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)

        self.grip2 = QSizeGrip(self)
        self.grip2.setFixedSize(15, 15)

        layout.addWidget(self.grip2, 0, Qt.AlignRight | Qt.AlignBottom)
        self.band = QRubberBand(QRubberBand.Rectangle, self)
        self.band.show()
        self.show()

    def resizeEvent(self, event):
        # Note: resizing from a top left grip creates loop
        rect = self.geometry()
        side = min(rect.width(), rect.height())

        self.band.setGeometry(0, 0, side, side)
        self.setGeometry(self.x(), self.y(), side, side)

    def paintEvent(self, event):
        # Get current window size
        window_size = self.size()
        qp = QPainter()
        qp.begin(self)
        qp.setRenderHint(QPainter.Antialiasing, True)

        side = min(window_size.width(), window_size.height())

        qp.drawRoundedRect(0, 0, window_size.width(), window_size.height(),
                           self.borderRadius, self.borderRadius)

        qp.end()

    def mousePressEvent(self, event):
        if self.draggable and event.button() == Qt.LeftButton:
            self.mousePressPos = event.globalPos()  # global
            self.mouseMovePos = event.globalPos() - self.pos()  # local
        super(ResizableRubberBand, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if self.draggable and event.buttons() & Qt.LeftButton:
            globalPos = event.globalPos()

            moved = globalPos - self.mousePressPos
            if moved.manhattanLength() > self.dragging_threshold:
                # Move when user drag window more than dragging_threshold
                diff = globalPos - self.mouseMovePos
                diffNew = QPoint(
                    max(
                        0,
                        min(
                            diff.x(),
                            self.parent().geometry().width() -
                            self.size().width())),
                    max(
                        0,
                        min(
                            diff.y(),
                            self.parent().geometry().height() -
                            self.size().height())))
                self.move(diffNew)
                self.mouseMovePos = globalPos - self.pos()

            super(ResizableRubberBand, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        if self.mousePressPos is not None:
            if event.button() == Qt.LeftButton:
                moved = event.globalPos() - self.mousePressPos
                if moved.manhattanLength() > self.dragging_threshold:
                    # Do not call click event or so on
                    event.ignore()
                self.mousePressPos = None
        super(ResizableRubberBand, self).mouseReleaseEvent(event)
Пример #31
0
class PieView(QAbstractItemView):
    def __init__(self, parent=None):
        super(PieView, self).__init__(parent)

        self.horizontalScrollBar().setRange(0, 0)
        self.verticalScrollBar().setRange(0, 0)

        self.margin = 8
        self.totalSize = 300
        self.pieSize = self.totalSize - 2*self.margin
        self.validItems = 0
        self.totalValue = 0.0
        self.origin = QPoint()
        self.rubberBand = None

    def dataChanged(self, topLeft, bottomRight, roles):
        super(PieView, self).dataChanged(topLeft, bottomRight, roles)

        self.validItems = 0
        self.totalValue = 0.0

        for row in range(self.model().rowCount(self.rootIndex())):

            index = self.model().index(row, 1, self.rootIndex())
            value = self.model().data(index)

            if value is not None and value > 0.0:
                self.totalValue += value
                self.validItems += 1

        self.viewport().update()

    def edit(self, index, trigger, event):
        if index.column() == 0:
            return super(PieView, self).edit(index, trigger, event)
        else:
            return False

    def indexAt(self, point):
        if self.validItems == 0:
            return QModelIndex()

        # Transform the view coordinates into contents widget coordinates.
        wx = point.x() + self.horizontalScrollBar().value()
        wy = point.y() + self.verticalScrollBar().value()

        if wx < self.totalSize:
            cx = wx - self.totalSize/2
            cy = self.totalSize/2 - wy; # positive cy for items above the center

            # Determine the distance from the center point of the pie chart.
            d = (cx**2 + cy**2)**0.5

            if d == 0 or d > self.pieSize/2:
                return QModelIndex()

            # Determine the angle of the point.
            angle = (180 / math.pi) * math.acos(cx/d)
            if cy < 0:
                angle = 360 - angle

            # Find the relevant slice of the pie.
            startAngle = 0.0

            for row in range(self.model().rowCount(self.rootIndex())):

                index = self.model().index(row, 1, self.rootIndex())
                value = self.model().data(index)

                if value > 0.0:
                    sliceAngle = 360*value/self.totalValue

                    if angle >= startAngle and angle < (startAngle + sliceAngle):
                        return self.model().index(row, 1, self.rootIndex())

                    startAngle += sliceAngle

        else:
            itemHeight = QFontMetrics(self.viewOptions().font).height()
            listItem = int((wy - self.margin) / itemHeight)
            validRow = 0

            for row in range(self.model().rowCount(self.rootIndex())):

                index = self.model().index(row, 1, self.rootIndex())
                if self.model().data(index) > 0.0:

                    if listItem == validRow:
                        return self.model().index(row, 0, self.rootIndex())

                    # Update the list index that corresponds to the next valid
                    # row.
                    validRow += 1

        return QModelIndex()

    def isIndexHidden(self, index):
        return False

    def itemRect(self, index):
        if not index.isValid():
            return QRect()

        # Check whether the index's row is in the list of rows represented
        # by slices.

        if index.column() != 1:
            valueIndex = self.model().index(index.row(), 1, self.rootIndex())
        else:
            valueIndex = index

        if self.model().data(valueIndex) > 0.0:

            listItem = 0
            for row in range(index.row()-1, -1, -1):
                if self.model().data(self.model().index(row, 1, self.rootIndex())) > 0.0:
                    listItem += 1

            if index.column() == 0:

                itemHeight = QFontMetrics(self.viewOptions().font).height()
                return QRect(self.totalSize,
                             int(self.margin + listItem*itemHeight),
                             self.totalSize - self.margin, int(itemHeight))
            elif index.column() == 1:
                return self.viewport().rect()

        return QRect()

    def itemRegion(self, index):
        if not index.isValid():
            return QRegion()

        if index.column() != 1:
            return QRegion(self.itemRect(index))

        if self.model().data(index) <= 0.0:
            return QRegion()

        startAngle = 0.0
        for row in range(self.model().rowCount(self.rootIndex())):

            sliceIndex = self.model().index(row, 1, self.rootIndex())
            value = self.model().data(sliceIndex)

            if value > 0.0:
                angle = 360*value/self.totalValue

                if sliceIndex == index:
                    slicePath = QPainterPath()
                    slicePath.moveTo(self.totalSize/2, self.totalSize/2)
                    slicePath.arcTo(self.margin, self.margin,
                            self.margin+self.pieSize, self.margin+self.pieSize,
                            startAngle, angle)
                    slicePath.closeSubpath()

                    return QRegion(slicePath.toFillPolygon().toPolygon())

                startAngle += angle

        return QRegion()

    def horizontalOffset(self):
        return self.horizontalScrollBar().value()

    def mousePressEvent(self, event):
        super(PieView, self).mousePressEvent(event)

        self.origin = event.pos()
        if not self.rubberBand:
            self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.rubberBand.setGeometry(QRect(self.origin, QSize()))
        self.rubberBand.show()

    def mouseMoveEvent(self, event):
        if self.rubberBand:
            self.rubberBand.setGeometry(QRect(self.origin, event.pos()).normalized())

        super(PieView, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        super(PieView, self).mouseReleaseEvent(event)

        if self.rubberBand:
            self.rubberBand.hide()

        self.viewport().update()

    def moveCursor(self, cursorAction, modifiers):
        current = self.currentIndex()

        if cursorAction in (QAbstractItemView.MoveLeft, QAbstractItemView.MoveUp):

            if current.row() > 0:
                current = self.model().index(current.row() - 1,
                        current.column(), self.rootIndex())
            else:
                current = self.model().index(0, current.column(),
                        self.rootIndex())

        elif cursorAction in (QAbstractItemView.MoveRight, QAbstractItemView.MoveDown):

            if current.row() < self.rows(current) - 1:
                current = self.model().index(current.row() + 1,
                        current.column(), self.rootIndex())
            else:
                current = self.model().index(self.rows(current) - 1,
                        current.column(), self.rootIndex())

        self.viewport().update()
        return current

    def paintEvent(self, event):
        selections = self.selectionModel()
        option = self.viewOptions()
        state = option.state

        background = option.palette.base()
        foreground = QPen(option.palette.color(QPalette.WindowText))
        textPen = QPen(option.palette.color(QPalette.Text))
        highlightedPen = QPen(option.palette.color(QPalette.HighlightedText))

        painter = QPainter(self.viewport())
        painter.setRenderHint(QPainter.Antialiasing)

        painter.fillRect(event.rect(), background)
        painter.setPen(foreground)

        # Viewport rectangles
        pieRect = QRect(self.margin, self.margin, self.pieSize,
                self.pieSize)
        keyPoint = QPoint(self.totalSize - self.horizontalScrollBar().value(),
                self.margin - self.verticalScrollBar().value())

        if self.validItems > 0:
            painter.save()
            painter.translate(pieRect.x() - self.horizontalScrollBar().value(),
                    pieRect.y() - self.verticalScrollBar().value())
            painter.drawEllipse(0, 0, self.pieSize, self.pieSize)
            startAngle = 0.0

            for row in range(self.model().rowCount(self.rootIndex())):

                index = self.model().index(row, 1, self.rootIndex())
                value = self.model().data(index)

                if value > 0.0:
                    angle = 360*value/self.totalValue

                    colorIndex = self.model().index(row, 0, self.rootIndex())
                    color = self.model().data(colorIndex, Qt.DecorationRole)

                    if self.currentIndex() == index:
                        painter.setBrush(QBrush(color, Qt.Dense4Pattern))
                    elif selections.isSelected(index):
                        painter.setBrush(QBrush(color, Qt.Dense3Pattern))
                    else:
                        painter.setBrush(QBrush(color))

                    painter.drawPie(0, 0, self.pieSize, self.pieSize,
                            int(startAngle*16), int(angle*16))

                    startAngle += angle

            painter.restore()

            keyNumber = 0

            for row in range(self.model().rowCount(self.rootIndex())):
                index = self.model().index(row, 1, self.rootIndex())
                value = self.model().data(index)

                if value > 0.0:
                    labelIndex = self.model().index(row, 0, self.rootIndex())

                    option = self.viewOptions()
                    option.rect = self.visualRect(labelIndex)
                    if selections.isSelected(labelIndex):
                        option.state |= QStyle.State_Selected
                    if self.currentIndex() == labelIndex:
                        option.state |= QStyle.State_HasFocus
                    self.itemDelegate().paint(painter, option, labelIndex)

                    keyNumber += 1

    def resizeEvent(self, event):
        self.updateGeometries()

    def rows(self, index):
        return self.model().rowCount(self.model().parent(index))

    def rowsInserted(self, parent, start, end):
        for row in range(start, end + 1):
            index = self.model().index(row, 1, self.rootIndex())
            value = self.model().data(index)

            if value is not None and value > 0.0:
                self.totalValue += value
                self.validItems += 1

        super(PieView, self).rowsInserted(parent, start, end)

    def rowsAboutToBeRemoved(self, parent, start, end):
        for row in range(start, end + 1):
            index = self.model().index(row, 1, self.rootIndex())
            value = self.model().data(index)

            if value is not None and value > 0.0:
                self.totalValue -= value
                self.validItems -= 1

        super(PieView, self).rowsAboutToBeRemoved(parent, start, end)

    def scrollContentsBy(self, dx, dy):
        self.viewport().scroll(dx, dy)

    def scrollTo(self, index, ScrollHint):
        area = self.viewport().rect()
        rect = self.visualRect(index)

        if rect.left() < area.left():
            self.horizontalScrollBar().setValue(
                self.horizontalScrollBar().value() + rect.left() - area.left())
        elif rect.right() > area.right():
            self.horizontalScrollBar().setValue(
                self.horizontalScrollBar().value() + min(
                    rect.right() - area.right(), rect.left() - area.left()))

        if rect.top() < area.top():
            self.verticalScrollBar().setValue(
                self.verticalScrollBar().value() + rect.top() - area.top())
        elif rect.bottom() > area.bottom():
            self.verticalScrollBar().setValue(
                self.verticalScrollBar().value() + min(
                    rect.bottom() - area.bottom(), rect.top() - area.top()))

    def setSelection(self, rect, command):
        # Use content widget coordinates because we will use the itemRegion()
        # function to check for intersections.

        contentsRect = rect.translated(self.horizontalScrollBar().value(),
                self.verticalScrollBar().value()).normalized()

        rows = self.model().rowCount(self.rootIndex())
        columns = self.model().columnCount(self.rootIndex())
        indexes = []

        for row in range(rows):
            for column in range(columns):
                index = self.model().index(row, column, self.rootIndex())
                region = self.itemRegion(index)
                if not region.intersect(QRegion(contentsRect)).isEmpty():
                    indexes.append(index)

        if len(indexes) > 0:
            firstRow = indexes[0].row()
            lastRow = indexes[0].row()
            firstColumn = indexes[0].column()
            lastColumn = indexes[0].column()

            for i in range(1, len(indexes)):
                firstRow = min(firstRow, indexes[i].row())
                lastRow = max(lastRow, indexes[i].row())
                firstColumn = min(firstColumn, indexes[i].column())
                lastColumn = max(lastColumn, indexes[i].column())

            selection = QItemSelection(
                self.model().index(firstRow, firstColumn, self.rootIndex()),
                self.model().index(lastRow, lastColumn, self.rootIndex()))
            self.selectionModel().select(selection, command)
        else:
            noIndex = QModelIndex()
            selection = QItemSelection(noIndex, noIndex)
            self.selectionModel().select(selection, command)

        self.update()

    def updateGeometries(self):
        self.horizontalScrollBar().setPageStep(self.viewport().width())
        self.horizontalScrollBar().setRange(0, max(0, 2*self.totalSize - self.viewport().width()))
        self.verticalScrollBar().setPageStep(self.viewport().height())
        self.verticalScrollBar().setRange(0, max(0, self.totalSize - self.viewport().height()))

    def verticalOffset(self):
        return self.verticalScrollBar().value()

    def visualRect(self, index):
        rect = self.itemRect(index)
        if rect.isValid():
            return QRect(rect.left() - self.horizontalScrollBar().value(),
                         rect.top() - self.verticalScrollBar().value(),
                         rect.width(), rect.height())
        else:
            return rect

    def visualRegionForSelection(self, selection):
        region = QRegion()

        for span in selection:
            for row in range(span.top(), span.bottom() + 1):
                for col in range(span.left(), span.right() + 1):
                    index = self.model().index(row, col, self.rootIndex())
                    region += self.visualRect(index)

        return region
Пример #32
0
class ImageCropperDropper(QLabel):
	'''A QLabel that displays a rectangle when drawing a rectangle with the mouse'''

	cropped = Signal(QPixmap)
	fileDropped = Signal(QUrl)

	def __init__(self, mainwin):
		QLabel.__init__(self)

		self.setAcceptDrops(True)

		self.marker = QRubberBand(QRubberBand.Rectangle, self)
		self.markOrigin = self.markEnd = None

		self.setContextMenuPolicy(Qt.ActionsContextMenu)
		self.addAction(mainwin.cropAction)
		self.addAction(mainwin.saveAction)

	def setPixmap(self, pix):
		QLabel.setPixmap(self, pix)
		self.resize(pix.size())

		self.marker.hide()
		self.markOrigin = self.markEnd = None

	@Slot()
	def doCrop(self):
		'''Crop the pixmap using the user-drawn rectangle, emits cropped(QPixmap) signal'''
		if not self.markEnd:
			QMessageBox.warning(self, 'Error', 'Select a region to crop first')
			return
		cropzone = self._makeRect(self.markOrigin, self.markEnd)
		croppedpix = self.pixmap().copy(cropzone)

		self.setPixmap(croppedpix)
		self.cropped.emit(croppedpix)

	def _makeRect(self, p1, p2):
		'''Make a QRect based on QPoints p1 and p2.
		The 2 points must be 2 corners but don't need to be upper-left&lower-right'''
		x1, x2 = min(p1.x(), p2.x()), max(p1.x(), p2.x())
		y1, y2 = min(p1.y(), p2.y()), max(p1.y(), p2.y())
		return QRect().adjusted(x1, y1, x2, y2)

	def mouseMoveEvent(self, ev):
		if ev.buttons() != Qt.LeftButton:
			return QLabel.mouseMoveEvent(self, ev)
		self.markEnd = ev.pos()
		diffpoint = self.markEnd - self.markOrigin
		#~ self.marker.resize(diffpoint.x(), diffpoint.y())
		self.marker.setGeometry(self._makeRect(self.markOrigin, self.markEnd))
		#~ ev.accept()

	def mousePressEvent(self, ev):
		if ev.button() != Qt.LeftButton:
			return QLabel.mousePressEvent(self, ev)
		self.markOrigin = ev.pos()
		self.marker.move(ev.pos())
		self.marker.resize(QSize())
		self.marker.show()
		#~ ev.accept()

	def dragEnterEvent(self, ev):
		if ev.mimeData().hasUrls():
			ev.setDropAction(Qt.CopyAction)
			ev.accept()

	def dropEvent(self, ev):
		if ev.mimeData().hasUrls():
			ev.setDropAction(Qt.CopyAction)
			ev.accept()
			self.fileDropped.emit(ev.mimeData().urls()[0])
Пример #33
0
class DragWidget(QWidget):
    spacerX = 16
    spacerY = 16
    clipicon = None
    new_window_signal = pyqtSignal(str)
    query = pyqtSignal()
    src_dragwidget = None
    src_selected = []

    def __init__(self, path, parent=None):
        super(DragWidget, self).__init__(parent)
        self.setMinimumSize(400, 200)
        self.setAcceptDrops(True)
        self.parent = parent
        # self.parent.menu.connect(self.delete_icon)
        self.modifier = False
        self.rubberband = QRubberBand(QRubberBand.Rectangle, self)
        self.path = path
        self.icons = []
        self.icon_offsetx = 0
        self.icon_offsety = 0
        # self.clipicon = None
        # self.moving_icons = []
        self.read_drawer()
        self.clean_up()
        # print(type(IconWidget.icon))
        # print(self.findChildren(ClickableIcon))

    def read_drawer(self):
        # self.icons.clear()
        for item in os.scandir(self.path):
            if item.is_dir():
                icon_widget = IconWidget(parent=self, name=item.name, path=self.path, dir=True)
            else:
                icon_widget = IconWidget(parent=self, name=item.name, path=self.path, dir=False)
            icon_widget.new_window.connect(self.new_window_signal.emit)
            icon_widget.clipboard.connect(self.on_clipboard)
            self.icons.append(icon_widget)
            self.icons[-1].setAttribute(Qt.WA_DeleteOnClose)
        # self.update()

    def updateScrollArea(self):
        """ set the dimension of the widget """
        iconx = []
        icony = []
        if len(self.icons) > 0:
            for item in self.icons:
                iconx.append(item.x())
                icony.append(item.y())
            self.setMinimumWidth(max(iconx)+75)
            self.setMinimumHeight(max(icony)+75)
        
    def dragEnterEvent(self, event):
        event.accept()

    def dragMoveEvent(self, event):
        event.accept()

    def get_dnd_list(self, event):
        icon_list = []
        icon_offsetx = None
        icon_offsety = None
        if len(DragWidget.src_selected) > 0:
            for item in DragWidget.src_selected:
                icon_list.append(item)
        else:
            icon_list.append(event.source())
        return icon_list

    def create_icon(self, name, drawer):
        if drawer:
            icon_widget = IconWidget(self, name=name, path=self.path, dir=True)
        else: 
            icon_widget = IconWidget(self, name=name, path=self.path, dir=False)
        icon_widget.new_window.connect(self.new_window_signal.emit)
        self.icons.append(icon_widget)

    def place_icon(self, x, y):
        self.icons[-1].move(x, y)
        self.icons[-1].show()

    def dropEvent(self, event):
        event.accept()
        icon_list = self.get_dnd_list(event)
        icon_offsetx = event.pos().x()
        icon_offsety = event.pos().y()
        for item in icon_list:
            name = item.name
            drawer = item.drawer
            src_path = item.path + "/" + name
            dst_path = self.path + "/"
            if event.mimeData().hasFormat("application/x-icon"):
                self.create_icon(name, drawer)
                self.move_data(src_path, dst_path)
                self.place_icon(icon_offsetx, icon_offsety)
                icon_offsetx += 100 
                if icon_offsetx > self.window().width():
                    icon_offsetx = event.pos().x()
                    icon_offsety += 75

        icon_offsetx = None
        icon_offsety = None
        self.updateScrollArea()

    def clear_dnd(self):
        DragWidget.src_dragwidget = None
        DragWidget.src_selected.clear()

    def get_modifier(self):
        return self.parent.modifier

    def mousePressEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            for item in self.icons:
                item.icon.deselect_icon()
            self.clear_dnd() 

            self.origin = event.pos()
            self.rubberband.setGeometry(QRect(self.origin, QSize()))
            self.rubberband.show()

    def mouseMoveEvent(self, event):
        if self.rubberband.isVisible():
            self.rubberband.setGeometry(
                QRect(self.origin, event.pos()).normalized())
        # QWidget.mouseMoveEvent(self, event)

    def mouseReleaseEvent(self, event):
        self.clear_dnd()
        if self.rubberband.isVisible():
            self.rubberband.hide()
            rect = self.rubberband.geometry()
            for child in self.findChildren(IconWidget):
                if rect.intersects(child.geometry()):
                    child.icon.select_icon()
                    DragWidget.src_selected.append(child)
                    if DragWidget.src_dragwidget is not self:
                        DragWidget.src_dragwidget = self

    def mouseDoubleClickEvent(self, event):
        print(BLU, "Double Click", END) 
        self.query.emit()

    def create_file(self):
        new_file = self.path + "/" + "newfile.txt"
        open(new_file, 'w').close()
        icon_widget = IconWidget(self, name="newfile.txt", path=self.path, dir=False)
        icon_widget.new_window.connect(self.new_window_signal.emit)
        icon_widget.show()
        self.icons.append(icon_widget)

    def create_drawer(self):
        print("creating new drawer")
        new_drawer = self.path + "/" + "NewDrawer"
        os.makedirs(new_drawer)
        icon_widget = IconWidget(self, name="NewDrawer", path=self.path, dir=True)
        icon_widget.new_window.connect(self.new_window_signal.emit)
        icon_widget.show()
        self.icons.append(icon_widget)

    def rename_file(self):
        print("renaming file")

    def clean_up(self):
        for item in self.icons:
            item.move(DragWidget.spacerX, DragWidget.spacerY)
            # initial icon placement
            DragWidget.spacerX += 100
            if DragWidget.spacerX + 100 > self.window().width():
                DragWidget.spacerY += 75
                DragWidget.spacerX = 16
        # reset placement values
        DragWidget.spacerX = 16
        DragWidget.spacerY = 16
        self.updateScrollArea()

    def move_data(self, source, dest):
        srce_path = source.rsplit('/', 1)[0]
        dest_path = dest.rsplit('/', 1)[0]
        if srce_path != dest_path:
            try:
                shutil.move(source, dest)
            except Exception as err:
                print(err)

    def copy_icon(self, source, dest):
        pass

    def delete_icon(self):
        dest = os.path.expanduser("~") + "/.Trash/"
        error_string = ""
        for item in self.icons:
            if item.icon.selected:
                source = item.path + "/" + item.name
                if source is not "":
                    try:
                        shutil.move(source, dest)
                    except Exception as err:
                        error_string += str(err) + "\n" + "\n"
                    else:
                        self.icons.remove(item)
                        item.deleteLater()
        if error_string is not "":
            QMessageBox.information(self, 'Info', error_string, QMessageBox.Ok)

    def paste_icon(self):
        print("---")
        print("srce=", self.clipicon.path + "/" + self.clipicon.name)
        # print("res=", self.clipicon.path + "/" + self.clipicon.name)
        print("dest=", self.path + "/")

        # if os.path.isdir(os.path.join(self.clipicon.path, self.clipicon.name)):
        SRCE = self.clipicon.path + "/" + self.clipicon.name
        DEST = self.path+"/" + self.clipicon.name
        shutil.copytree(SRCE, DEST)

    def on_clipboard(self, icon):
        print("realpath", self.path)
        print("clip_icon_name=", icon.name)
        DragWidget.clipicon = icon
Пример #34
0
class ImageView(QGraphicsView):
    @staticmethod
    def close_enough(point1, point2):
        d = 20
        return abs(point1.x() - point2.x()) < d and abs(point1.y() -
                                                        point2.y()) < d

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

        self.go_prev_img = parent.go_prev_img
        self.go_next_img = parent.go_next_img

        pal = self.palette()
        pal.setColor(self.backgroundRole(), Qt.black)
        self.setPalette(pal)
        self.setFrameShape(QFrame.NoFrame)

        self.rband = None
        self.rband_state = None
        self.rband_corner = None  # If mouse is over a corner
        self.rband_origin = QPoint()
        self.rband_endpoint = QPoint()

    def mousePressEvent(self, event):
        """Go to the next / previous image, or be able to drag the image with a hand."""
        if self.rband_state == "initial":
            self.rband = QRubberBand(QRubberBand.Rectangle, self)
            self.rband_origin = event.pos()
            self.rband.setGeometry(QRect(self.rband_origin, QSize()))
            self.rband.show()
            self.rband_state = "set-endpoint"
        elif self.rband_state == "drawn":
            if self.rband_corner == "nw":
                self.rband_state = "set-origin"
            elif self.rband_corner == "se":
                self.rband_state = "set-endpoint"
            elif self.rband_corner == "inside":
                self.rband_state = "move"
                self.setCursor(QCursor(Qt.ClosedHandCursor))
                self.rband_previous_pos = event.pos()
        else:
            if event.button() == Qt.LeftButton:
                x = event.x()
                if x < 100:
                    self.go_prev_img()
                elif x > self.width() - 100:
                    self.go_next_img()
                else:
                    self.setDragMode(QGraphicsView.ScrollHandDrag)
        QGraphicsView.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        if self.rband_state == "set-endpoint":
            self.rband.setGeometry(
                QRect(self.rband_origin, event.pos()).normalized())
            self.rband_endpoint = event.pos()
        elif self.rband_state == "set-origin":
            self.rband.setGeometry(
                QRect(event.pos(), self.rband_endpoint).normalized())
            self.rband_origin = event.pos()
        elif self.rband_state == "move":
            old_pos = self.rband.geometry()
            new_pos = old_pos.translated(event.pos() - self.rband_previous_pos)
            trace(0)
            self.rband.setGeometry(new_pos)
            self.rband_previous_pos = event.pos()
        elif self.rband_state == "drawn":
            if ImageView.close_enough(self.rband_origin, event.pos()):
                self.rband_corner = "nw"
                self.setCursor(QCursor(Qt.SizeFDiagCursor))
            elif ImageView.close_enough(self.rband_endpoint, event.pos()):
                self.rband_corner = "se"
                self.setCursor(QCursor(Qt.SizeFDiagCursor))
            elif self.rband.geometry().contains(event.pos()):
                self.rband_corner = "inside"
                self.setCursor(QCursor(Qt.OpenHandCursor))
            else:
                self.rband_corner = None
                self.setCursor(QCursor(Qt.ArrowCursor))
        QGraphicsView.mouseMoveEvent(self, event)

    def mouseReleaseEvent(self, event):
        #print("State %s", self.rband_state)
        if self.rband_state == "set-endpoint" or self.rband_state == "set-origin":
            self.rband_state = "drawn"
        elif self.rband_state == "move":
            self.setCursor(QCursor(Qt.ArrowCursor))
            self.rband_state = "drawn"
            self.rband_origin = self.rband.geometry().topLeft()
            self.rband_endpoint = self.rband.geometry().bottomRight()
        else:
            self.setCursor(QCursor(Qt.ArrowCursor))
            self.setDragMode(QGraphicsView.NoDrag)
        QGraphicsView.mouseReleaseEvent(self, event)

    def keyPressEvent(self, event):
        if self.rband_state == "drawn":
            if event.key() == Qt.Key_Escape:
                self.setCursor(QCursor(Qt.ArrowCursor))
                self.rband.hide()
                self.rband_state = None
                self.setMouseTracking(False)
            elif event.key() in [Qt.Key_Return, Qt.Key_Enter, Qt.Key_Space]:
                self.setCursor(QCursor(Qt.ArrowCursor))
                self.rband.hide()
                self.rband_state = None
                self.setMouseTracking(False)
                #print("CB ", self.get_coords())
                self.crop_callback(self.get_coords())
        event.accept()

    def zoom(self, zoomratio):
        self.scale(zoomratio, zoomratio)

    def wheelEvent(self, event):
        zoomratio = 1.1
        if event.angleDelta().y() < 0:
            zoomratio = 1.0 / zoomratio
        self.scale(zoomratio, zoomratio)

    def crop(self, callback):
        self.crop_callback = callback
        self.rband_state = "initial"
        self.setMouseTracking(True)

    def get_coords(self):
        rect = self.rband.geometry()
        size = self.mapToScene(rect).boundingRect()
        x = int(size.x())
        y = int(size.y())
        width = int(size.width())
        height = int(size.height())
        return (x, y, width, height)
Пример #35
0
class FrameLess(QObject):
    def __init__(self, parent):
        super(FrameLess, self).__init__(parent)
        self._parent = parent
        self._cursorChanged = False
        self._leftButtonPressed = False
        self._mouseMove = Edge.NoEdge
        self._mousePress = Edge.NoEdge
        self._borderWidth = 5
        self._rubberBand = QRubberBand(QRubberBand.Rectangle)
        self._parent.setWindowFlags(Qt.FramelessWindowHint | Qt.CustomizeWindowHint | Qt.Window)
        self._parent.setAttribute(Qt.WA_Hover)
        self._parent.setMouseTracking(True)
        self._parent.installEventFilter(self)

    def eventFilter(self, obj, event):
        if event.type() == QEvent.MouseMove:
            self.__mouseMove(QMouseEvent(event))
            return True
        else:
            if event.type() == QEvent.Leave:
                self.__mouseLeave(event)
                return True
            else:
                if event.type() == QEvent.HoverMove:
                    self.__mouseHover(QHoverEvent(event))
                    return True
                else:
                    if event.type() == QEvent.MouseButtonPress:
                        self.__mousePress(QMouseEvent(event))
                        return True
                    else:
                        if event.type() == QEvent.MouseButtonRelease:
                            self.__mouseRelease(QMouseEvent(event))
                            return True
                        else:
                            return False

    def __mouseHover(self, event):
        self.__updateCursorShape(self._parent.mapToGlobal(event.pos()))

    def __mouseLeave(self, event):
        if not self._leftButtonPressed:
            self._parent.unsetCursor()

    def __mousePress(self, event):
        if event.button() == Qt.LeftButton:
            self._leftButtonPressed = True
            self._mousePress = self.__calculateCursorPosition(event.globalPos(), self._parent.frameGeometry())
            if self._mousePress != Edge.NoEdge:
                self._rubberBand.setGeometry(self._parent.frameGeometry())

    def __mouseRelease(self, event):
        if event.button() == Qt.LeftButton:
            self._leftButtonPressed = False

    def __mouseMove(self, event):
        if self._leftButtonPressed:
            if self._mousePress != Edge.NoEdge:
                left = self._rubberBand.frameGeometry().left()
                top = self._rubberBand.frameGeometry().top()
                right = self._rubberBand.frameGeometry().right()
                bottom = self._rubberBand.frameGeometry().bottom()
                if self._mousePress == Edge.Top:
                    top = event.globalPos().y()
                else:
                    if self._mousePress == Edge.Bottom:
                        bottom = event.globalPos().y()
                    else:
                        if self._mousePress == Edge.Right:
                            right = event.globalPos().x()
                        else:
                            if self._mousePress == Edge.Left:
                                left = event.globalPos().x()
                            else:
                                if self._mousePress == Edge.TopRight:
                                    top = event.globalPos().y()
                                    right = event.globalPos().x()
                                else:
                                    if self._mousePress == Edge.TopLeft:
                                        top = event.globalPos().y()
                                        left = event.globalPos().x()
                                    else:
                                        if self._mousePress == Edge.BottomLeft:
                                            bottom = event.globalPos().y()
                                            left = event.globalPos().x()
                                        else:
                                            if self._mousePress == Edge.BottomRight:
                                                bottom = event.globalPos().y()
                                                right = event.globalPos().x()

                newRect = QRect(QPoint(left, top), QPoint(right, bottom))
                if newRect.width() < self._parent.minimumWidth():
                    left = self.frameGeometry().x()
                else:
                    if newRect.height() < self._parent.minimumHeight():
                        top = self.frameGeometry().y()
                self._parent.setGeometry(QRect(QPoint(left, top), QPoint(right, bottom)))
                self._rubberBand.setGeometry(QRect(QPoint(left, top), QPoint(right, bottom)))
        else:
            self.__updateCursorShape(event.globalPos())

    def __updateCursorShape(self, pos):
        if self._parent.isFullScreen() or self._parent.isMaximized():
            if self._cursorChanged:
                self._parent.unsetCursor()
                return
        self._mouseMove = self.__calculateCursorPosition(pos, self._parent.frameGeometry())
        if self._mouseMove == Edge.Left or self._mouseMove == Edge.Right:
            self._parent.setCursor(Qt.SizeHorCursor)
            self._cursorChanged = True
        else:
            if self._mouseMove == Edge.Top or self._mouseMove == Edge.Bottom:
                self._parent.setCursor(Qt.SizeVerCursor)
                self._cursorChanged = True
            else:
                if self._mouseMove == Edge.TopLeft or self._mouseMove == Edge.BottomRight:
                    self._parent.setCursor(Qt.SizeFDiagCursor)
                    self._cursorChanged = True
                else:
                    if self._mouseMove == Edge.TopRight or self._mouseMove == Edge.BottomLeft:
                        self._parent.setCursor(Qt.SizeBDiagCursor)
                        self._cursorChanged = True
                    else:
                        self._parent.unsetCursor()
                        self._cursorChanged = False

    def __calculateCursorPosition(self, pos, framerect):
        onLeft = pos.x() <= framerect.x() + self._borderWidth and \
                 pos.x() >= framerect.x() and \
                 pos.y() <= framerect.y() + framerect.height() - self._borderWidth and \
                 pos.y() >= framerect.y() + self._borderWidth

        onRight = pos.x() >= framerect.x() + framerect.width() - self._borderWidth and \
                  pos.x() <= framerect.x() + framerect.width() and \
                  pos.y() >= framerect.y() + self._borderWidth and \
                  pos.y() <= framerect.y() + framerect.height() - self._borderWidth 

        onBottom = pos.x() >= framerect.x() + self._borderWidth and \
                   pos.x() <= framerect.x() + framerect.width() - self._borderWidth  and \
                   pos.y() >= framerect.y() + framerect.height() - self._borderWidth and \
                   pos.y() <= framerect.y() + framerect.height()

        onTop = pos.x() >= framerect.x() + self._borderWidth and \
                pos.x() <= framerect.x() + framerect.width() - self._borderWidth and \
                pos.y() >= framerect.y() and pos.y() <= framerect.y() + self._borderWidth

        onBottomLeft = pos.x() <= framerect.x() + self._borderWidth and \
                       pos.x() >= framerect.x() and \
                       pos.y() <= framerect.y() + framerect.height() and \
                       pos.y() >= framerect.y() + framerect.height() - self._borderWidth

        onBottomRight = pos.x() >= framerect.x() + framerect.width() - self._borderWidth and \
                        pos.x() <= framerect.x() + framerect.width() and \
                        pos.y() >= framerect.y() + framerect.height() - self._borderWidth and \
                        pos.y() <= framerect.y() + framerect.height()

        onTopRight = pos.x() >= framerect.x() + framerect.width() - self._borderWidth and \
                     pos.x() <= framerect.x() + framerect.width() and \
                     pos.y() >= framerect.y() and \
                     pos.y() <= framerect.y() + self._borderWidth

        onTopLeft = pos.x() >= framerect.x() and \
                    pos.x() <= framerect.x() + self._borderWidth and \
                    pos.y() >= framerect.y() and \
                    pos.y() <= framerect.y() + self._borderWidth

        if onLeft:
            return Edge.Left
        else:
            if onRight:
                return Edge.Right
            else:
                if onBottom:
                    return Edge.Bottom
                else:
                    if onTop:
                        return Edge.Top
                    else:
                        if onBottomLeft:
                            return Edge.BottomLeft
                        else:
                            if onBottomRight:
                                return Edge.BottomRight
                            else:
                                if onBottomRight:
                                    return Edge.BottomRight
                                else:
                                    if onTopRight:
                                        return Edge.TopRight
                                    else:
                                        if onTopLeft:
                                            return Edge.TopLeft
                                        else:
                                            return Edge.NoEdge

    def setBorderWidth(self, borderWidth):
        self._borderWidth = borderWidth

    def borderWidth(self):
        return self._borderWidth
class ImageHolder(QWidget):

    foregroundState = list()
    foreground = None
    mousePressPoint = None
    cropMode = False
    def __init__(self, image):
        super(ImageHolder, self).__init__()
        self.image = image
        self.setMinimumSize(self.image.size())
        self.resize(self.image.size())
        self.foreground = QImage(self.image.size(),QImage.Format_ARGB32_Premultiplied)
        undo = QShortcut(QKeySequence("Ctrl+z"), self)
        undo.activated.connect(self.undo)

        crop = QShortcut(QKeySequence("c"), self)
        crop.activated.connect(self.toggleCropMode)


    def applyState(self):
        print("apply state")
        if self.cropMode:
            rect = self.currentQRubberBand.geometry()
            self.image = self.image.copy(rect)
            self.setMinimumSize(self.image.size())
            self.resize(self.image.size())
            QApplication.restoreOverrideCursor()
            self.toggleCropMode()
            self.currentQRubberBand.hide()
            self.repaint()

    def cancelState(self):
        if cropMode:
            self.currentQRubberBand.hide()

    def toggleCropMode(self):
        self.cropMode = not self.cropMode
        if self.cropMode:
            QApplication.setOverrideCursor(QCursor(Qt.CrossCursor))
        else:
            QApplication.restoreOverrideCursor()

    def mousePressEvent(self, event):
        print("ImageHolder: " + str(event.pos()))
        self.mousePressPoint = event.pos();
        if self.cropMode:
            if hasattr(self, "currentQRubberBand"):
                self.currentQRubberBand.hide()
            self.currentQRubberBand = QRubberBand(QRubberBand.Rectangle, self)
            self.currentQRubberBand.setGeometry(QRect(self.mousePressPoint, QSize()))
            self.currentQRubberBand.show()

    def mouseMoveEvent(self, event):
        print("mouseMove: " + str(event.pos()))
        if self.cropMode:
            self.currentQRubberBand.setGeometry(QRect(self.mousePressPoint, event.pos()).normalized())

    def undo(self):
        if self.cropMode:
            self.currentQRubberBand.hide()
        elif len(self.foregroundState) > 0:
            self.foreground = self.foregroundState.pop()
            self.repaint()

    def mouseReleaseEvent(self, event):
        if not self.cropMode:
            self.foregroundState.append(QImage(self.foreground))
            self.painter.begin(self.foreground)
            self.painter.setPen(QPen(QBrush(QColor(255,241,18,100)), 15, Qt.SolidLine, Qt.RoundCap))
            self.painter.drawLine(QLine(self.mousePressPoint.x(),self.mousePressPoint.y(),
             event.pos().x(), event.pos().y()))
            self.painter.end()
            self.repaint()

    def saveChanges(self):
        newImage = QImage(self.image.size(), QImage.Format_ARGB32_Premultiplied)
        painter = QPainter(newImage)
        painter.drawImage(0,0, self.image)
        painter.drawImage(0,0, self.foreground)
        painter.end()
        return newImage

    def paintEvent(self, event):
        self.painter = QPainter(self)
        self.painter.setPen(QPen(QBrush(QColor(255,241,18,100)), 15, Qt.SolidLine, Qt.RoundCap))
        self.painter.drawImage(0,0, self.image)
        self.painter.drawImage(0,0, self.foreground)
        self.painter.end()
Пример #37
0
class FsApp(QMainWindow):

    def __init__(self, app):
        super(FsApp, self).__init__()
        self.app       = app
        self.selRect   = None
        self.screenPix = None

        # Set up the user interface from Designer.
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        #self.setWindowOpacity(0.5)
        #self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
        self.captureScreen()
        self.showMaximized()
        self.showFullScreen()


        #capture screen and display
        rec = QApplication.desktop().screenGeometry()
        height = rec.height()
        width = rec.width()
        self.ui.labPix.resize(width, height)
        self.ui.labPix.setScaledContents(True)
        self.ui.labPix.setPixmap(self.screenPix)

        #start rubberband
        self.rubberband = QRubberBand(QRubberBand.Rectangle, self)
        bla = QtGui.QPalette()
        bla.setBrush(QtGui.QPalette.Highlight, QtGui.QBrush(QtCore.Qt.red))
        self.rubberband.setPalette(bla)
        self.rubberband.setWindowOpacity(1.0)

    def captureScreen(self):
        screens = self.app.screens()
        self.screenPix = screens[0].grabWindow(0)

    def mousePressEvent(self, event):
        self.origin = event.pos()
        self.rubberband.setGeometry(QtCore.QRect(self.origin, QtCore.QSize()))
        self.rubberband.show()
        QWidget.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        if self.rubberband.isVisible():
            self.rubberband.setGeometry(QtCore.QRect(self.origin, event.pos()).normalized())
        QWidget.mouseMoveEvent(self, event)

    def mouseReleaseEvent(self, event):
        if self.rubberband.isVisible():
            self.selRect = self.rubberband.geometry()
            self.rubberband.hide()
            codePix = self.screenPix.copy(    self.selRect.x(),
                            self.selRect.y(), 
                            self.selRect.width(),
                            self.selRect.height())
            QApplication.clipboard().setPixmap(codePix)
            self.exit()
        QWidget.mouseReleaseEvent(self, event)

    def exit(self):
        sys.exit(0)
Пример #38
0
class MyGraphicsView(CanvasBase):
    """
    This is the used Canvas to print the graphical interface of dxf2gcode.
    All GUI things should be performed in the View and plotting functions in
    the scene
    """

    def __init__(self, parent=None):
        """
        Initialisation of the View Object. This is called by the gui created
        with the QTDesigner.
        @param parent: Main is passed as a pointer for reference.
        """
        super(MyGraphicsView, self).__init__(parent)
        self.currentItem = None

        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QGraphicsView.AnchorViewCenter)

        # self.setDragMode(QGraphicsView.RubberBandDrag )
        self.setDragMode(QGraphicsView.NoDrag)

        self.parent = parent
        self.mppos = None

        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.prvRectRubberBand = QtCore.QRect()

    def tr(self, string_to_translate):
        """
        Translate a string using the QCoreApplication translation framework
        @param string_to_translate: a unicode string
        @return: the translated unicode string if it was possible to translate
        """
        return text_type(QtCore.QCoreApplication.translate('MyGraphicsView',
                                                           string_to_translate))

    def contextMenuEvent(self, event):
        """
        Create the contextmenu.
        @purpose: Links the new Class of ContextMenu to Graphicsview.
        """
        position = self.mapToGlobal(event.pos())
        GVPos = self.mapToScene(event.pos())
        real_pos = Point(GVPos.x(), -GVPos.y())

        menu = MyDropDownMenu(self.scene(), position, real_pos)

    def wheelEvent(self, event):
        """
        With Mouse Wheel the object is scaled
        @purpose: Scale by mouse wheel
        @param event: Event Parameters passed to function
        """
        if c.PYQT5notPYQT4:
            delta = event.angleDelta().y()
        else:
            delta = event.delta()
        scale = (1000 + delta) / 1000.0
        self.scale(scale, scale)

    def mousePressEvent(self, event):
        """
        Right Mouse click shall have no function, Therefore pass only left
        click event
        @purpose: Change inherited mousePressEvent
        @param event: Event Parameters passed to function
        """

        if self.dragMode() == 1:
            super(MyGraphicsView, self).mousePressEvent(event)
        elif event.button() == QtCore.Qt.LeftButton:
            self.mppos = event.pos()
        else:
            pass

    def mouseReleaseEvent(self, event):
        """
        Right Mouse click shall have no function, Therefore pass only left
        click event
        @purpose: Change inherited mousePressEvent
        @param event: Event Parameters passed to function
        """
        delta = 2

        if self.dragMode() == 1:
            # if (event.key() == QtCore.Qt.Key_Shift):
            # self.setDragMode(QGraphicsView.NoDrag)
            super(MyGraphicsView, self).mouseReleaseEvent(event)

        # Selection only enabled for left Button
        elif event.button() == QtCore.Qt.LeftButton:
            self.currentItems = []
            scene = self.scene()
            if not self.isMultiSelect:
                for item in scene.selectedItems():
                    item.setSelected(False, False)
            # If the mouse button is pressed without movement of rubberband
            if self.rubberBand.isHidden():
                rect = QtCore.QRect(event.pos().x()-delta,
                                    event.pos().y() - delta,
                                    2 * delta, 2*delta)
                # logger.debug(rect)

                point = self.mapToScene(event.pos())
                min_distance = float(0x7fffffff)
                for item in self.items(rect):
                    itemDistance = item.contains_point(point)
                    if itemDistance < min_distance:
                        min_distance = itemDistance
                        self.currentItems = item
                if self.currentItems:
                    if self.currentItems.isSelected():
                        self.currentItems.setSelected(False, False)
                    else:
                        self.currentItems.setSelected(True, False)
            else:
                rect = self.rubberBand.geometry()
                self.currentItems = self.items(rect)
                self.rubberBand.hide()
                # logger.debug("Rubberband Selection")

                # All items in the selection
                # self.currentItems = self.items(rect)
                # print self.currentItems
                # logger.debug(rect)

                for item in self.currentItems:
                    if item.isSelected():
                        item.setSelected(False, False)
                    else:
                        # print (item.flags())
                        item.setSelected(True, False)

        else:
            pass

        self.mppos = None
        # super(MyGraphicsView, self).mouseReleaseEvent(event)

    def mouseMoveEvent(self, event):
        """
        MouseMoveEvent of the Graphiscview. May also be used for the Statusbar.
        @purpose: Get the MouseMoveEvent and use it for the Rubberband Selection
        @param event: Event Parameters passed to function
        """
        if self.mppos is not None:
            Point = event.pos() - self.mppos
            if Point.manhattanLength() > 3:
                # print 'the mouse has moved more than 3 pixels since the oldPosition'
                # print "Mouse Pointer is currently hovering at: ", event.pos()
                rect = QtCore.QRect(self.mppos, event.pos())
                '''
                The following is needed because of PyQt5 doesn't like to switch from sign
                 it will keep displaying last rectangle, i.e. you can end up will multiple rectangles
                '''
                if self.prvRectRubberBand.width() > 0 and not rect.width() > 0 or rect.width() == 0 or\
                   self.prvRectRubberBand.height() > 0 and not rect.height() > 0 or rect.height() == 0:
                    self.rubberBand.hide()
                self.rubberBand.setGeometry(rect.normalized())
                self.rubberBand.show()
                self.prvRectRubberBand = rect

        scpoint = self.mapToScene(event.pos())

        # self.setStatusTip('X: %3.1f; Y: %3.1f' % (scpoint.x(), -scpoint.y()))
        # works not as supposed to
        self.setToolTip('X: %3.1f; Y: %3.1f' %(scpoint.x(), -scpoint.y()))

        super(MyGraphicsView, self).mouseMoveEvent(event)

    def autoscale(self):
        """
        Automatically zooms to the full extend of the current GraphicsScene
        """
        scene = self.scene()
        width = scene.bottomRight.x - scene.topLeft.x
        height = scene.topLeft.y - scene.bottomRight.y
        scext = QtCore.QRectF(scene.topLeft.x, -scene.topLeft.y, width * 1.05, height * 1.05)
        self.fitInView(scext, QtCore.Qt.KeepAspectRatio)
        logger.debug(self.tr("Autoscaling to extend: %s") % scext)

    def setShowPathDirections(self, flag):
        """
        This function is called by the Main Window from the Menubar.
        @param flag: This flag is true if all Path Direction shall be shown
        """
        scene = self.scene()
        for shape in scene.shapes:
            shape.starrow.setallwaysshow(flag)
            shape.enarrow.setallwaysshow(flag)
            shape.stmove.setallwaysshow(flag)

    def resetAll(self):
        """
        Deletes the existing GraphicsScene.
        """
        scene = self.scene()
        del scene
Пример #39
0
class QtImagePartSelector(QGraphicsView):
    """
    Partly based on https://github.com/marcel-goldschen-ohm/PyQtImageViewer
    by Marcel Goldschen-Ohm, MIT license
    """

    rectSet = pyqtSignal(QRect)

    def __init__(self):
        QGraphicsView.__init__(self)

        # Image is displayed as a QPixmap in a QGraphicsScene attached to this QGraphicsView.
        self.scene = QGraphicsScene()
        self.setScene(self.scene)

        # Store a local handle to the scene's current image pixmap.
        self._pixmapHandle = None

        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        # rubber band for area selection
        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.rubberBandScenePos = None # so it can be restored after resizing
        self.setMouseTracking(True)
        self.origin = QPoint()
        self.changeRubberBand = False

        # previous mouse position during mouse drag action
        self.dragPrevMousePos = None

        self.setCursor(Qt.CrossCursor)

    def hasImage(self):
        """ Returns whether or not the scene contains an image pixmap.
        """
        return self._pixmapHandle is not None

    def clearImage(self):
        """ Removes the current image pixmap from the scene if it exists.
        """
        if self.hasImage():
            self.scene.removeItem(self._pixmapHandle)
            self._pixmapHandle = None

    def pixmap(self):
        """ Returns the scene's current image pixmap as a QPixmap, or else None if no image exists.
        :rtype: QPixmap | None
        """
        if self.hasImage():
            return self._pixmapHandle.pixmap()
        return None

    def image(self):
        """ Returns the scene's current image pixmap as a QImage, or else None if no image exists.
        :rtype: QImage | None
        """
        if self.hasImage():
            return self._pixmapHandle.pixmap().toImage()
        return None

    def resizeEvent(self, event):
        QGraphicsView.resizeEvent(self, event)
        self.updateRubberBandDisplay()


    def showEvent(self, event):
        self.old_center = self.mapToScene(self.rect().center())

    def setImage(self, image):
        """ Set the scene's current image pixmap to the input QImage or QPixmap.
        Raises a RuntimeError if the input image has type other than QImage or QPixmap.
        :type image: QImage | QPixmap
        """
        if type(image) is QPixmap:
            pixmap = image
        elif type(image) is QImage:
            pixmap = QPixmap.fromImage(image)
        else:
            raise RuntimeError("ImageViewer.setImage: Argument must be a QImage or QPixmap.")
        if self.hasImage():
            self._pixmapHandle.setPixmap(pixmap)
        else:
            self._pixmapHandle = self.scene.addPixmap(pixmap)
        self.setSceneRect(QRectF(pixmap.rect()))  # Set scene size to image size.



    def loadImageFromFile(self, fileName=""):
        """ Load an image from file.
        Without any arguments, loadImageFromFile() will popup a file dialog to choose the image file.
        With a fileName argument, loadImageFromFile(fileName) will attempt to load the specified image file directly.
        """
        if len(fileName) == 0:
            fileName, dummy = QFileDialog.getOpenFileName(self, "Open image file.")
        if len(fileName) and os.path.isfile(fileName):
            image = QImage(fileName)
            self.setImage(image)

    def mousePressEvent(self, event):
        """ Start creation of rubber band
        """
        if event.button() == Qt.LeftButton:
            self.origin = event.pos()
            self.rubberBand.setGeometry(QRect(self.origin, QSize()))
            self.rubberBandScenePos = self.mapToScene(self.rubberBand.geometry())

            self.rubberBand.show()
            self.changeRubberBand = True
        elif event.button() == Qt.MidButton:
            self.setCursor(Qt.ClosedHandCursor)
            self.dragPrevMousePos = event.pos()

        QGraphicsView.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        if self.changeRubberBand:
            # update rubber
            self.rubberBand.setGeometry(QRect(self.origin, event.pos()).normalized())
            self.rubberBandScenePos = self.mapToScene(self.rubberBand.geometry())
        if event.buttons() & Qt.MidButton:
            # drag image
            offset = self.dragPrevMousePos - event.pos()
            self.dragPrevMousePos = event.pos()

            self.verticalScrollBar().setValue(self.verticalScrollBar().value() + offset.y())
            self.horizontalScrollBar().setValue(self.horizontalScrollBar().value() + offset.x())
            self.updateRubberBandDisplay()

        QGraphicsView.mouseMoveEvent(self, event)

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            # Emit rubber band size
            self.changeRubberBand = False
            self.rectSet.emit(self.rubberBandScenePos.boundingRect().toAlignedRect())
        elif event.button() == Qt.MiddleButton:
            self.setCursor(Qt.CrossCursor)

        QGraphicsView.mouseReleaseEvent(self, event)

    def updateRubberBandDisplay(self):
        if self.rubberBandScenePos is not None:
            self.rubberBand.setGeometry(self.mapFromScene(self.rubberBandScenePos).boundingRect())

    def wheelEvent(self, event):
        # Zoom Factor
        zoomInFactor = 1.1
        zoomOutFactor = 1 / zoomInFactor

        # Set Anchors
        self.setTransformationAnchor(QGraphicsView.NoAnchor)
        self.setResizeAnchor(QGraphicsView.NoAnchor)

        # Save the scene pos
        oldPos = self.mapToScene(event.pos())

        # Zoom
        if event.angleDelta().y() > 0:
            zoomFactor = zoomInFactor
        else:
            zoomFactor = zoomOutFactor
        self.scale(zoomFactor, zoomFactor)

        # Get the new position
        newPos = self.mapToScene(event.pos())

        # Move scene to old position
        delta = newPos - oldPos
        self.translate(delta.x(), delta.y())

        self.updateRubberBandDisplay()
Пример #40
0
class TcamScreen(QtWidgets.QGraphicsView):

    new_pixmap = pyqtSignal(QtGui.QPixmap)
    new_pixel_under_mouse = pyqtSignal(bool, int, int, QtGui.QColor)
    destroy_widget = pyqtSignal()
    fit_in_view = pyqtSignal()

    def __init__(self, parent=None):
        super(TcamScreen, self).__init__(parent)
        self.setMouseTracking(True)
        self.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                           QtWidgets.QSizePolicy.Expanding)
        self.setDragMode(QGraphicsView.ScrollHandDrag)
        self.setFrameStyle(0)
        self.scene = QGraphicsScene(self)
        self.setScene(self.scene)

        self.new_pixmap.connect(self.on_new_pixmap)
        self.fit_in_view.connect(self.fit_view)
        self.pix = ViewItem()
        self.scene.addItem(self.pix)
        self.scene.setSceneRect(self.pix.boundingRect())

        self.is_fullscreen = False

        # Flag to differentiate between actual images
        # and 'fake images' i.e. color background + text while
        # waiting for first trigger image
        self.display_real_image = True
        self.text_item = None

        self.fit_in_view_called = False

        self.mouse_position_x = -1
        self.mouse_position_y = -1

        self.zoom_factor = 1.0
        self.first_image = True
        self.image_counter = 0

        self.capture_roi = False
        self.roi_obj = None
        self.roi_origin = None
        self.roi_widgets = []

        self.selection_area = None
        self.capture_widget = None
        self.origin = None

    def fit_view(self):
        """

        """

        self.reset_zoom()
        self.scene.setSceneRect(self.pix.boundingRect())
        self.scene.update()
        self.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)

    def reset_zoom(self):

        self.zoom_factor = 1.0
        # this resets the view internal transformation matrix
        self.setTransform(QtGui.QTransform())

    def on_new_pixmap(self, pixmap):
        self.image_counter += 1
        self.pix.setPixmap(pixmap)

        if not self.display_real_image:
            self.text_item.hide()
            self.scene.removeItem(self.text_item)
            self.display_real_image = True

        if self.image_counter == 1:
            self.resize(self.size())
            self.scene.setSceneRect(self.pix.boundingRect())
            self.update()

            self.reset_zoom()
            self.first_image = False

        # wait for the second image
        # resizeEvents, etc appear before the scene has adjusted
        # to the actual image size. By waiting for the 2. image
        # we circumvent this by having the first image making all
        # adjustments for us. The only scenario where this will
        # cause problems is triggering.
        if self.is_fullscreen and self.image_counter == 2:
            self.fit_view()

        self.send_mouse_pixel()
        # don't call repaint here
        # it causes problems once the screen goes blank due to screensavers, etc
        # self.repaint()

    def wait_for_first_image(self):

        if not self.display_real_image:
            return

        self.reset_zoom()
        self.display_real_image = False

        self.text_item = QGraphicsTextItem()
        self.text_item.setDefaultTextColor(QColor("white"))

        self.text_item.setPos(100, 70)
        self.text_item.setPlainText("In Trigger Mode. Waiting for first image...")

        bg = QPixmap(1280, 720)
        bg.fill(QColor("grey"))
        self.pix.setPixmap(bg)
        self.image_counter += 1
        self.scene.addItem(self.text_item)

    def send_mouse_pixel(self):
        # mouse positions start at 0
        # we want the lower right corner to have the correct coordinates
        # e.g. an 1920x1080 image should have the coordinates
        # 1920x1080 for the last pixel

        self.new_pixel_under_mouse.emit(self.pix.legal_coordinates(self.mouse_position_x,
                                                                   self.mouse_position_y),
                                        self.mouse_position_x + 1,
                                        self.mouse_position_y + 1,
                                        self.pix.get_color_at_position(self.mouse_position_x,
                                                                       self.mouse_position_y))

    def mouseMoveEvent(self, event):
        mouse_position = self.mapToScene(event.pos())
        self.mouse_position_x = mouse_position.x()
        self.mouse_position_y = mouse_position.y()

        if self.selection_area:

            # adjust rect since we want to pull in all directions
            # origin can well be bottom left, thus recalc
            def calc_selection_rect():

                x = min(self.origin.x(), event.pos().x())
                y = min(self.origin.y(), event.pos().y())
                x2 = max(self.origin.x(), event.pos().x())
                y2 = max(self.origin.y(), event.pos().y())

                return QPoint(x, y), QPoint(x2, y2)

            p1, p2 = calc_selection_rect()
            self.selection_area.setGeometry(QRect(p1, p2))

        super().mouseMoveEvent(event)

    def mousePressEvent(self, event):
        """"""

        if self.capture_widget:

            self.selection_area = QRubberBand(QRubberBand.Rectangle, self)
            self.selection_area.setGeometry(QRect(event.pos(), QSize()))
            self.origin = event.pos()
            self.selection_area.show()

        super().mousePressEvent(event)

    def mouseReleaseEvent(self, event):

        if self.capture_widget:
            selectionBBox = self.selection_area.rect()
            rect = QRect(self.selection_area.pos(), selectionBBox.size())
            selectionBBox = self.mapToScene(rect).boundingRect().toRect()
            self.capture_widget.emit(selectionBBox)

            self.selection_area.hide()
            self.selection_area = None
            QApplication.restoreOverrideCursor()

        self.capture_widget = None
        self.selection_area = None

        super().mouseReleaseEvent(event)

    def is_scene_larger_than_image(self):
        """
        checks if the entire ViewItem is visible in the scene
        """
        port_rect = self.viewport().rect()
        scene_rect = self.mapToScene(port_rect).boundingRect()
        item_rect = self.pix.mapRectFromScene(scene_rect)

        isec = item_rect.intersected(self.pix.boundingRect())

        res = self.pix.get_resolution()
        if (isec.size().width() >= QSizeF(res).width() and
                isec.size().height() >= QSizeF(res).height()):
            return True
        return False

    def wheelEvent(self, event):

        if not self.display_real_image:
            return
        # Zoom Factor
        zoomInFactor = 1.25
        zoomOutFactor = 1 / zoomInFactor

        # Set Anchors
        self.setTransformationAnchor(QGraphicsView.NoAnchor)
        self.setResizeAnchor(QGraphicsView.NoAnchor)

        # Save the scene pos
        oldPos = self.mapToScene(event.pos())

        # Zoom
        if event.angleDelta().y() > 0:
            zoomFactor = zoomInFactor
        else:
            zoomFactor = zoomOutFactor

        if (self.is_scene_larger_than_image() and
                zoomFactor < 1.0):
            return

        self.zoom_factor *= zoomFactor

        # we scale the view itself to get infinite zoom
        # so that we can inspect a single pixel
        self.scale(zoomFactor, zoomFactor)

        # Get the new position
        newPos = self.mapToScene(event.pos())

        # Move scene to old position
        delta = newPos - oldPos
        self.translate(delta.x(), delta.y())

        self.scene.setSceneRect(self.pix.boundingRect())

    def set_scale_position(self, scale_factor, x, y):
        self.scale(scale_factor, scale_factor)
        self.translate(x, y)

    def keyPressEvent(self, event):
        if self.isFullScreen():
            if (event.key() == Qt.Key_F11 or
                    event.key() == Qt.Key_Escape or
                    event.key() == Qt.Key_F):
                self.destroy_widget.emit()
        elif self.capture_widget and event.key() == Qt.Key_Escape:
            self.abort_roi_capture()
        else:
            # Ignore event so that parent widgets can use it.
            # This is only called when we are not fullscreen.
            # Fullscreen causes us to have no parents.
            event.ignore()

    def start_roi_capture(self, finished_signal):
        """
        Capture a region of interest
        """

        self.capture_widget = finished_signal
        QApplication.setOverrideCursor(Qt.CrossCursor)

    def abort_roi_capture(self):
        """
        Abort the capture of a regoin of interest
        """
        self.capture_widget = None
        self.origin = None

        if self.selection_area:
            self.selection_area.hide()
            self.selection_area = None

        QApplication.restoreOverrideCursor()

    def add_roi(self, roi_widget):
        """
        Add roi_widget to the QGraphicsScene for display
        """
        if not roi_widget:
            return

        self.roi_widgets.append(roi_widget)
        self.scene.addItem(roi_widget)
        roi_widget.show()

    def remove_roi(self, roi_widget):
        """
        Remove given roi widget from the scene
        """
        if not roi_widget:
            return

        roi_widget.hide()
        try:
            self.roi_widgets.remove(roi_widget)
        except ValueError as e:
            # This means the widget is not in the list
            pass
Пример #41
0
class QMainLabel(QLabel):
    def __init__(self, parentQWidget):
        super(QMainLabel, self).__init__(parentQWidget)
        self.original_image_pixmap = None
        self.original_mask_pixmap = None
        self.target_size = self.parent().main_label_size

    def set_size(self, size):
        self.target_size = size

    def load_pixmap(self, image, mask=None):
        self.original_image_pixmap = QPixmap(image)

        if mask:
            self.original_mask_pixmap = QPixmap(mask)
            combo = self.merge_image_mask(self.original_image_pixmap,
                                          self.original_mask_pixmap)
            self.setPixmap(combo)
            return

        self.setPixmap(self.original_image_pixmap)

    def merge_image_mask(self, image, mask):

        print(type(image), type(mask))

        if type(image) == QPixmap and type(mask) == QPixmap:
            pil_image = ImageQt.fromqpixmap(image)
            pil_mask = ImageQt.fromqpixmap(mask)
        else:
            pil_image = image
            pil_mask = mask

        np_image = np.array(pil_image)
        np_mask = np.array(pil_mask)

        print(np_image.shape, np_mask.shape)

        prob = np.float32(np_mask) / 255.0
        np_combo = np.uint8(np_image * (1 - prob) +
                            np_mask * prob * np.array([[[0., 1., 0.]]]))

        pil_combo = Image.fromarray(np_combo)
        combo = ImageQt.toqpixmap(pil_combo)

        return combo

    def restore_original(self):
        print('Ctrl+Z')

        image = self.original_image_pixmap
        mask = self.original_mask_pixmap

        if image and mask:
            image = self.merge_image_mask(image, mask)

        self.setPixmap(image)

    def mousePressEvent(self, eventQMouseEvent):
        self.originQPoint = eventQMouseEvent.pos()
        self.currentQRubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.currentQRubberBand.setGeometry(QRect(self.originQPoint, QSize()))
        self.currentQRubberBand.show()

    def mouseMoveEvent(self, eventQMouseEvent):
        self.currentQRubberBand.setGeometry(
            QRect(self.originQPoint, eventQMouseEvent.pos()).normalized())

    def mouseReleaseEvent(self, eventQMouseEvent):
        self.currentQRubberBand.hide()
        currentQRect = self.currentQRubberBand.geometry()
        self.currentQRubberBand.deleteLater()
        cropQPixmap = self.pixmap().copy(currentQRect)
        # cropQPixmap.save('output.png')

        crop_PIL = ImageQt.fromqpixmap(cropQPixmap)
        crop_PIL = pad_to_square(crop_PIL, self.target_size)
        cropQPixmap = ImageQt.toqpixmap(crop_PIL)
        self.setPixmap(cropQPixmap)
Пример #42
0
class MainView(QGraphicsView):
    """
    This class implements the main view displayed in the MDI area.
    """
    MoveRate = 40
    MoveBound = 10

    sgnScaled = pyqtSignal(float)

    def __init__(self, mainwindow, scene):
        """
        Initialize the main scene.
        :type mainwindow: MainWindow
        :type scene: DiagramScene
        """
        super().__init__(scene)
        self.setContextMenuPolicy(Qt.PreventContextMenu)
        self.setDragMode(QGraphicsView.NoDrag)
        self.setOptimizationFlags(QGraphicsView.DontAdjustForAntialiasing)
        self.setOptimizationFlags(QGraphicsView.DontSavePainterState)
        self.setViewportUpdateMode(QGraphicsView.MinimalViewportUpdate)
        self.mainwindow = mainwindow
        self.mousePressCenterPos = None
        self.mousePressPos = None
        self.moveTimer = None
        self.rubberBandOrigin = None
        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.rubberBand.hide()
        self.zoom = 1.00

    ####################################################################################################################
    #                                                                                                                  #
    #   SLOTS                                                                                                          #
    #                                                                                                                  #
    ####################################################################################################################

    @pyqtSlot()
    def updateView(self):
        """
        Update the Overview.
        """
        viewport = self.viewport()
        viewport.update()

    @pyqtSlot(float)
    def zoomChanged(self, zoom):
        """
        Executed when the zoom factor changes (triggered by the Zoom widget).
        :type zoom: float
        """
        self.scaleView(zoom)

    ####################################################################################################################
    #                                                                                                                  #
    #   DRAWING                                                                                                        #
    #                                                                                                                  #
    ####################################################################################################################

    def drawBackground(self, painter, rect):
        """
        Draw the scene background.
        :type painter: QPainter
        :type rect: QRectF
        """
        if self.mainwindow.snapToGrid:
            s = DiagramScene.GridSize
            x = int(rect.left()) - (int(rect.left()) % s)
            y = int(rect.top()) - (int(rect.top()) % s)
            painter.setPen(DiagramScene.GridPen)
            painter.drawPoints(*(QPointF(i, j) for i in rangeF(x, rect.right(), s) for j in rangeF(y, rect.bottom(), s)))

    ####################################################################################################################
    #                                                                                                                  #
    #   EVENTS                                                                                                         #
    #                                                                                                                  #
    ####################################################################################################################

    def keyPressEvent(self, keyEvent):
        """
        Executed when a combination of key is pressed.
        :type keyEvent: QKeyEvent
        """
        scene = self.scene()
        key = keyEvent.key()
        modifiers = keyEvent.modifiers()

        if scene.mode is DiagramMode.Idle and \
            modifiers & Qt.ControlModifier and \
                key in {Qt.Key_Minus, Qt.Key_Plus, Qt.Key_0}:

            if key == Qt.Key_Minus:
                zoom = self.zoom - Zoom.Step
            elif key == Qt.Key_Plus:
                zoom = self.zoom + Zoom.Step
            else:
                zoom = Zoom.Default

            zoom = clamp(zoom, Zoom.Min, Zoom.Max)

            if zoom != self.zoom:
                self.setTransformationAnchor(QGraphicsView.NoAnchor)
                self.setResizeAnchor(QGraphicsView.NoAnchor)
                self.scaleView(zoom)
                self.sgnScaled.emit(zoom)

        else:
            super().keyPressEvent(keyEvent)

    def mousePressEvent(self, mouseEvent):
        """
        Executed when a mouse button is clicked on the view.
        :type mouseEvent: QGraphicsSceneMouseEvent
        """
        scene = self.scene()
        mouseButtons = mouseEvent.buttons()
        mousePos = mouseEvent.pos()

        if mouseButtons & Qt.RightButton:

            ############################################################################################################
            #                                                                                                          #
            #                                              SCENE DRAG                                                  #
            #                                                                                                          #
            ############################################################################################################

            visibleRect = self.visibleRect()
            self.mousePressCenterPos = visibleRect.center()
            self.mousePressPos = mousePos

        else:

            if mouseButtons & Qt.LeftButton:

                ########################################################################################################
                #                                                                                                      #
                #                                      RUBBERBAND SELECTION                                            #
                #                                                                                                      #
                ########################################################################################################

                if scene.mode is DiagramMode.Idle and not self.itemAt(mousePos):
                    self.rubberBandOrigin = self.mapToScene(mousePos)
                    self.rubberBand.setGeometry(QRectF(mousePos, mousePos).toRect())
                    self.rubberBand.show()
                    scene.setMode(DiagramMode.RubberBandDrag)

            super().mousePressEvent(mouseEvent)

    # noinspection PyArgumentList
    def mouseMoveEvent(self, mouseEvent):
        """
        Executed when then mouse is moved on the view.
        :type mouseEvent: QGraphicsSceneMouseEvent
        """
        scene = self.scene()
        mousePos = mouseEvent.pos()
        mouseButtons = mouseEvent.buttons()
        viewport = self.viewport()

        if mouseButtons & Qt.RightButton:

            if (mouseEvent.pos() - self.mousePressPos).manhattanLength() >= QApplication.startDragDistance():

                ########################################################################################################
                #                                                                                                      #
                #                                            SCENE DRAG                                                #
                #                                                                                                      #
                ########################################################################################################

                if scene.mode is not DiagramMode.SceneDrag:
                    scene.setMode(DiagramMode.SceneDrag)
                    viewport.setCursor(Qt.ClosedHandCursor)

                mousePos /= self.zoom
                mousePressPos = self.mousePressPos / self.zoom
                self.centerOn(self.mousePressCenterPos - mousePos + mousePressPos)

        else:

            super().mouseMoveEvent(mouseEvent)

            if mouseButtons & Qt.LeftButton:
                
                self.stopMove()

                if scene.mode is DiagramMode.RubberBandDrag:

                    ####################################################################################################
                    #                                                                                                  #
                    #                                       RUBBERBAND DRAG                                            #
                    #                                                                                                  #
                    ####################################################################################################

                    area = QRectF(self.mapFromScene(self.rubberBandOrigin), mousePos).normalized()
                    path = QPainterPath()
                    path.addRect(area)
                    scene.setSelectionArea(self.mapToScene(path))
                    self.rubberBand.setGeometry(area.toRect())

                if scene.mode in { DiagramMode.BreakPointMove,
                                   DiagramMode.InsertEdge,
                                   DiagramMode.MoveNode,
                                   DiagramMode.ResizeNode,
                                   DiagramMode.RubberBandDrag }:

                    ####################################################################################################
                    #                                                                                                  #
                    #                                      VIEW SCROLLING                                              #
                    #                                                                                                  #
                    ####################################################################################################

                    R = viewport.rect()
                    if not R.contains(mousePos):

                        move = QPointF(0, 0)

                        if mousePos.x() < R.left():
                            move.setX(mousePos.x() - R.left())
                        elif mousePos.x() > R.right():
                            move.setX(mousePos.x() - R.right())

                        if mousePos.y() < R.top():
                            move.setY(mousePos.y() - R.top())
                        elif mousePos.y() > R.bottom():
                            move.setY(mousePos.y() - R.bottom())

                        if move:
                            move.setX(clamp(move.x(), -MainView.MoveBound, +MainView.MoveBound))
                            move.setY(clamp(move.y(), -MainView.MoveBound, +MainView.MoveBound))
                            self.startMove(move, MainView.MoveRate)

    def mouseReleaseEvent(self, mouseEvent):
        """
        Executed when the mouse is released from the view.
        :type mouseEvent: QGraphicsSceneMouseEvent
        """
        self.mousePressCenterPos = None
        self.mousePressPos = None
        self.rubberBandOrigin = None
        self.rubberBand.hide()

        self.stopMove()

        scene = self.scene()
        viewport = self.viewport()
        viewport.setCursor(Qt.ArrowCursor)
        viewport.update()

        super().mouseReleaseEvent(mouseEvent)

        if scene.mode in {DiagramMode.RubberBandDrag, DiagramMode.SceneDrag}:
            scene.setMode(DiagramMode.Idle)

    def wheelEvent(self, wheelEvent):
        """
        Executed when the mouse wheel is moved on the scene.
        :type wheelEvent: QWheelEvent
        """
        if wheelEvent.modifiers() & Qt.ControlModifier:

            wheelPos = wheelEvent.pos()
            wheelAngle = wheelEvent.angleDelta()

            zoom = self.zoom
            zoom += +Zoom.Step if wheelAngle.y() > 0 else -Zoom.Step
            zoom = clamp(zoom, Zoom.Min, Zoom.Max)

            if zoom != self.zoom:
                self.setTransformationAnchor(QGraphicsView.NoAnchor)
                self.setResizeAnchor(QGraphicsView.NoAnchor)
                p1 = self.mapToScene(wheelPos)
                self.scaleView(zoom)
                self.sgnScaled.emit(zoom)
                p2 = self.mapToScene(wheelPos)
                move = p2 - p1
                self.translate(move.x(), move.y())

        else:
            super().wheelEvent(wheelEvent)

    ####################################################################################################################
    #                                                                                                                  #
    #   INTERFACE                                                                                                      #
    #                                                                                                                  #
    ####################################################################################################################

    def moveBy(self, *__args):
        """
        Move the view by the given delta.
        """
        if len(__args) == 1:
            delta = __args[0]
        elif len(__args) == 2:
            delta = QPointF(__args[0], __args[1])
        else:
            raise TypeError('too many arguments; expected {}, got {}'.format(2, len(__args)))
        self.centerOn(self.visibleRect().center() + delta)

    def scaleView(self, zoom):
        """
        Scale the view according to the given zoom.
        :type zoom: float
        """
        transform = self.transform()
        self.resetTransform()
        self.translate(transform.dx(), transform.dy())
        self.scale(zoom, zoom)
        self.zoom = zoom

    def startMove(self, delta, rate):
        """
        Start the view movement.
        :type delta: QPointF
        :type rate: float
        """
        if self.moveTimer:
            self.stopMove()

        # move the view: this is needed before the timer so that if we keep
        # moving the mouse fast outside the viewport rectangle we still are able
        # to move the view; if we don't do this the timer may not have kicked in
        # and thus we remain with a non-moving view with a unfocused graphicsitem
        self.moveBy(delta)

        # setup a timer for future move, so the view keeps moving
        # also if we are not moving the mouse anymore but we are
        # holding the position outside the viewport rect
        self.moveTimer = QTimer()
        connect(self.moveTimer.timeout, self.moveBy, delta)
        self.moveTimer.start(rate)

    def stopMove(self):
        """
        Stop the view movement by destroying the timer object causing it.
        """
        if self.moveTimer:
            self.moveTimer.stop()
            disconnect(self.moveTimer.timeout)
            self.moveTimer = None

    def visibleRect(self):
        """
        Returns the visible area in scene coordinates.
        :rtype: QRectF
        """
        return self.mapToScene(self.viewport().rect()).boundingRect()