示例#1
0
    def __init__(self, tileSource, parent=None):
        """Constructor.

        Args:
            tileSource(MapTileSource): Source for loading the tiles.
            parent(QObject): Parent object, default `None`
        """
        QGraphicsScene.__init__(self, parent=parent)

        self._zoom = 15

        self._tileSource = tileSource
        self._tileSource.setParent(self)
        self._tileSource.tileReceived.connect(self.setTilePixmap)
        tdim = self._tileSource.tileSize()

        self._emptyTile = QPixmap(tdim, tdim)
        self._emptyTile.fill(Qt.lightGray)

        self._tilesRect = QRect()
        self._tilePixmaps = {}

        self._tileInDownload = list()

        self.setSceneRect(0.0, 0.0, 400, 300)
        self.sceneRectChanged.connect(self.onSceneRectChanged)
示例#2
0
class BlockDiagramEditorView(QWidget):
    _size = 1_000

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

        self.labeledSlider = VLabeledSlider()

        self._qscene = QGraphicsScene()
        self._qscene.setSceneRect(-self._size / 2, -self._size / 2, self._size,
                                  self._size)

        self._qview = BlockDiagramView(scene=self._qscene, parent=self)

        layout = QHBoxLayout()
        layout.addWidget(self.labeledSlider, 0)
        layout.addWidget(self._qview, 1)
        layout.setAlignment(Qt.AlignCenter)
        self.widgetLayout = layout

        groupBox = QGroupBox()
        groupBox.setTitle("Block diagram")
        groupBox.setLayout(layout)

        parentLayout = QVBoxLayout()
        parentLayout.addWidget(groupBox)
        self.setLayout(parentLayout)
示例#3
0
    def __init__(self, tileSource, parent=None):
        """Constructor.

        Args:
            tileSource(MapTileSource): Source for loading the tiles.
            parent(QObject): Parent object, default `None`
        """
        QGraphicsScene.__init__(self, parent=parent)

        self._zoom = 15

        self._tileSource = tileSource
        self._tileSource.setParent(self)
        self._tileSource.tileReceived.connect(self.setTilePixmap)
        tdim = self._tileSource.tileSize()

        self._emptyTile = QPixmap(tdim, tdim)
        self._emptyTile.fill(Qt.lightGray)

        self._tilesRect = QRect()
        self._tilePixmaps = {}

        self._tileInDownload = list()

        self.setSceneRect(0.0, 0.0, 400, 300)
        self.sceneRectChanged.connect(self.onSceneRectChanged)
示例#4
0
    def __init__(self,
                 registry=None,
                 style=None,
                 parent=None,
                 allow_node_creation=True,
                 allow_node_deletion=True):
        '''
        Create a new flow scene

        Parameters
        ----------
        registry : DataModelRegistry, optional
        style : StyleCollection, optional
        parent : QObject, optional
        '''
        # Note: PySide2 does not support a cooperative __init__, meaning we
        # cannot use super().__init__ here.
        # super().__init__(registry=registry, parent=parent)
        QGraphicsScene.__init__(self, parent=parent)
        _FlowSceneModel.__init__(self, registry=registry)

        if style is None:
            style = style_module.default_style

        self._style = style
        self.allow_node_deletion = allow_node_creation
        self.allow_node_creation = allow_node_deletion

        self.setItemIndexMethod(QGraphicsScene.NoIndex)
示例#5
0
    def __init__(self, appdata: CnaData, name: str):
        self.scene = QGraphicsScene()
        QGraphicsView.__init__(self, self.scene)
        palette = self.palette()
        palette.setColor(QPalette.Base, Qt.white)
        self.setPalette(palette)

        self.appdata = appdata
        self.name = name
        self.setAcceptDrops(True)
        self.drag = False
        self.reaction_boxes: Dict[str, ReactionBox] = {}
        self._zoom = 0
        self.drag = False
        self.drag_start = None

        # initial scale
        self._zoom = self.appdata.project.maps[self.name]["zoom"]
        if self._zoom > 0:
            for _ in range(1, self._zoom):
                self.scale(INCREASE_FACTOR, INCREASE_FACTOR)
        if self._zoom < 0:
            for _ in range(self._zoom, -1):
                self.scale(DECREASE_FACTOR, DECREASE_FACTOR)

        # connect events to methods
        self.horizontalScrollBar().valueChanged.connect(self.on_hbar_change)
        self.verticalScrollBar().valueChanged.connect(self.on_vbar_change)
示例#6
0
    def __init__(self, camera, **settings):
        super(CroppableCameraView, self).__init__()
        self.setRenderHint(QPainter.Antialiasing)
        self.cam = camera
        self.is_live = False
        self._cmin = 0
        self._cmax = None
        self.settings = settings
        self._selecting = False
        self.needs_resize = False
        self.latest_array = None

        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.scene = QGraphicsScene()
        #self.setFrameStyle(QFrame.NoFrame)
        self.setScene(self.scene)
        self.pixmapitem = self.scene.addPixmap(QPixmap())
        self._uncropped_pixmap = None

        self.setMouseTracking(True)

        self.start = None
        c1 = QColor(0, 100, 220, 150)
        self.c2 = QColor(0, 100, 220, 50)
        self.c3 = QColor(0, 100, 220, 0)
        pen = QPen(c1, 2)

        self.selrect = self.scene.addRect(1, 1, 1, 1, pen, self.c3)
        self.selrect.setZValue(100)
        self.selrect.hide()
示例#7
0
 def showImage(self, posterPath: str):
     self.removeImage()
     imgData = requests.get(self.__poster_url__ + posterPath)
     pix = QPixmap()
     pix.loadFromData(imgData.content)
     item = QGraphicsPixmapItem(pix)
     self.__scene__ = QGraphicsScene(self)
     self.__scene__.addItem(item)
     self.ui.graphicsView.setScene(self.__scene__)
     self.resizeImage()
示例#8
0
    def __init__(self, **kwargs):
        super(GraphicsView, self).__init__(**kwargs)
        self._scene = QGraphicsScene(parent=self)

        self.current_image = QGraphicsPixmapItem()
        self._scene.addItem(self.current_image)

        self.setScene(self._scene)
        self.fitInView(self._scene.sceneRect(), Qt.KeepAspectRatio)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.setMouseTracking(True)
        self.setRenderHint(QPainter.Antialiasing)
示例#9
0
    def mousePressEvent(self, evt):
        '''Catch right-click events for rectangle drawing'''
        if self.rubberband_enabled and evt.button() == 2:
            evt.accept()
            pos = evt.scenePos()
            self.rect_start = pos

            if self.rubberband != None:
                self.removeItem(self.rubberband)
                self.rubberband = None

        else:
            evt.ignore()
            QGraphicsScene.mousePressEvent(self, evt)
示例#10
0
    def __init__(self, parent=None):

        super(GraphicsView, self).__init__(parent)

        self.scene = QGraphicsScene()
        self.pixmapItem = QGraphicsPixmapItem()
        self.scene.setSceneRect(0, 0, 500, 500)
        self.setScene(self.scene)
        self.scene.addItem(self.pixmapItem)
        #would eventually make this fit to size of screen, waiting cause it's annoying.

        self.buildingParams = []
        self.scalef = [1, 1]

        self.Buildings()
示例#11
0
    def __init__(self, camera, **settings):
        super(CroppableCameraView, self).__init__()
        self.setRenderHint(QPainter.Antialiasing)
        self.cam = camera
        self.is_live = False
        self._cmin = 0
        self._cmax = None
        self.settings = settings
        self._selecting = False
        self.needs_resize = False
        self.latest_array = None

        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.scene = QGraphicsScene()
        #self.setFrameStyle(QFrame.NoFrame)
        self.setScene(self.scene)
        self.pixmapitem = self.scene.addPixmap(QPixmap())
        self._uncropped_pixmap = None

        self.setMouseTracking(True)

        self.start = None
        c1 = QColor(0, 100, 220, 150)
        self.c2 = QColor(0, 100, 220, 50)
        self.c3 = QColor(0, 100, 220, 0)
        pen = QPen(c1, 2)

        self.selrect = self.scene.addRect(1, 1, 1, 1, pen, self.c3)
        self.selrect.setZValue(100)
        self.selrect.hide()
示例#12
0
    def mouseReleaseEvent(self, evt):
        '''Catch right-click events for rectangle drawing'''
        if self.rubberband_enabled and evt.button() == 2:
            evt.accept()
            pos = evt.scenePos()
            lon0, lat0 = self.lonLatFromPos(self.rect_start.x(),
                                            self.rect_start.y())
            lon1, lat1 = self.lonLatFromPos(pos.x(), pos.y())
            self.removeItem(self.rubberband)

            self.rect_start = None
            self.rect_end = None
            self.rubberband = None

            self.sigSelectionDrawn.emit(lon0, lat0, lon1, lat1)

        else:
            evt.ignore()
            QGraphicsScene.mouseReleaseEvent(self, evt)
示例#13
0
    def __init__(self, parent=None):

        super(DataGraphWidget, self).__init__(parent=parent)

        # Set up scene

        self.scene = QGraphicsScene(self)
        self.scene.setItemIndexMethod(QGraphicsScene.NoIndex)
        self.scene.setSceneRect(0, 0, 800, 300)

        self.setScene(self.scene)

        self.setWindowTitle("Glue data graph")

        self.setRenderHint(QPainter.Antialiasing)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QGraphicsView.AnchorViewCenter)

        self.selection_level = 0
示例#14
0
        def setup_gfx_ui():
            # design overview
            self.motor_display_view = QGraphicsView()
            self.motor_display_scene = QGraphicsScene()
            self.motor_display_view.setScene(self.motor_display_scene)
            self.motor_display_view.show()

            # sliced cross section
            self.grain_slice_view = QGraphicsView()
            self.grain_slice_scene = QGraphicsScene()
            self.grain_slice_view.setScene(self.grain_slice_scene)
            self.grain_slice_view.show()

            # splitter
            self.splt_gfx = QSplitter(Qt.Horizontal)
            self.splt_gfx.addWidget(self.motor_display_view)
            self.splt_gfx.addWidget(self.grain_slice_view)
            self.splt_gfx.setStretchFactor(0, 10)
            self.splt_gfx.setStretchFactor(1, 3)
            self.splt_gfx.setMinimumHeight(50)
示例#15
0
 def __init__(self, item) -> None:
     QGraphicsView.__init__(self)
     scene = QGraphicsScene(self)
     self.setScene(scene)
     item.setMinimumSize(QSize(150, 150))
     item.setMaximum(36000)
     item.setSingleStep(100)
     item.setPageStep(100)
     item.setInvertedAppearance(True)
     item.setWrapping(True)
     item.setNotchTarget(.1)
     item.setNotchesVisible(True)
     graphics_item = scene.addWidget(item)
     graphics_item.setRotation(-90)
     # make the QGraphicsView invisible.
     self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
     self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
     self.setFixedHeight(item.height())
     self.setFixedWidth(item.width())
     self.setStyleSheet("border: 0px;")
示例#16
0
class GraphicsView(QGraphicsView):
    def __init__(self, **kwargs):
        super(GraphicsView, self).__init__(**kwargs)
        self._scene = QGraphicsScene(parent=self)

        self.current_image = QGraphicsPixmapItem()
        self._scene.addItem(self.current_image)

        self.setScene(self._scene)
        self.fitInView(self._scene.sceneRect(), Qt.KeepAspectRatio)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.setMouseTracking(True)
        self.setRenderHint(QPainter.Antialiasing)

    def update_image(self, img: np.ndarray):
        rgb_image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        h, w, ch = rgb_image.shape
        bytes_per_line = ch * w
        qimg = QImage(rgb_image.data, w, h, bytes_per_line,
                      QImage.Format_RGB888)
        pixmap = QPixmap.fromImage(qimg)
        self.current_image.setPixmap(pixmap)
        self._scene.setSceneRect(0, 0, w, h)
        self.fitInView(self._scene.sceneRect(), Qt.KeepAspectRatio)

    def resizeEvent(self, e):
        self.fitInView(self._scene.sceneRect(), Qt.KeepAspectRatio)

    def wheelEvent(self, e):
        if e.angleDelta().y() > 0:
            self.scale(1.25, 1.25)
        elif e.angleDelta().y() < 0:
            self.scale(0.85, 0.85)

    def mousePressEvent(self, e):
        # シーン上のマウス位置を取得する
        pos = self.mapToScene(e.pos())
        if e.button() == Qt.LeftButton:
            if e.modifiers() == Qt.NoModifier:
                pass
            elif e.modifiers() == Qt.AltModifier:
                self.setDragMode(QGraphicsView.ScrollHandDrag)
        QGraphicsView.mousePressEvent(self, e)

    def mouseReleaseEvent(self, e):
        QGraphicsView.mouseReleaseEvent(self, e)
        if e.button() == Qt.LeftButton:
            self.setDragMode(QGraphicsView.NoDrag)

    def calc_offset(self, p: QPoint):
        offset_x = p.x() - int(self.viewport().width() / 2)
        offset_y = p.y() - int(self.viewport().height() / 2)
        return QPoint(offset_x, offset_y)
示例#17
0
 def __init__(self, parent: QWidget):
     super(QRotatableView, self).__init__(parent)
     scene = QGraphicsScene(self)
     self.setScene(scene)
     self.dial = QDial()
     self.dial.setMinimumSize(QSize(150, 150))
     self.dial.setSingleStep(100)
     self.dial.setPageStep(100)
     self.dial.setInvertedAppearance(True)
     self.dial.setWrapping(True)
     self.dial.setNotchTarget(0.1)
     self.dial.setNotchesVisible(True)
     self.dial.valueChanged.connect(self.__value_changed)
     self.set_maximum(360)
     graphics_item = scene.addWidget(self.dial)
     graphics_item.setRotation(-90)
     # make the QGraphicsView invisible.
     self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
     self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
     self.setFixedHeight(self.dial.height())
     self.setFixedWidth(self.dial.width())
     self.setStyleSheet("border: 0px;")
示例#18
0
    def __init__(self, parent=None):
        super(SvgView, self).__init__(parent)
        self.signal = NodeSignal()
        self.renderer = SvgView.Native
        self.__svg_items = []
        self.__wrapper_item = None
        self.__svg_renderer = QSvgRenderer()

        self.setScene(QGraphicsScene(self))
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setDragMode(QGraphicsView.ScrollHandDrag)
        self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
        self.setViewport(QWidget())
        self.setBackgroundBrush(
            QBrush(QColor(QPalette().color(QPalette.Active, QPalette.Window))))
示例#19
0
    def __init__(self, width, height, pixel_ratio, path):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # overwrite dimesions specified in slideShow3.py, as they are specific to MacBookPro display, and QTDesigner
        # has its own idea on what they should be.  This code should work on any size display
        self.resize(width, height)
        self.ui.graphicsView.setGeometry(QtCore.QRect(0, 0, width, height))
        self.ui.menubar.setGeometry(QtCore.QRect(0, 0, width, 0))

        self.width = width
        self.height = height
        self.pixel_ratio = pixel_ratio
        self.path = path
        self.imageFiles = []
        self.slideIndex = -1
        self.random_index_number = 0
        self.random = ""
        self.imageFiles, self.random_index, self.path, self.max_index = self.getImageNames2(
        )
        self.helpFile = os.path.join(
            os.path.dirname(os.path.realpath(sys.argv[0])), "instructions.png")
        #print(self.helpFile)
        self.scene = QGraphicsScene(self)
        #self.scene.setAlignment(QtCore.Qt.AlignCenter)
        self.ui.actionDir.triggered.connect(self.openFileNameDialog)
        self.ui.actionStart_Slide_Show.triggered.connect(self.slide_show)
        self.ui.actionRandom_Slide_Show.triggered.connect(
            self.random_slide_show)
        eventFilter = MouseEventFilter(self.scene)
        self.scene.installEventFilter(eventFilter)
        self.ui.actionHelp.triggered.connect(self.helpWindow)

        #self.show()
        self.showFullScreen()
示例#20
0
    def __init__(self, parent=None):

        super(DataGraphWidget, self).__init__(parent=parent)

        # Set up scene

        self.scene = QGraphicsScene(self)
        self.scene.setItemIndexMethod(QGraphicsScene.NoIndex)
        self.scene.setSceneRect(0, 0, 800, 300)

        self.setScene(self.scene)

        self.setWindowTitle("Glue data graph")

        self.setRenderHint(QPainter.Antialiasing)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QGraphicsView.AnchorViewCenter)

        self.selection_level = 0
    def __init__(self, parent=None):
        super(TestWidgetItem, self).__init__(parent)
        scene = QGraphicsScene()
        self.setScene(scene)

        self.line_item = LineItem()
        self.line_item.setLine(0, 0, 10, 10)

        self.line_item2 = LineItem()
        self.line_item2.setLine(30, 30, 40, 40)

        self.circle_item = CenterManipulatorItem()
        self.circle_item.setRect(10, 10, 50, 50)

        self.text_item = TextItem()

        self.scene().addItem(self.text_item)
        self.scene().addItem(self.circle_item)
        self.scene().addItem(self.line_item)
        self.scene().addItem(self.line_item2)

        self.scene().setSceneRect(0,0,100,100)
        self.setMouseTracking(True)
示例#22
0
    def __init__(self, item):
        super().__init__()

        self._shown = False
        self.modified_callback = None

        scene = QGraphicsScene()
        self.scene = scene

        self.scene_item = item
        scene.addItem(item)

        layout = QBoxLayout(QBoxLayout.TopToBottom, self)

        scene_view = View(self)
        self.scene_view = scene_view
        scene_view.setScene(scene)
        scene_view.setMinimumSize(350, 350)
        scene_view.setRenderHint(QPainter.Antialiasing)
        layout.addWidget(scene_view)

        self.double_click_callback = None
        self.mouse_press_callback = None
        if hasattr(self.scene_item, "mouse_pressed_in"):
            self.mouse_press_callback = self.scene_item.mouse_pressed_in
        if hasattr(self.scene_item, "double_clicked_in_background"):
            self.double_click_callback = \
                self.scene_item.double_clicked_in_background
        if hasattr(self.scene_item, "mouse_moved_in_scene"):
            self.scene_view.mouse_move_callback = \
                self.scene_item.mouse_moved_in_scene

        self.menus = []
        view_menu = QMenu("&View")
        self.view_menu = view_menu
        self.menus.append(view_menu)
        export_menu = QMenu("&Export")
        self.menus.append(export_menu)

        self.tools = []

        fit_action = QAction("&Fit", self)
        fit_action.setShortcut("0")
        fit_action.setIcon(QIcon.fromTheme("zoom-fit-best"))
        fit_action.setStatusTip("Fit the entire scene to the viewport")
        fit_action.triggered.connect(self.scene_view.fit_all_in_view)
        view_menu.addAction(fit_action)
        self.tools.append(fit_action)

        reset_action = QAction("&Reset (1:1)", self)
        reset_action.setShortcut("9")
        reset_action.setIcon(QIcon.fromTheme("zoom-original"))
        reset_action.setStatusTip("Reset the view to 100% scale")
        reset_action.triggered.connect(self.scene_view.reset_scale)
        view_menu.addAction(reset_action)
        self.tools.append(reset_action)

        zoom_in_action = QAction("Zoom &In", self)
        zoom_in_action.setShortcuts(["+", "="])
        zoom_in_action.setStatusTip("Zoom in")
        zoom_in_action.triggered.connect(lambda: self.scene_view.zoom_in())
        view_menu.addAction(zoom_in_action)

        zoom_out_action = QAction("Zoom &Out", self)
        zoom_out_action.setShortcuts(["-", "_"])
        zoom_out_action.setStatusTip("Zoom out")
        zoom_out_action.triggered.connect(lambda: self.scene_view.zoom_out())
        view_menu.addAction(zoom_out_action)

        export_svg_action = QAction("As &SVG...", self)
        export_svg_action.setStatusTip("Export the current tab as an SVG file")
        export_svg_action.triggered.connect(lambda: export_as_svg(self.scene))
        export_menu.addAction(export_svg_action)

        export_png_action = QAction("As PN&G...", self)
        export_png_action.setStatusTip("Export the current tab as an PNG file")
        export_png_action.triggered.connect(lambda: export_as_png(self.scene))
        export_menu.addAction(export_png_action)

        export_pdf_action = QAction("As &PDF...", self)
        export_pdf_action.setStatusTip("Export the current tab as an PDF file")
        export_pdf_action.triggered.connect(lambda: export_as_pdf(self.scene))
        export_menu.addAction(export_pdf_action)

        export_svg_clip_action = QAction("To Clipboard as SVG", self)
        export_svg_clip_action.setStatusTip(
            "Export the current tab to the clipoard in SVG format")
        export_svg_clip_action.triggered.connect(
            lambda: export_to_clipboard_as_svg(self.scene))
        export_menu.addAction(export_svg_clip_action)

        export_image_clip_action = QAction("To &Clipboard as Image", self)
        export_image_clip_action.setStatusTip(
            "Export the current tab to the clipoard as an image")
        export_image_clip_action.triggered.connect(
            lambda: export_to_clipboard_as_image(self.scene))
        export_menu.addAction(export_image_clip_action)

        self.resize(800, 600)
示例#23
0
class MyForm(QMainWindow):
    def __init__(self, width, height, pixel_ratio, path):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # overwrite dimesions specified in slideShow3.py, as they are specific to MacBookPro display, and QTDesigner
        # has its own idea on what they should be.  This code should work on any size display
        self.resize(width, height)
        self.ui.graphicsView.setGeometry(QtCore.QRect(0, 0, width, height))
        self.ui.menubar.setGeometry(QtCore.QRect(0, 0, width, 0))

        self.width = width
        self.height = height
        self.pixel_ratio = pixel_ratio
        self.path = path
        self.imageFiles = []
        self.slideIndex = -1
        self.random_index_number = 0
        self.random = ""
        self.imageFiles, self.random_index, self.path, self.max_index = self.getImageNames2(
        )
        self.helpFile = os.path.join(
            os.path.dirname(os.path.realpath(sys.argv[0])), "instructions.png")
        #print(self.helpFile)
        self.scene = QGraphicsScene(self)
        #self.scene.setAlignment(QtCore.Qt.AlignCenter)
        self.ui.actionDir.triggered.connect(self.openFileNameDialog)
        self.ui.actionStart_Slide_Show.triggered.connect(self.slide_show)
        self.ui.actionRandom_Slide_Show.triggered.connect(
            self.random_slide_show)
        eventFilter = MouseEventFilter(self.scene)
        self.scene.installEventFilter(eventFilter)
        self.ui.actionHelp.triggered.connect(self.helpWindow)

        #self.show()
        self.showFullScreen()

    extension = staticmethod(lambda f: f.split('.').pop().lower())
    filename = staticmethod(lambda f: f.split('/').pop())

    def openFileNameDialog(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        self.fileName, _ = QFileDialog.getOpenFileName(
            self,
            "QFileDialog.getOpenFileName()",
            "",
            "All Files (*);;Python Files (*.py)",
            options=options)
        if self.fileName:
            self.path = os.path.dirname(self.fileName)
            self.imageFiles = []
            self.random_index = []
            self.max_index = []
            self.imageFiles, self.random_index, self.path, self.max_index = self.getImageNames2(
            )
            self.slideIndex = self.imageFiles.index(self.fileName) - 1

    def getImageNames2(self):
        "get the names of all images on disc or from the web (which are cached locally)"

        if not self.path:
            self.path = os.getcwd()
        if self.path[-1] != '/':
            self.path += '/'
        try:
            os.listdir(self.path)
        except:
            error_dialog = QtWidgets.QErrorMessage()
            error_dialog.showMessage(
                'Error in path' + self.path
            )  # https://stackoverflow.com/questions/40227047/python-pyqt5-how-to-show-an-error-message-with-pyqt5
            return [], self.path

        for i in GlobDirectoryWalker(self.path, "*.*"):
            if os.path.isfile(i):
                if self.checkImageType(i): self.imageFiles.append(i)

        max_index = len(self.imageFiles) - 1

        self.imageFiles.sort()

        random_index = list(range(max_index + 1))
        random.shuffle(random_index)
        return self.imageFiles, random_index, self.path, max_index

    def slide(self, i):
        self.pixmap = QtGui.QPixmap()
        #self.pixmap.setAlignment(QtCore.Qt.AlignCenter)
        self.pixmap.load(self.imageFiles[i])
        self.pixmap.setDevicePixelRatio(
            self.pixel_ratio
        )  # https://stackoverflow.com/questions/50127246/pyqt-5-10-enabling-high-dpi-support-for-macos-poor-pixmap-quality
        #self.pixmap4 = self.pixmap.scaled(self.width * self.pixel_ratio, (self.height * self.pixel_ratio)-45, Qt.KeepAspectRatio)
        self.pixmap4 = self.pixmap.scaled(self.width * self.pixel_ratio,
                                          (self.height * self.pixel_ratio),
                                          Qt.KeepAspectRatio)
        try:
            self.scene.removeItem(self.item)
        except:
            print("failed to remove item")
        self.item = QGraphicsPixmapItem(self.pixmap4)
        self.scene.addItem(self.item)
        #myapp.setWindowTitle(os.path.basename(self.imageFiles[i]))
        self.setWindowTitle(os.path.basename(self.imageFiles[i]))
        self.ui.graphicsView.setScene(self.scene)

    def slide_show(self):
        self.random = 0
        self.next_slide()

    def random_slide_show(self):
        self.random = 1
        self.next_slide()

    def next_slide(self):
        if self.random == 0:
            self.increment_slide()
        else:
            self.random_next()

    def prev_slide(self):
        if self.random == 0:
            self.decrement_slide()
        else:
            self.random_prev()

    def random_next(self):
        "display the next random slide"
        self.random_index_number += 1
        try:
            self.slideIndex = self.random_index[self.random_index_number]
            self.slide(self.slideIndex)
        except IndexError:
            self.random_index_number = 0
            self.slideIndex = self.random_index[self.random_index_number]
            self.slide(self.slideIndex)
        return False

    def random_prev(self):
        "display the previous random slide"
        self.random_index_number -= 1
        #self.ImageWindow.clear()
        try:
            self.slideIndex = self.random_index[self.random_index_number]
            self.slide(self.slideIndex)
        except IndexError:
            self.random_index_number = self.max_index
            self.slideIndex = self.random_index[self.random_index_number]
            self.slide(self.slideIndex)
        return False

    def increment_slide(self):
        "display a higher slide"
        print("in increment_slide")
        self.slideIndex += 1
        if self.slideIndex > self.max_index:
            self.slideIndex = 0
            print('Max index hit')
        self.slide(self.slideIndex)
        return False

    def decrement_slide(self):
        "display a lower slide"
        self.slideIndex -= 1
        if self.slideIndex < 0:
            self.slideIndex = self.max_index
        self.slide(self.slideIndex)
        return False

    def checkImageType(self, f):
        "check to see if we have an file with an image extension"
        ext = self.extension(f)
        chk = [
            i for i in ['jpg', 'gif', 'ppm', 'tif', 'png', 'jpeg'] if i == ext
        ]
        if chk == []: return False
        return True

    def helpWindow(self):
        self.pixmap = QtGui.QPixmap()
        #self.pixmap.setAlignment(QtCore.Qt.AlignCenter)
        self.pixmap.load(self.helpFile)
        self.pixmap.setDevicePixelRatio(
            self.pixel_ratio
        )  # https://stackoverflow.com/questions/50127246/pyqt-5-10-enabling-high-dpi-support-for-macos-poor-pixmap-quality
        #self.pixmap4 = self.pixmap.scaled(self.width * self.pixel_ratio, (self.height * self.pixel_ratio)-45, Qt.KeepAspectRatio)
        self.pixmap4 = self.pixmap.scaled(self.width * self.pixel_ratio,
                                          (self.height * self.pixel_ratio),
                                          Qt.KeepAspectRatio)
        try:
            self.scene.removeItem(self.item)
        except:
            print("failed to remove item")
        self.item = QGraphicsPixmapItem(self.pixmap4)
        self.scene.addItem(self.item)
        #myapp.setWindowTitle(os.path.basename("Instructions"))
        self.setWindowTitle(os.path.basename("Instructions"))
        self.ui.graphicsView.setScene(self.scene)

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.Quit()
        if e.key() == Qt.Key_Q:
            self.Quit()
        if e.key() == Qt.Key_Space:
            self.next_slide()
        if e.key() == Qt.Key_N:
            self.random_next()
        if e.key() == Qt.Key_P:
            self.random_prev()
        if e.key() == Qt.Key_Comma:
            self.decrement_slide()
        if e.key() == Qt.Key_Period:
            self.increment_slide()
        if e.key() == Qt.Key_H:
            self.helpWindow = self.helpWindow()
        if e.key() == Qt.Key_BracketLeft:
            self.slideIndex = self.decrement_slide()

    def mousePressEvent(self, e):
        if e.button() == QtCore.Qt.LeftButton:
            print("trapped left mouse click")
            self.next_slide()
        if e.button() == QtCore.Qt.RightButton:
            print("trapped right mouse click")
            self.prev_slide()

    def Quit(self):
        sys.exit(app.exec_())
示例#24
0
class MapView(QGraphicsView):
    """A map of reaction boxes"""
    def __init__(self, appdata: CnaData, name: str):
        self.scene = QGraphicsScene()
        QGraphicsView.__init__(self, self.scene)
        palette = self.palette()
        palette.setColor(QPalette.Base, Qt.white)
        self.setPalette(palette)

        self.appdata = appdata
        self.name = name
        self.setAcceptDrops(True)
        self.drag = False
        self.reaction_boxes: Dict[str, ReactionBox] = {}
        self._zoom = 0
        self.drag = False
        self.drag_start = None

        # initial scale
        self._zoom = self.appdata.project.maps[self.name]["zoom"]
        if self._zoom > 0:
            for _ in range(1, self._zoom):
                self.scale(INCREASE_FACTOR, INCREASE_FACTOR)
        if self._zoom < 0:
            for _ in range(self._zoom, -1):
                self.scale(DECREASE_FACTOR, DECREASE_FACTOR)

        # connect events to methods
        self.horizontalScrollBar().valueChanged.connect(self.on_hbar_change)
        self.verticalScrollBar().valueChanged.connect(self.on_vbar_change)

    def on_hbar_change(self, x):
        self.appdata.project.maps[self.name]["pos"] = (
            x, self.verticalScrollBar().value())

    def on_vbar_change(self, y):
        self.appdata.project.maps[self.name]["pos"] = (
            self.horizontalScrollBar().value(), y)

    def dragEnterEvent(self, event: QGraphicsSceneDragDropEvent):
        event.setAccepted(True)
        event.accept()
        event.acceptProposedAction()

    def dragMoveEvent(self, event: QGraphicsSceneDragDropEvent):
        event.setAccepted(True)
        point = event.pos()
        point_item = self.mapToScene(point)
        r_id = event.mimeData().text()

        if r_id in self.appdata.project.maps[self.name]["boxes"].keys():
            self.appdata.project.maps[self.name]["boxes"][r_id] = (
                point_item.x(), point_item.y())
            self.mapChanged.emit(r_id)
        else:
            self.appdata.project.maps[self.name]["boxes"][r_id] = (
                point_item.x(), point_item.y())
            self.reactionAdded.emit(r_id)

        self.update()

    def dragLeaveEvent(self, _event):
        self.update()

    def dropEvent(self, event: QGraphicsSceneDragDropEvent):
        self.drag = False
        point = event.pos()
        point_item = self.mapToScene(point)
        identifier = event.mimeData().text()
        self.appdata.project.maps[self.name]["boxes"][identifier] = (
            point_item.x(), point_item.y())
        self.mapChanged.emit(identifier)
        self.update()

    def wheelEvent(self, event):
        modifiers = QApplication.queryKeyboardModifiers()
        if modifiers == Qt.ControlModifier:
            if event.angleDelta().y() > 0:
                self.appdata.project.maps[
                    self.name]["bg-size"] *= INCREASE_FACTOR
            else:
                self.appdata.project.maps[
                    self.name]["bg-size"] *= DECREASE_FACTOR

            self.mapChanged.emit("dummy")
            self.update()

        if event.angleDelta().y() > 0:
            self.zoom_in()
        else:
            self.zoom_out()

    def fit(self):
        self.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)

    def zoom_in(self):
        self._zoom += 1

        self.appdata.project.maps[self.name]["zoom"] = self._zoom
        self.scale(INCREASE_FACTOR, INCREASE_FACTOR)

    def zoom_out(self):
        self._zoom -= 1

        self.appdata.project.maps[self.name]["zoom"] = self._zoom
        self.scale(DECREASE_FACTOR, DECREASE_FACTOR)

    def mousePressEvent(self, event: QMouseEvent):
        self.drag = True
        self.drag_start = event.pos()
        super(MapView, self).mousePressEvent(event)

    def mouseMoveEvent(self, event: QGraphicsSceneMouseEvent):
        modifiers = QApplication.queryKeyboardModifiers()
        if modifiers == Qt.ControlModifier:
            if self.drag:
                point = event.pos()
                move_x = self.drag_start.x() - point.x()
                move_y = self.drag_start.y() - point.y()
                self.drag_start = point
                for key, val in self.appdata.project.maps[
                        self.name]["boxes"].items():
                    self.appdata.project.maps[self.name]["boxes"][key] = (
                        val[0] - move_x, val[1] - move_y)
                self.mapChanged.emit("dummy")
                self.update()
        else:
            if self.drag:
                self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
                self.translate(1, 1)
            super(MapView, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event: QMouseEvent):
        if self.drag:
            self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
            self.translate(1, 1)
        self.drag = False
        super(MapView, self).mouseReleaseEvent(event)

    def update_selected(self, string):

        for r_id in self.reaction_boxes:
            if string.lower() in r_id.lower():
                self.reaction_boxes[r_id].item.setHidden(False)
            elif string.lower() in self.reaction_boxes[r_id].name.lower():
                self.reaction_boxes[r_id].item.setHidden(False)
            else:
                self.reaction_boxes[r_id].item.setHidden(True)

    def focus_reaction(self, reaction: str):
        x = self.appdata.project.maps[self.name]["boxes"][reaction][0]
        y = self.appdata.project.maps[self.name]["boxes"][reaction][1]
        self.centerOn(x, y)

    def highlight_reaction(self, string):
        # hide other boxes
        # for id in self.reaction_boxes:
        #     self.reaction_boxes[id].item.setHidden(True)

        treffer = self.reaction_boxes[string]
        treffer.item.setHidden(False)

        treffer.set_color(Qt.magenta)

    def update(self):
        self.scene.clear()
        background = QGraphicsSvgItem(
            self.appdata.project.maps[self.name]["background"])
        background.setFlags(QGraphicsItem.ItemClipsToShape)
        background.setScale(self.appdata.project.maps[self.name]["bg-size"])
        self.scene.addItem(background)

        for r_id in self.appdata.project.maps[self.name]["boxes"]:
            try:
                name = self.appdata.project.cobra_py_model.reactions.get_by_id(
                    r_id).name
                box = ReactionBox(self, r_id, name)
                box.setPos(
                    self.appdata.project.maps[self.name]["boxes"][r_id][0],
                    self.appdata.project.maps[self.name]["boxes"][r_id][1])
                self.scene.addItem(box)
                self.reaction_boxes[r_id] = box
            except KeyError:
                print("failed to add reaction box for", r_id)

        self.set_values()

        # set scrollbars
        self.horizontalScrollBar().setValue(
            self.appdata.project.maps[self.name]["pos"][0])
        self.verticalScrollBar().setValue(
            self.appdata.project.maps[self.name]["pos"][1])

    def set_values(self):
        for r_id in self.appdata.project.maps[self.name]["boxes"]:
            if r_id in self.appdata.project.scen_values.keys():
                self.reaction_boxes[r_id].set_val_and_color(
                    self.appdata.project.scen_values[r_id])
            elif r_id in self.appdata.project.comp_values.keys():
                self.reaction_boxes[r_id].set_val_and_color(
                    self.appdata.project.comp_values[r_id])

    def remove_box(self, reaction: str):
        del self.appdata.project.maps[self.name]["boxes"][reaction]
        del self.reaction_boxes[reaction]
        self.update()
        self.reactionRemoved.emit(reaction)

    # def emit_doubleClickedReaction(self, reaction: str):
    #     print("emit_doubleClickedReaction")
    #     self.doubleClickedReaction.emit(reaction)

    def value_changed(self, reaction: str, value: str):
        self.reactionValueChanged.emit(reaction, value)
        self.reaction_boxes[reaction].recolor()

    switchToReactionMask = Signal(str)
    maximizeReaction = Signal(str)
    minimizeReaction = Signal(str)
    reactionRemoved = Signal(str)
    reactionValueChanged = Signal(str, str)
    reactionAdded = Signal(str)
    mapChanged = Signal(str)
示例#25
0
class CroppableCameraView(QGraphicsView):
    rectChanged = Signal(QRect)
    imageDisplayed = Signal(np.ndarray)
    videoStarted = Signal()
    mouseMoved = Signal(QMouseEvent)
    mousePressed = Signal(QMouseEvent)
    mouseReleased = Signal(QMouseEvent)

    def __init__(self, camera, **settings):
        super(CroppableCameraView, self).__init__()
        self.setRenderHint(QPainter.Antialiasing)
        self.cam = camera
        self.is_live = False
        self._cmin = 0
        self._cmax = None
        self.settings = settings
        self._selecting = False
        self.needs_resize = False
        self.latest_array = None

        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.scene = QGraphicsScene()
        #self.setFrameStyle(QFrame.NoFrame)
        self.setScene(self.scene)
        self.pixmapitem = self.scene.addPixmap(QPixmap())
        self._uncropped_pixmap = None

        self.setMouseTracking(True)

        self.start = None
        c1 = QColor(0, 100, 220, 150)
        self.c2 = QColor(0, 100, 220, 50)
        self.c3 = QColor(0, 100, 220, 0)
        pen = QPen(c1, 2)

        self.selrect = self.scene.addRect(1, 1, 1, 1, pen, self.c3)
        self.selrect.setZValue(100)
        self.selrect.hide()

    def enable_selecting(self):
        print("Selection enabled")
        self._selecting = True

    def disable_selecting(self):
        self._selecting = False

    def mousePressEvent(self, event):
        if self._selecting:
            print("Mouse pressed")
            if not self.selrect.isVisible():
                self.selrect.show()

            if event.button() == Qt.LeftButton:
                sp = self.mapToScene(event.pos())
                self.start = (sp.x(), sp.y())
                self.selrect.setRect(sp.x(), sp.y(), 0, 0)
                self.selrect.setBrush(self.c2)

        self.mousePressed.emit(event)

    def mouseMoveEvent(self, event):
        if self.start:
            x1, y1 = self.start
            sp = self.mapToScene(event.pos())

            # Image width, height in scene coords
            ir = self.pixmapitem.boundingRect()
            sr = self.pixmapitem.sceneTransform().mapRect(ir)

            size = self.pixmapitem.pixmap().size()
            x2 = max(sr.left(), min(sr.right()-1, sp.x()))
            y2 = max(sr.top(), min(sr.bottom()-1, sp.y()))
            x1, x2 = sorted((x1, x2))
            y1, y2 = sorted((y1, y2))
            self.selrect.setRect(x1, y1, x2-x1, y2-y1)

        self.mouseMoved.emit(event)

    def mouseReleaseEvent(self, event):
        if self.start and event.button() == Qt.LeftButton:
            self.start = None
            self.selrect.setBrush(self.c3)
            self.rectChanged.emit(self.selrect.rect().toRect())

        self.mouseReleased.emit(event)

    def update_rect(self, x, y, w, h):
        self.selrect.setRect(x, y, w, h)
        self.rectChanged.emit(self.selrect.rect().toRect())

    def hideRect(self):
        self.selrect.hide()

    def showRect(self):
        self.selrect.show()

    def setRectVisible(self, visible):
        self.selrect.setVisible(visible)

    def isRectVisible(self):
        return self.selrect.isVisible()

    def rect(self):
        """QRect of the selection in camera coordinates"""
        # selrect in _image_ (pixmap) coordinates
        i_selrect = self.pixmapitem.sceneTransform().inverted()[0].mapRect(self.selrect.rect())
        current_left = self.settings.get('left', 0)
        current_top = self.settings.get('top', 0)
        return i_selrect.toRect().translated(current_left, current_top)

    def crop_to_rect(self):
        was_live = self.is_live
        if was_live:
            self.stop_video()

        self.hideRect()

        rect = self.rect()
        self.settings['left'] = rect.left()
        self.settings['right'] = rect.right()
        self.settings['top'] = rect.top()
        self.settings['bot'] = rect.bottom()

        if was_live:
            self.start_video()
        else:
            if not self._uncropped_pixmap:
                self._uncropped_pixmap = self.pixmapitem.pixmap()
            self.pixmapitem.setPixmap(self._uncropped_pixmap.copy(rect))
            self.setFixedSize(rect.width(), rect.height())

    def uncrop(self):
        was_live = self.is_live
        if was_live:
            self.stop_video()

        for key in ['left', 'right', 'top', 'bot']:
            if key in self.settings:
                del self.settings[key]

        if was_live:
            self.start_video()
        else:
            pixmap = self._uncropped_pixmap
            self.pixmapitem.setPixmap(pixmap)

        ir = self.pixmapitem.boundingRect()
        sr = self.pixmapitem.sceneTransform().mapRect(ir)
        self.scene.setSceneRect(sr)
        self.setFixedSize(sr.width(), sr.height())

    def mapSceneToPixmap(self, pt):
        transform = self.pixmapitem.sceneTransform().inverted()[0]
        return transform.mapRect(pt) if isinstance(pt, (QRect, QRectF)) else transform.map(pt)

    def mapViewToPixmap(self, view_pt):
        scene_pt = self.mapToScene(view_pt)
        return self.mapSceneToPixmap(scene_pt)

    def mapPixmapToScene(self, pixmap_pt):
        transform = self.pixmapitem.sceneTransform()
        map_func = transform.mapRect if isinstance(pixmap_pt, (QRect, QRectF)) else transform.map
        return map_func(pixmap_pt)

    def mapSceneToCamera(self, sc_pt):
        px_pt = self.mapSceneToPixmap(sc_pt)
        return QPoint(px_pt.x() + self.settings.get('left', 0),
                      px_pt.y() + self.settings.get('top', 0))

    def set_image(self, image_arr):
        pixmap = QPixmap(self._array_to_qimage(image_arr))
        if not self.pixmapitem:
            self.pixmapitem = self.scene.addPixmap(pixmap)
        else:
            self.pixmapitem.setPixmap(pixmap)

        if self.needs_resize:
            self._autoresize_viewport()
            self.needs_resize = False

    def _autoresize_viewport(self):
        ir = self.pixmapitem.boundingRect()
        sr = self.pixmapitem.sceneTransform().mapRect(ir)
        self.scene.setSceneRect(sr)
        #self.setFixedSize(sr.width(), sr.height())
        self.resize(sr.width(), sr.height())
        #self.viewport().setMaximumSize(sr.width(), sr.height())
        d = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        self.setMaximumSize(sr.width() + 2*d, sr.height() + 2*d)

    def grab_image(self):
        arr = self.cam.grab_image(**self.settings)
        self.set_image(arr)
        self.latest_array = arr
        self.imageDisplayed.emit(arr)

    def start_video(self):
        timer = QTimer()
        self.timer = timer
        timer.timeout.connect(self._wait_for_frame)
        self.cam.start_live_video(**self.settings)
        timer.start(0)  # Run full throttle
        self.is_live = True
        self.needs_resize = True
        self.videoStarted.emit()

    def stop_video(self):
        self.timer.stop()
        self.cam.stop_live_video()
        self.is_live = False

    def _wait_for_frame(self):
        frame_ready = self.cam.wait_for_frame(timeout='0 ms')
        if frame_ready:
            arr = self.cam.latest_frame(copy=True)
            self.set_image(arr)
            self.latest_array = arr
            self.imageDisplayed.emit(arr)

    def _scale_image(self, arr):
        """Return a bytescaled copy of the image array"""
        if not self._cmax:
            self._cmax = arr.max()  # Set cmax once from first image
        return scipy.misc.bytescale(arr, self._cmin, self._cmax)

    def _lut_scale_image(self, arr):
        if not self._cmax:
            self._cmax = arr.max()
        lut = scipy.misc.bytescale(np.arange(2**16), self._cmin, self._cmax)
        return lut[arr]

    def _create_lut(self, k):
        A = 2**15
        B = 100  # k's scaling factor
        g = lambda i, k: A*((k-B)*i) / ((2*k)*x - (k+B)*A)

    def _array_to_qimage(self, arr):
        bpl = arr.strides[0]
        is_rgb = len(arr.shape) == 3

        if is_rgb and arr.dtype == np.uint8:
            format = QImage.Format_RGB32
            image = QImage(arr.data, self.cam.width, self.cam.height, bpl, format)
        elif not is_rgb and arr.dtype == np.uint8:
            # TODO: Somehow need to make sure data is ordered as I'm assuming
            format = QImage.Format_Indexed8
            image = QImage(arr.data, self.cam.width, self.cam.height, bpl, format)
            self._saved_img = arr
        elif not is_rgb and arr.dtype == np.uint16:
            arr = self._scale_image(arr)
            format = QImage.Format_Indexed8
            w, h = self.cam.width, self.cam.height
            image = QImage(arr.data, w, h, w, format)
            self._saved_img = arr  # Save a reference to keep Qt from crashing
        else:
            raise Exception("Unsupported color mode")

        return image
class Image_Note(QMainWindow, gui_window.Ui_MainWindow):
    def __init__(self, parent=None):
        super(Image_Note, self).__init__(parent)
        self.setupUi(self)
        self.button_browse.clicked.connect(self.browse_file)
        self.button_browse_pdf.clicked.connect(self.browse_pdf_file)

        self.slider.setMinimum(0)
        self.slider.setMaximum(100)
        self.slider.setValue(40)
        self.button_reset.clicked.connect(self.reset)
        self.slider.valueChanged.connect(self.sensitivity_slider)
        self.button_delete.clicked.connect(self.remove_residual_images)
        self.button_save.clicked.connect(self.save_image)
        self.button_pdf_save.clicked.connect(self.save_pdf)
        self.visibility_widgets()

    def visibility_widgets(self, disable: bool = False):
        self.all_widgets = [
            self.button_delete, self.button_pdf_save, self.button_reset,
            self.button_save, self.slider
        ]

        for widget in self.all_widgets:
            widget.setEnabled(disable)
            print(type(widget))

    def sensitivity_slider(self):
        value = self.slider.value()
        print(value)
        self.thumbnail_image = Image.open(self.thumbnail_address)
        self.thumbnail_address_converted = \
            file_handler.filepath_modified_suffix(
                self.thumbnail_address)
        convert_util.convert_sample(self.thumbnail_address,
                                    self.thumbnail_address_converted, value)
        self.load_graphics_image(self.thumbnail_address_converted)

    def reset(self):
        self.slider.setValue(40)
        self.thumbnail_image = Image.open(self.thumbnail_address)
        self.load_graphics_image(self.thumbnail_address)

    def remove_residual_images(self):
        file_handler.remove_file(self.thumbnail_address)
        file_handler.remove_file(self.thumbnail_address_converted)

    def save_image(self):
        value = self.slider.value()
        convert_util.convert_full_image(self.file_address,
                                        self.modified_image_address, value)

    def save_pdf(self):
        import os
        if not os.path.exists(self.modified_image_address):
            self.save_image()
        convert_util.convert_image_to_pdf(
            self.modified_image_address,
            file_handler.change_path_extension(self.modified_image_address,
                                               ".pdf"))

    # def pdf_convert(self):
    #     self.save_image()
    #     convert_util.convert_image_to_pdf(self.modified_image_address,
    #                                       file_handler.change_path_extension(  # noqa
    #                                           self.modified_image_address,
    #                                           ".pdf"))

    def browse_pdf_file(self):
        self.pdf_file_address = QFileDialog.getOpenFileName(
            self, 'Open PDF File')[0]
        # print(self.pdf_file_address[0])
        self.file_address = file_handler.change_path_extension(
            self.pdf_file_address, ".png")
        convert_util.convert_pdf_to_image(self.pdf_file_address,
                                          self.file_address)
        self.process_file()

    def browse_file(self):

        response = QFileDialog.getOpenFileName(self, 'Open Image File')
        self.file_address = response[0]
        if not os.path.exists(self.file_address):
            return
        # return
        self.process_file()

    def process_file(self):
        self.thumbnail_address: str = file_handler.filepath_modified_suffix(
            self.file_address, "_thumbnail")
        self.modified_image_address: str = \
            file_handler.filepath_modified_suffix(
                self.file_address)
        image_handler.save_thumbnail(Image.open(self.file_address),
                                     self.thumbnail_address)
        self.visibility_widgets(True)
        self.load_graphics_image(self.thumbnail_address)

    def load_graphics_image(self, image_address: str):
        self.graphics_scene = QGraphicsScene()
        self.graphics_scene.addPixmap(QPixmap(image_address))
        self.graphicsView.setScene(self.graphics_scene)
示例#27
0
class GraphicsView(QGraphicsView):

    def __init__(self, parent=None):

        super(GraphicsView, self).__init__(parent)

        self.scene = QGraphicsScene()
        self.pixmapItem = QGraphicsPixmapItem()
        self.scene.setSceneRect(0, 0, 500, 500)
        self.setScene(self.scene)
        self.scene.addItem(self.pixmapItem)
        #would eventually make this fit to size of screen, waiting cause it's annoying.

        self.buildingParams = []
        self.scalef = [1, 1]

        self.Buildings()
    
    def Buildings(self):
        
        filename = os.getcwd() + "\examplebuildings.png"
        img = cv2.imread(filename)
        imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        ret,thresh = cv2.threshold(imgray, 250, 255, 0)
        contours , h = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

        MinCntArea = 5000.
        MaxCntArea = 100000.

        for cnt in contours:
            
            if cv2.contourArea(cnt) > MinCntArea and cv2.contourArea(cnt) < MaxCntArea:
                
                cv2.drawContours(img, cnt, -1, (0, 255, 0), 3) # this is a green rectangle which shows the found contour

                #cv2.circle(img, (min(cnt.T[0][0]), min(cnt.T[1][0])), 4, 4) #makes a circle around the upper left corner

                #np.set_printoptions(threshold=np.inf) #this is to make it so that the whole numpy array prints to the terminal

                self.buildingParams.append([min(cnt.T[0][0]), min(cnt.T[1][0]), max(cnt.T[0][0])-min(cnt.T[0][0]), max(cnt.T[1][0])-min(cnt.T[1][0])]) # x, y, height, width
                
        # copy and paste these three lines if you would like to see what an opencv images looks like anywhere in the program
        #cv2.imshow('img', img)
        #cv2.waitKey(0)
        #cv2.destroyAllWindows()

        #cv2.rectangle(img, (self.buildingParams[0][0], self.buildingParams[0][1]), 
        #                   (self.buildingParams[0][0] + self.buildingParams[0][2], self.buildingParams[0][1] + self.buildingParams[0][3]),
        #                   (255, 0, 0), -1) # draws a blue filled in rectangle - did this to make sure I had the indicies correct for x, y, width, and height

        height, width, channel = img.shape
        bytesPerLine = 3*width
        qimg = QImage(img.data, width, height, bytesPerLine, QImage.Format_RGB888).rgbSwapped()

        ##### need to add not null checks here

        self.ogimage = QPixmap.fromImage(qimg)
        self.image = self.ogimage.scaled(self.scene.width(), self.scene.height())
        self.pixmapItem.setPixmap(self.image)

        self.updateScalef()
        self.buildingParams += self.scalef

        for i in range(len(self.buildingParams)-2):

            parameters = self.buildingParams
            rect = GraphicsRectItem(QRectF(QPointF(parameters[i][0] * parameters[4],
                                                                parameters[i][1] * parameters[5]),
                                                                QPointF((parameters[i][0] + parameters[i][2]) * parameters[4],
                                                                (parameters[i][1] + parameters[i][3]) * parameters[5])))
            
            rect.setAcceptHoverEvents(True)
            self.scene.addItem(rect)

        

    def updateScalef(self):

        self.scalef[0] = self.image.width()/self.ogimage.width()
        self.scalef[1] = self.image.height()/self.ogimage.height()

    def mousePressEvent(self, e):
        print(e.pos())
示例#28
0
        self._length = length

    def spacing(self):
        return self._spacing

    def setSpacing(self, spacing):
        self._spacing = spacing


if __name__ == '__main__':
    import sys
    from qtpy.QtWidgets import QApplication, QGraphicsView, QGraphicsScene
    from qtpy.QtGui import QCursor
    app = QApplication(sys.argv)
    v = QGraphicsView()
    s = QGraphicsScene()
    v.setSceneRect(0, 0, 200, 200)
    v.setScene(s)
    # GRADIENT
    g = drawColorTypeGradient(attrs.HUE, 100, 100)
    g.setFinalStop(0, 300)
    s.setBackgroundBrush(QBrush(g))

    #LINE
    l = DualColoredLineSegment()
    l.setLine(0, 0, 300, 300)
    s.addItem(l)

    v.show()
    v.move(QCursor.pos())
    sys.exit(app.exec_())
示例#29
0
class CroppableCameraView(QGraphicsView):
    rectChanged = Signal(QRect)
    imageDisplayed = Signal(np.ndarray)
    videoStarted = Signal()
    mouseMoved = Signal(QMouseEvent)
    mousePressed = Signal(QMouseEvent)
    mouseReleased = Signal(QMouseEvent)

    def __init__(self, camera, **settings):
        super(CroppableCameraView, self).__init__()
        self.setRenderHint(QPainter.Antialiasing)
        self.cam = camera
        self.is_live = False
        self._cmin = 0
        self._cmax = None
        self.settings = settings
        self._selecting = False
        self.needs_resize = False
        self.latest_array = None

        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.scene = QGraphicsScene()
        #self.setFrameStyle(QFrame.NoFrame)
        self.setScene(self.scene)
        self.pixmapitem = self.scene.addPixmap(QPixmap())
        self._uncropped_pixmap = None

        self.setMouseTracking(True)

        self.start = None
        c1 = QColor(0, 100, 220, 150)
        self.c2 = QColor(0, 100, 220, 50)
        self.c3 = QColor(0, 100, 220, 0)
        pen = QPen(c1, 2)

        self.selrect = self.scene.addRect(1, 1, 1, 1, pen, self.c3)
        self.selrect.setZValue(100)
        self.selrect.hide()

    def enable_selecting(self):
        print("Selection enabled")
        self._selecting = True

    def disable_selecting(self):
        self._selecting = False

    def mousePressEvent(self, event):
        if self._selecting:
            print("Mouse pressed")
            if not self.selrect.isVisible():
                self.selrect.show()

            if event.button() == Qt.LeftButton:
                sp = self.mapToScene(event.pos())
                self.start = (sp.x(), sp.y())
                self.selrect.setRect(sp.x(), sp.y(), 0, 0)
                self.selrect.setBrush(self.c2)

        self.mousePressed.emit(event)

    def mouseMoveEvent(self, event):
        if self.start:
            x1, y1 = self.start
            sp = self.mapToScene(event.pos())

            # Image width, height in scene coords
            ir = self.pixmapitem.boundingRect()
            sr = self.pixmapitem.sceneTransform().mapRect(ir)

            size = self.pixmapitem.pixmap().size()
            x2 = max(sr.left(), min(sr.right() - 1, sp.x()))
            y2 = max(sr.top(), min(sr.bottom() - 1, sp.y()))
            x1, x2 = sorted((x1, x2))
            y1, y2 = sorted((y1, y2))
            self.selrect.setRect(x1, y1, x2 - x1, y2 - y1)

        self.mouseMoved.emit(event)

    def mouseReleaseEvent(self, event):
        if self.start and event.button() == Qt.LeftButton:
            self.start = None
            self.selrect.setBrush(self.c3)
            self.rectChanged.emit(self.selrect.rect().toRect())

        self.mouseReleased.emit(event)

    def update_rect(self, x, y, w, h):
        self.selrect.setRect(x, y, w, h)
        self.rectChanged.emit(self.selrect.rect().toRect())

    def hideRect(self):
        self.selrect.hide()

    def showRect(self):
        self.selrect.show()

    def setRectVisible(self, visible):
        self.selrect.setVisible(visible)

    def isRectVisible(self):
        return self.selrect.isVisible()

    def rect(self):
        """QRect of the selection in camera coordinates"""
        # selrect in _image_ (pixmap) coordinates
        i_selrect = self.pixmapitem.sceneTransform().inverted()[0].mapRect(
            self.selrect.rect())
        current_left = self.settings.get('left', 0)
        current_top = self.settings.get('top', 0)
        return i_selrect.toRect().translated(current_left, current_top)

    def crop_to_rect(self):
        was_live = self.is_live
        if was_live:
            self.stop_video()

        self.hideRect()

        rect = self.rect()
        self.settings['left'] = rect.left()
        self.settings['right'] = rect.right()
        self.settings['top'] = rect.top()
        self.settings['bot'] = rect.bottom()

        if was_live:
            self.start_video()
        else:
            if not self._uncropped_pixmap:
                self._uncropped_pixmap = self.pixmapitem.pixmap()
            self.pixmapitem.setPixmap(self._uncropped_pixmap.copy(rect))
            self.setFixedSize(rect.width(), rect.height())

    def uncrop(self):
        was_live = self.is_live
        if was_live:
            self.stop_video()

        for key in ['left', 'right', 'top', 'bot']:
            if key in self.settings:
                del self.settings[key]

        if was_live:
            self.start_video()
        else:
            pixmap = self._uncropped_pixmap
            self.pixmapitem.setPixmap(pixmap)

        ir = self.pixmapitem.boundingRect()
        sr = self.pixmapitem.sceneTransform().mapRect(ir)
        self.scene.setSceneRect(sr)
        self.setFixedSize(sr.width(), sr.height())

    def mapSceneToPixmap(self, pt):
        transform = self.pixmapitem.sceneTransform().inverted()[0]
        return transform.mapRect(pt) if isinstance(
            pt, (QRect, QRectF)) else transform.map(pt)

    def mapViewToPixmap(self, view_pt):
        scene_pt = self.mapToScene(view_pt)
        return self.mapSceneToPixmap(scene_pt)

    def mapPixmapToScene(self, pixmap_pt):
        transform = self.pixmapitem.sceneTransform()
        map_func = transform.mapRect if isinstance(pixmap_pt,
                                                   (QRect,
                                                    QRectF)) else transform.map
        return map_func(pixmap_pt)

    def mapSceneToCamera(self, sc_pt):
        px_pt = self.mapSceneToPixmap(sc_pt)
        return QPoint(px_pt.x() + self.settings.get('left', 0),
                      px_pt.y() + self.settings.get('top', 0))

    def set_image(self, image_arr):
        pixmap = QPixmap(self._array_to_qimage(image_arr))
        if not self.pixmapitem:
            self.pixmapitem = self.scene.addPixmap(pixmap)
        else:
            self.pixmapitem.setPixmap(pixmap)

        if self.needs_resize:
            self._autoresize_viewport()
            self.needs_resize = False

    def _autoresize_viewport(self):
        ir = self.pixmapitem.boundingRect()
        sr = self.pixmapitem.sceneTransform().mapRect(ir)
        self.scene.setSceneRect(sr)
        #self.setFixedSize(sr.width(), sr.height())
        self.resize(sr.width(), sr.height())
        #self.viewport().setMaximumSize(sr.width(), sr.height())
        d = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        self.setMaximumSize(sr.width() + 2 * d, sr.height() + 2 * d)

    def grab_image(self):
        arr = self.cam.grab_image(**self.settings)
        self.set_image(arr)
        self.latest_array = arr
        self.imageDisplayed.emit(arr)

    def start_video(self):
        timer = QTimer()
        self.timer = timer
        timer.timeout.connect(self._wait_for_frame)
        self.cam.start_live_video(**self.settings)
        timer.start(0)  # Run full throttle
        self.is_live = True
        self.needs_resize = True
        self.videoStarted.emit()

    def stop_video(self):
        self.timer.stop()
        self.cam.stop_live_video()
        self.is_live = False

    def _wait_for_frame(self):
        frame_ready = self.cam.wait_for_frame(timeout='0 ms')
        if frame_ready:
            arr = self.cam.latest_frame(copy=True)
            self.set_image(arr)
            self.latest_array = arr
            self.imageDisplayed.emit(arr)

    def _scale_image(self, arr):
        """Return a bytescaled copy of the image array"""
        if not self._cmax:
            self._cmax = arr.max()  # Set cmax once from first image
        return scipy.misc.bytescale(arr, self._cmin, self._cmax)

    def _lut_scale_image(self, arr):
        if not self._cmax:
            self._cmax = arr.max()
        lut = scipy.misc.bytescale(np.arange(2**16), self._cmin, self._cmax)
        return lut[arr]

    def _create_lut(self, k):
        A = 2**15
        B = 100  # k's scaling factor
        g = lambda i, k: A * ((k - B) * i) / ((2 * k) * x - (k + B) * A)

    def _array_to_qimage(self, arr):
        bpl = arr.strides[0]
        is_rgb = len(arr.shape) == 3

        if is_rgb and arr.dtype == np.uint8:
            format = QImage.Format_RGB32
            image = QImage(arr.data, self.cam.width, self.cam.height, bpl,
                           format)
        elif not is_rgb and arr.dtype == np.uint8:
            # TODO: Somehow need to make sure data is ordered as I'm assuming
            format = QImage.Format_Indexed8
            image = QImage(arr.data, self.cam.width, self.cam.height, bpl,
                           format)
            self._saved_img = arr
        elif not is_rgb and arr.dtype == np.uint16:
            arr = self._scale_image(arr)
            format = QImage.Format_Indexed8
            w, h = self.cam.width, self.cam.height
            image = QImage(arr.data, w, h, w, format)
            self._saved_img = arr  # Save a reference to keep Qt from crashing
        else:
            raise Exception("Unsupported color mode")

        return image
 def load_graphics_image(self, image_address: str):
     self.graphics_scene = QGraphicsScene()
     self.graphics_scene.addPixmap(QPixmap(image_address))
     self.graphicsView.setScene(self.graphics_scene)
示例#31
0
class DataGraphWidget(QGraphicsView):

    selection_changed = Signal()

    def __init__(self, parent=None):

        super(DataGraphWidget, self).__init__(parent=parent)

        # Set up scene

        self.scene = QGraphicsScene(self)
        self.scene.setItemIndexMethod(QGraphicsScene.NoIndex)
        self.scene.setSceneRect(0, 0, 800, 300)

        self.setScene(self.scene)

        self.setWindowTitle("Glue data graph")

        self.setRenderHint(QPainter.Antialiasing)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QGraphicsView.AnchorViewCenter)

        self.selection_level = 0

    def resizeEvent(self, event):
        self.scene.setSceneRect(0, 0, self.width(), self.height())
        self.relayout(reorder=False)

    def relayout(self, reorder=True):

        # Update radius
        for node in self.nodes:
            node.radius = self.height() / 30.

        layout_simple_circle(self.nodes, self.edges,
                             center=(self.width() / 2, self.height() / 2),
                             radius=self.height() / 3, reorder=reorder)

        # Update edge positions
        for edge in self.edges:
            edge.update_position()

        # Set up labels
        self.left_nodes = [node for node in self.nodes if node.node_position[0] < self.width() / 2]
        self.left_nodes = sorted(self.left_nodes, key=lambda x: x.node_position[1], reverse=True)

        self.right_nodes = [node for node in self.nodes if node not in self.left_nodes]
        self.right_nodes = sorted(self.right_nodes, key=lambda x: x.node_position[1], reverse=True)

        for i, node in enumerate(self.left_nodes):
            y = self.height() - (i + 1) / (len(self.left_nodes) + 1) * self.height()
            node.label_position = self.width() / 2 - self.height() / 2, y

        for i, node in enumerate(self.right_nodes):
            y = self.height() - (i + 1) / (len(self.right_nodes) + 1) * self.height()
            node.label_position = self.width() / 2 + self.height() / 2, y

    def set_data_collection(self, data_collection):

        # Get data and initialize nodes
        self.data_to_nodes = dict((data, DataNode(data)) for data in data_collection)
        self.nodes = list(self.data_to_nodes.values())

        # Get links and set up edges
        self.edges = [Edge(self.data_to_nodes[data1], self.data_to_nodes[data2])
                      for data1, data2 in get_connections(data_collection.external_links)]

        # Figure out positions
        self.relayout()

        # Add nodes and edges to graph

        for node in self.nodes:
            node.add_to_scene(self.scene)

        for edge in self.edges:
            edge.add_to_scene(self.scene)

        self.text_adjusted = False

        self.selected_edge = None
        self.selected_node1 = None
        self.selected_node2 = None

    def set_links(self, links):

        for edge in self.edges:
            edge.remove_from_scene(self.scene)

        self.edges = [Edge(self.data_to_nodes[data1], self.data_to_nodes[data2])
                      for data1, data2 in get_connections(links)]

        for edge in self.edges:
            edge.update_position()

        for edge in self.edges:
            edge.add_to_scene(self.scene)

        self._update_selected_edge()

        self._update_selected_colors()

    def paintEvent(self, event):

        super(DataGraphWidget, self).paintEvent(event)

        if not self.text_adjusted:

            for node in self.nodes:

                width = node.label.boundingRect().width()
                height = node.label.boundingRect().height()

                transform = QTransform()
                if node in self.left_nodes:
                    transform.translate(-width, -height / 2)
                else:
                    transform.translate(0, -height / 2)

                node.label.setTransform(transform)

            self.text_adjusted = True

    def manual_select(self, data1=None, data2=None):
        if data1 is None and data2 is not None:
            data1, data2 = data2, data1
        if data2 is not None:
            self.selection_level = 2
        elif data1 is not None:
            self.selection_level = 1
        else:
            self.selection_level = 0
        self.selected_node1 = self.data_to_nodes.get(data1, None)
        self.selected_node2 = self.data_to_nodes.get(data2, None)
        self._update_selected_edge()
        self._update_selected_colors()

    def find_object(self, event):
        for obj in list(self.nodes) + self.edges:
            if obj.contains(event.localPos()):
                return obj

    def mouseMoveEvent(self, event):

        # TODO: Don't update until the end
        # TODO: Only select object on top

        selected = self.find_object(event)

        if selected is None:

            if self.selection_level == 0:
                self.selected_node1 = None
                self.selected_node2 = None
                self._update_selected_edge()
            elif self.selection_level == 1:
                self.selected_node2 = None
                self._update_selected_edge()

        elif isinstance(selected, DataNode):

            if self.selection_level == 0:
                self.selected_node1 = selected
                self.selected_node2 = None
            elif self.selection_level == 1:
                if selected is not self.selected_node1:
                    self.selected_node2 = selected
                    self._update_selected_edge()

        elif isinstance(selected, Edge):

            if self.selection_level == 0:
                self.selected_edge = selected
                self.selected_node1 = selected.node_source
                self.selected_node2 = selected.node_dest

        self._update_selected_colors()

        self.selection_changed.emit()

    def mousePressEvent(self, event):

        # TODO: Don't update until the end
        # TODO: Only select object on top

        selected = self.find_object(event)

        if selected is None:

            self.selection_level = 0
            self.selected_node1 = None
            self.selected_node2 = None

            self._update_selected_edge()

        elif isinstance(selected, DataNode):

            if self.selection_level == 0:
                self.selected_node1 = selected
                self.selection_level += 1
            elif self.selection_level == 1:
                if selected is self.selected_node1:
                    self.selected_node1 = None
                    self.selection_level = 0
                else:
                    self.selected_node2 = selected
                    self.selection_level = 2
            elif self.selection_level == 2:
                if selected is self.selected_node2:
                    self.selected_node2 = None
                    self.selection_level = 1
                else:
                    self.selected_node1 = selected
                    self.selected_node2 = None
                    self.selection_level = 1

            self._update_selected_edge()

        elif isinstance(selected, Edge):

            if self.selected_edge is selected and self.selection_level == 2:
                self.selected_edge = None
                self.selected_node1 = None
                self.selected_node2 = None
                self.selection_level = 0
            else:
                self.selected_edge = selected
                self.selected_node1 = selected.node_source
                self.selected_node2 = selected.node_dest
                self.selection_level = 2

        self.mouseMoveEvent(event)

    def _update_selected_edge(self):
        for edge in self.edges:
            if (edge.node_source is self.selected_node1 and edge.node_dest is self.selected_node2 or
                    edge.node_source is self.selected_node2 and edge.node_dest is self.selected_node1):
                self.selected_edge = edge
                break
        else:
            self.selected_edge = None

    def _update_selected_colors(self):

        colors = {}

        if self.selected_node1 is not None and self.selection_level < 2:

            direct, indirect = find_connections(self.selected_node1, self.nodes, self.edges)

            for node in self.nodes:
                if node in direct or node in indirect:
                    colors[node] = COLOR_CONNECTED
                else:
                    colors[node] = COLOR_DISCONNECTED

            for edge in self.edges:
                if (edge.node_source is self.selected_node1 or
                        edge.node_dest is self.selected_node1):
                    colors[edge] = COLOR_CONNECTED

        if self.selected_edge is not None:
            colors[self.selected_edge] = COLOR_SELECTED

        if self.selected_node1 is not None:
            colors[self.selected_node1] = COLOR_SELECTED

        if self.selected_node2 is not None:
            colors[self.selected_node2] = COLOR_SELECTED

        self.set_colors(colors)

    def set_colors(self, colors):

        for obj in list(self.nodes) + self.edges:
            default_color = '0.8' if isinstance(obj, DataNode) else '0.5'
            obj.color = colors.get(obj, default_color)
            obj.update()
示例#32
0
class DataGraphWidget(QGraphicsView):

    selection_changed = Signal()

    def __init__(self, parent=None):

        super(DataGraphWidget, self).__init__(parent=parent)

        # Set up scene

        self.scene = QGraphicsScene(self)
        self.scene.setItemIndexMethod(QGraphicsScene.NoIndex)
        self.scene.setSceneRect(0, 0, 800, 300)

        self.setScene(self.scene)

        self.setWindowTitle("Glue data graph")

        self.setRenderHint(QPainter.Antialiasing)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QGraphicsView.AnchorViewCenter)

        self.selection_level = 0

    def resizeEvent(self, event):
        self.scene.setSceneRect(0, 0, self.width(), self.height())
        self.relayout(reorder=False)

    def relayout(self, reorder=True):

        # Update radius
        for node in self.nodes:
            node.radius = self.height() / 30.

        layout_simple_circle(self.nodes,
                             self.edges,
                             center=(self.width() / 2, self.height() / 2),
                             radius=self.height() / 3,
                             reorder=reorder)

        # Update edge positions
        for edge in self.background_edges + self.edges:
            edge.update_position()

        # Set up labels
        self.left_nodes = [
            node for node in self.nodes
            if node.node_position[0] < self.width() / 2
        ]
        self.left_nodes = sorted(self.left_nodes,
                                 key=lambda x: x.node_position[1],
                                 reverse=True)

        self.right_nodes = [
            node for node in self.nodes if node not in self.left_nodes
        ]
        self.right_nodes = sorted(self.right_nodes,
                                  key=lambda x: x.node_position[1],
                                  reverse=True)

        for i, node in enumerate(self.left_nodes):
            y = self.height() - (i + 1) / (len(self.left_nodes) +
                                           1) * self.height()
            node.label_position = self.width() / 2 - self.height() / 2, y

        for i, node in enumerate(self.right_nodes):
            y = self.height() - (i + 1) / (len(self.right_nodes) +
                                           1) * self.height()
            node.label_position = self.width() / 2 + self.height() / 2, y

    def set_data_collection(self,
                            data_collection,
                            old_links=None,
                            new_links=None):

        # Get data and initialize nodes
        self.data_to_nodes = OrderedDict(
            (data, DataNode(data)) for data in data_collection)
        self.nodes = list(self.data_to_nodes.values())

        # Get links and set up edges

        if old_links:
            self.background_edges = [
                Edge(self.data_to_nodes[data1],
                     self.data_to_nodes[data2],
                     linewidth=1,
                     zindex=1) for data1, data2 in get_connections(
                         data_collection.external_links)
            ]
        else:
            self.background_edges = []

        if new_links:
            self.edges = [
                Edge(self.data_to_nodes[data1], self.data_to_nodes[data2])
                for data1, data2 in get_connections(new_links)
            ]
        else:
            self.edges = []

        # Figure out positions
        self.relayout()

        # Add nodes and edges to graph

        for node in self.nodes:
            node.add_to_scene(self.scene)

        for edge in self.background_edges + self.edges:
            edge.add_to_scene(self.scene)

        self.text_adjusted = False

        self.selected_edge = None
        self.selected_node1 = None
        self.selected_node2 = None

    def set_links(self, links):

        for edge in self.edges:
            edge.remove_from_scene(self.scene)

        self.edges = [
            Edge(self.data_to_nodes[data1], self.data_to_nodes[data2])
            for data1, data2 in get_connections(links)
        ]

        for edge in self.edges:
            edge.update_position()

        for edge in self.edges:
            edge.add_to_scene(self.scene)

        self._update_selected_edge()

        self._update_selected_colors()

    def paintEvent(self, event):

        super(DataGraphWidget, self).paintEvent(event)

        if not self.text_adjusted:

            for node in self.nodes:

                width = node.label.boundingRect().width()
                height = node.label.boundingRect().height()

                transform = QTransform()
                if node in self.left_nodes:
                    transform.translate(-width, -height / 2)
                else:
                    transform.translate(0, -height / 2)

                node.label.setTransform(transform)

            self.text_adjusted = True

    def manual_select(self, data1=None, data2=None):
        if data1 is None and data2 is not None:
            data1, data2 = data2, data1
        if data2 is not None:
            self.selection_level = 2
        elif data1 is not None:
            self.selection_level = 1
        else:
            self.selection_level = 0
        self.selected_node1 = self.data_to_nodes.get(data1, None)
        self.selected_node2 = self.data_to_nodes.get(data2, None)
        self._update_selected_edge()
        self._update_selected_colors()

    def find_object(self, event):
        for obj in list(self.nodes) + self.edges:
            if obj.contains(event.localPos()):
                return obj

    def mouseMoveEvent(self, event):

        # TODO: Don't update until the end
        # TODO: Only select object on top

        selected = self.find_object(event)

        if selected is None:

            if self.selection_level == 0:
                self.selected_node1 = None
                self.selected_node2 = None
                self._update_selected_edge()
            elif self.selection_level == 1:
                self.selected_node2 = None
                self._update_selected_edge()

        elif isinstance(selected, DataNode):

            if self.selection_level == 0:
                self.selected_node1 = selected
                self.selected_node2 = None
            elif self.selection_level == 1:
                if selected is not self.selected_node1:
                    self.selected_node2 = selected
                    self._update_selected_edge()

        elif isinstance(selected, Edge):

            if self.selection_level == 0:
                self.selected_edge = selected
                self.selected_node1 = selected.node_source
                self.selected_node2 = selected.node_dest

        self._update_selected_colors()

        self.selection_changed.emit()

    def mousePressEvent(self, event):

        # TODO: Don't update until the end
        # TODO: Only select object on top

        selected = self.find_object(event)

        if selected is None:

            self.selection_level = 0
            self.selected_node1 = None
            self.selected_node2 = None

            self._update_selected_edge()

        elif isinstance(selected, DataNode):

            if self.selection_level == 0:
                self.selected_node1 = selected
                self.selection_level += 1
            elif self.selection_level == 1:
                if selected is self.selected_node1:
                    self.selected_node1 = None
                    self.selection_level = 0
                else:
                    self.selected_node2 = selected
                    self.selection_level = 2
            elif self.selection_level == 2:
                if selected is self.selected_node2:
                    self.selected_node2 = None
                    self.selection_level = 1
                else:
                    self.selected_node1 = selected
                    self.selected_node2 = None
                    self.selection_level = 1

            self._update_selected_edge()

        elif isinstance(selected, Edge):

            if self.selected_edge is selected and self.selection_level == 2:
                self.selected_edge = None
                self.selected_node1 = None
                self.selected_node2 = None
                self.selection_level = 0
            else:
                self.selected_edge = selected
                self.selected_node1 = selected.node_source
                self.selected_node2 = selected.node_dest
                self.selection_level = 2

        self.mouseMoveEvent(event)

    def _update_selected_edge(self):
        for edge in self.edges:
            if (edge.node_source is self.selected_node1
                    and edge.node_dest is self.selected_node2
                    or edge.node_source is self.selected_node2
                    and edge.node_dest is self.selected_node1):
                self.selected_edge = edge
                break
        else:
            self.selected_edge = None

    def _update_selected_colors(self):

        colors = {}

        if self.selected_node1 is not None and self.selection_level < 2:

            direct, indirect = find_connections(self.selected_node1,
                                                self.nodes, self.edges)

            for node in self.nodes:
                if node in direct or node in indirect:
                    colors[node] = COLOR_CONNECTED
                else:
                    colors[node] = COLOR_DISCONNECTED

            for edge in self.edges:
                if (edge.node_source is self.selected_node1
                        or edge.node_dest is self.selected_node1):
                    colors[edge] = COLOR_CONNECTED

        if self.selected_edge is not None:
            colors[self.selected_edge] = COLOR_SELECTED

        if self.selected_node1 is not None:
            colors[self.selected_node1] = COLOR_SELECTED

        if self.selected_node2 is not None:
            colors[self.selected_node2] = COLOR_SELECTED

        self.set_colors(colors)

    def set_colors(self, colors):

        for obj in list(self.nodes) + self.edges:
            default_color = '0.8' if isinstance(obj, DataNode) else '0.5'
            obj.color = colors.get(obj, default_color)
            obj.update()
示例#33
0
class MovieSelectionWindow(QDialog):

    __scene__ = None
    __poster_url__ = 'https://image.tmdb.org/t/p/original'
    __possibilities__ = None
    acceptedId = -1

    def __init__(self, oFile, possibilities):
        self.acceptedId = -1
        QDialog.__init__(self)

        self.ui = Ui_MovieSelection()
        self.ui.setupUi(self)

        self.ui.btnEnterId.clicked.connect(self.enterId)
        self.ui.btnEnterTitle.clicked.connect(self.enterTitle)
        self.ui.btnAccept.clicked.connect(self.accept)

        self.ui.tablePossibilities.horizontalHeader().setVisible(True)
        self.ui.tablePossibilities.verticalHeader().setVisible(True)
        self.ui.tablePossibilities.cellClicked.connect(self.selectionChanged)
        self.ui.lblOriginalFile.setText(oFile)

        self.__possibilities__ = possibilities
        self.actualizeTable()

    def showImage(self, posterPath: str):
        self.removeImage()
        imgData = requests.get(self.__poster_url__ + posterPath)
        pix = QPixmap()
        pix.loadFromData(imgData.content)
        item = QGraphicsPixmapItem(pix)
        self.__scene__ = QGraphicsScene(self)
        self.__scene__.addItem(item)
        self.ui.graphicsView.setScene(self.__scene__)
        self.resizeImage()

    def removeImage(self):
        if self.__scene__ != None:
            self.__scene__.clear()
        self.__scene__ = None

    def resizeEvent(self, event):
        QDialog.resizeEvent(self, event)
        self.resizeImage()

    def resizeImage(self):
        if (self.__scene__ != None):
            self.ui.graphicsView.fitInView(self.__scene__.sceneRect(),
                                           mode=Qt.KeepAspectRatio)
            self.ui.graphicsView.show()

    def actualizeTable(self):
        self.ui.tablePossibilities.clearContents()

        r = 0
        for p in self.__possibilities__:
            if 'title' not in p.__dict__ or 'release_date' not in p.__dict__:
                self.__possibilities__.remove(p)
                continue
            self.ui.tablePossibilities.setRowCount(r + 1)
            self.ui.tablePossibilities.setItem(r, 0, QTableWidgetItem(p.title))
            self.ui.tablePossibilities.setItem(
                r, 1, QTableWidgetItem(p.release_date[:4]))
            r += 1

        self.ui.tablePossibilities.clearSelection()

    def selectionChanged(self, row, column):
        self.ui.txtOverview.clear()
        self.ui.txtOverview.appendPlainText(
            self.__possibilities__[row].overview)
        self.ui.lblTitle.setText(self.__possibilities__[row].title + ' (' +
                                 self.__possibilities__[row].release_date[:4] +
                                 ')')
        if self.__possibilities__[row].poster_path != None:
            self.showImage(self.__possibilities__[row].poster_path)
        else:
            self.removeImage()

    def enterId(self):
        select = CustomEnterWindow(True)
        select.setWindowModality(Qt.WindowModal)
        mw = qtmodern.windows.ModernWindow(select)
        mw.setWindowModality(Qt.WindowModal)
        mw.show()
        select.ui.txtId.setFocus()

        loop = QEventLoop()
        select.finished.connect(loop.quit)
        loop.exec()

        if select.result != None and select.result.isdecimal():
            self.acceptedId = int(select.result)
            self.close()

    def __enterTitleWindow__(self, search):
        select = CustomEnterWindow(False)
        select.setWindowModality(Qt.WindowModal)
        mw = qtmodern.windows.ModernWindow(select)
        mw.setWindowModality(Qt.WindowModal)
        mw.show()
        select.ui.txtId.setFocus()

        loop = QEventLoop()
        select.finished.connect(loop.quit)
        loop.exec()

        if select.result != None:
            self.__possibilities__ = search(select.result)
            self.actualizeTable()

    def enterTitle(self):
        self.__enterTitleWindow__(Movie().search)

    def accept(self):
        self.acceptedId = self.__possibilities__[
            self.ui.tablePossibilities.currentRow()].id
        self.close()
示例#34
0
 def __init__(self, *args, **kwargs):
     self.scene = QGraphicsScene()
     super(FlatStem, self).__init__(self.scene, *args, **kwargs)
示例#35
0
class FlatStem(MeristemDisplay, QGraphicsView):
    """A QTGraphics canvas to display a 2D (rolled out) view of a meristem."""

    def __init__(self, *args, **kwargs):
        self.scene = QGraphicsScene()
        super(FlatStem, self).__init__(self.scene, *args, **kwargs)

    def thin_line(self, colour=None):
        """Return a pen that draws a thin line in the given colour."""
        pen = QPen(colour) if colour else QPen()
        pen.setWidth(0)
        return pen

    def shadow_if_needed(self, bud):
        """Check if the bud crosses over the side bars, and if so draw a shadow bud on the opposite side."""
        angle = bud.angle2x(bud.angle + math.radians(self.viewing_angle[0]))
        if abs(angle) < math.pi * bud.radius - bud.scale:
            return

        if angle > 0:
            angle = angle - bud.scale - 2 * math.pi * bud.radius
        else:
            angle = angle - bud.scale + 2 * math.pi * bud.radius

        return self.scene.addEllipse(
            angle, -bud.height - bud.scale,
            bud.scale * 2, bud.scale * 2,
            self.thin_line(), QBrush(qtpy.QtGui.QColor(*(bud.html_colour + [100])))
        )

    def make_item(self, bud):
        """Add the given bud to the scene as a ball."""
        item = self.scene.addEllipse(
            bud.angle2x(bud.angle + math.radians(self.viewing_angle[0])) - bud.scale, -bud.height - bud.scale,
            bud.scale * 2, bud.scale * 2,
            self.thin_line(), QBrush(qtpy.QtGui.QColor(*bud.html_colour))
        )
        return item

    def set_scale(self):
        """Scale the view in accordance with the zoom level."""
        self.resetTransform()
        size = self.size()
        dist = math.sqrt(size.width() * size.height())/50.0
        zoom = math.pi * 300/(dist + self.zoom + 11)
        self.scale(zoom, zoom)

    def draw_side_bars(self):
        """Draw the bounding lines of the meristem."""
        if not self.displayables:
            return

        side_bar = self.thin_line(Qt.blue)
        top = max([b.radius for b in self.displayables if b.height < b.scale] or [0])
        for height in range(int(round(self.objects.height))):
            bottom = top
            top = max([b.radius for b in self.displayables if abs(b.height - height) < b.scale] or [0])

            bot_side_bar_pos = math.pi * bottom
            top_side_bar_pos = math.pi * top
            self.scene.addLine(-bot_side_bar_pos, -height + 0.5, -top_side_bar_pos, -height - 0.5, side_bar)
            self.scene.addLine(bot_side_bar_pos, -height + 0.5, top_side_bar_pos, -height - 0.5, side_bar)

    def redraw(self):
        """Redraw all objects on the scene."""
        for item in self.scene.items():
            self.scene.removeItem(item)

        # Draw all buds
        for bud in self.displayables:
            self.make_item(bud)
            self.shadow_if_needed(bud)

        self.draw_side_bars()

        self.set_scale()

    def select(self, event):
        """Select the item that is under the cursor (if enabled)."""
        if not self.can_select:
            return

        scene_pos = self.mapToScene(QPoint(event.x(), event.y()))
        x, y = scene_pos.x(), -scene_pos.y()
        offsets = (math.radians(self.viewing_angle[0]), 0)
        if self.objects.bounds_test(x, y, offsets) > 0:
            self.objects.select()

        # signal all and any slots that something new was selected
        self._signal_selected()