def __init__(self, port_mode, port_type, parent): QGraphicsPathItem.__init__(self) self.setParentItem(parent) self.m_port_mode = port_mode self.m_port_type = port_type # Port position doesn't change while moving around line self.p_itemX = self.scenePos().x() self.p_itemY = self.scenePos().y() self.p_width = parent.getPortWidth() if port_type == PORT_TYPE_AUDIO_JACK: pen = QPen(canvas.theme.line_audio_jack, 2) elif port_type == PORT_TYPE_MIDI_JACK: pen = QPen(canvas.theme.line_midi_jack, 2) elif port_type == PORT_TYPE_MIDI_ALSA: pen = QPen(canvas.theme.line_midi_alsa, 2) elif port_type == PORT_TYPE_PARAMETER: pen = QPen(canvas.theme.line_parameter, 2) else: qWarning( "PatchCanvas::CanvasBezierLineMov({}, {}, {}) - invalid port type" .format(port_mode2str(port_mode), port_type2str(port_type), parent)) pen = QPen(Qt.black) pen.setCapStyle(Qt.FlatCap) pen.setWidthF(pen.widthF() + 0.00001) self.setPen(pen)
def addPath(self): self.removePath() self.path = QGraphicsPathItem(self.sideWays.setPaintPath(True)) self.path.setPen(QPen(QColor(self.color), 3, Qt.DashDotLine)) self.path.setZValue(common['pathZ']) self.scene.addItem(self.path) self.pathSet = True
def visualize(self): """ called when user clicks draw lsystem. This visualizes the lsystem to allow setup before the actual lsystification takes place """ self.getdata() self.run_lsystem() old_group = self.layersModel.itemFromIndex( self.parent.layersList.currentIndex()).get_graphics_items_group() if old_group: self.parent.scene.removeItem(old_group) group = QGraphicsItemGroup() path = QPainterPath() for idx, point in enumerate( self.lsysteminterpreter.globalstate["pts"]): x = point[0][0][0] y = point[0][1][0] direction = point[1] x = x * self.xscale + self.xoffs y = y * self.yscale + self.yoffs if idx == 0: path.moveTo(x, y) else: path.lineTo(x, y) item = QGraphicsPathItem(path) pen = QPen() pen.setWidth(self.strokeWidth) item.setPen(pen) group.addToGroup(item) self.addNewGraphicsItems(group)
def _initLabel(self): """Display the length of the insertion.""" self._label = InsertionLabel(self) self._seq_item = QGraphicsPathItem(parent=self) self._seq_text = None self.show()
def __init__(self, point=QPointF(0,0), parent=None, scene=None,\ brush=QBrush(Qt.white, Qt.SolidPattern),\ pen=QPen(Qt.black, 2, Qt.SolidLine),\ orient='v', rsize=7) : self._lst_circle = None path = self.pathForPointV(point, scene, rsize) if orient=='v' else\ self.pathForPointH(point, scene, rsize) if orient=='h' else\ self.pathForPointR(point, scene, rsize) QGraphicsPathItem.__init__(self, path, parent) if scene is not None: scene.addItem(self) DragBase.__init__(self, parent, brush, pen) self.setAcceptHoverEvents(True) self.setAcceptTouchEvents(True) #self.setAcceptedMouseButtons(Qt.LeftButton) self.setPen(self._pen_pos) self.setBrush(self._brush) self.setFlags(self.ItemIsSelectable | self.ItemIsMovable) #self.setBoundingRegionGranularity(0.95) self._mode = ADD
def __init__(self, part_item, grid_type): """Summary previous_grid_bounds (tuple): a tuple corresponding to the bounds of the grid. Args: part_item (TYPE): Description grid_type (TYPE): Description """ super(GridItem, self).__init__(parent=part_item) self.setFlag(QGraphicsItem.ItemClipsChildrenToShape) self._path = None self.part_item = part_item self._path = QGraphicsPathItem(self) self.dots = (styles.DOT_SIZE, styles.DOT_SIZE / 2) # self.allow_snap = part_item.window().action_vhelix_snap.isChecked() self._draw_gridpoint_coordinates = False self.draw_lines = False self.points = [] self.points_dict = dict() self.previous_grid_bounds = None self.bounds = None self.grid_type = None self.setPen( getPenObj(styles.GRAY_STROKE, styles.EMPTY_HELIX_STROKE_WIDTH)) self.setGridType(grid_type) self.previous_grid_type = grid_type
def __init__(self, from_virtual_helix_item: PathVirtualHelixItemT, is_fwd: bool, from_index: int, nearby_idxs: List[int], to_vh_id_num: int, prexoveritem_manager: PreXoverManagerT): """Summary Args: from_virtual_helix_item: Description is_fwd: is this a forward strand? from_index: index of the Virtual Helix this xover is coming from nearby_idxs: to_vh_id_num: Virtual Helix number this Xover point might connect to prexoveritem_manager: Manager of the PreXoverItems """ super(QGraphicsRectItem, self).__init__(BASE_RECT, from_virtual_helix_item) self.adapter = PropertyWrapperObject(self) self._tick_marks = QGraphicsPathItem(self) self._tick_marks.setAcceptHoverEvents(True) self._bond_item = QGraphicsPathItem(self) self._bond_item.hide() self._label = PreXoverLabel(is_fwd, self) self._path = QGraphicsPathItem() self.setZValue(styles.ZPREXOVERITEM) self.setPen(getNoPen()) self.resetItem(from_virtual_helix_item, is_fwd, from_index, nearby_idxs, to_vh_id_num, prexoveritem_manager) self._getActiveTool = from_virtual_helix_item.viewroot().manager.activeToolGetter
def __init__(self, *args, **kwargs): KineticsDisplayItem.__init__(self, *args, **kwargs) points = [ QtCore.QPointF(0, TableItem.defaultWidth / 2), QtCore.QPointF(TableItem.defaultHeight / 2 - 2, 0), QtCore.QPointF(TableItem.defaultWidth / 2 + 2, 0), QtCore.QPointF(TableItem.defaultWidth, TableItem.defaultHeight / 2), ] path = QtGui.QPainterPath() path.moveTo(points[0]) for p in points[1:]: path.lineTo(p) path.moveTo(p) path.moveTo(0, 0) path.lineTo(TableItem.defaultWidth, 0) path.moveTo(-(TableItem.defaultWidth / 3), TableItem.defaultHeight / 4) path.lineTo((TableItem.defaultWidth + 10), TableItem.defaultHeight / 4) self.gobj = QGraphicsPathItem(path, self) #self.gobj.setToolTip("Need to see what to show unlike conc/nint for pool") tabledoc = (moose.element(self.mobj.path)).outputValue self.gobj.setToolTip(str(tabledoc)) self.gobj.setPen( QtGui.QPen(QtCore.Qt.black, 2, Qt.Qt.SolidLine, Qt.Qt.RoundCap, Qt.Qt.RoundJoin)) self.gobj.mobj = self.mobj
def __init__(self, parent=None, **kwargs): Annotation.__init__(self, parent, **kwargs) self.setFlag(QGraphicsItem.ItemIsMovable) self.setFlag(QGraphicsItem.ItemIsSelectable) self.setFocusPolicy(Qt.ClickFocus) self.__textMargins = (2, 2, 2, 2) rect = self.geometry().translated(-self.pos()) ################################ # PyQt 5.10 crashes because of this call (3) #self.__framePathItem = QGraphicsPathItem(self) self.__framePathItem = QGraphicsPathItem(None) self.__framePathItem.setPen(QPen(Qt.NoPen)) self.__textItem = GraphicsTextEdit(self) self.__textItem.setPlaceholderText(self.tr("Enter text here")) self.__textItem.setPos(2, 2) self.__textItem.setTextWidth(rect.width() - 4) self.__textItem.setTabChangesFocus(True) self.__textItem.setTextInteractionFlags(Qt.NoTextInteraction) self.__textItem.setFont(self.font()) self.__textInteractionFlags = Qt.NoTextInteraction layout = self.__textItem.document().documentLayout() layout.documentSizeChanged.connect(self.__onDocumentSizeChanged) self.__updateFrame()
def __init__(self, radius: float, center_x: float, center_y: float, start_angle: float, end_angle: float, clockwise, line_width: float, line_color=Qt.black, fill_color=Qt.transparent): super().__init__() # The supporting rectangle if end_angle < start_angle: end_angle += 2 * math.pi start_angle = -start_angle end_angle = -end_angle shift = end_angle - start_angle if clockwise: shift = -shift - 2 * math.pi x, y = center_x - radius, center_y - radius self.rect = QRectF(x, y, 2 * radius, 2 * radius) # The underlying QGraphicsPathItem self.painter_path = QPainterPath( QPointF(center_x + math.cos(start_angle) * radius, center_y - math.sin(start_angle) * radius)) self.painter_path.arcTo(self.rect, math.degrees(start_angle), math.degrees(shift)) self.path = QGraphicsPathItem(self.painter_path) self.path.setBrush(QtGui.QBrush(fill_color)) pen = QPen() pen.setWidthF(line_width) pen.setColor(line_color) self.path.setPen(pen) self._visible = 1
def __init__(self, virtual_helix_item, xover_item, strand3p, idx): """Summary Args: virtual_helix_item (cadnano.views.pathview.virtualhelixitem.VirtualHelixItem): from vhi xover_item (TYPE): Description strand3p (Strand): reference to the 3' strand idx (int): the base index within the virtual helix """ super(ForcedXoverNode3, self).__init__(virtual_helix_item) self._vhi = virtual_helix_item self._xover_item = xover_item self._idx = idx self.is_forward = strand3p.strandSet().isForward() self._is_on_top = self.is_forward self._partner_virtual_helix = virtual_helix_item self._blank_thing = QGraphicsRectItem(_blankRect, self) self._blank_thing.setBrush(QBrush(Qt.white)) self._path_thing = QGraphicsPathItem(self) self.configurePath() self._label = None self.setPen(_NO_PEN) self.setBrush(_NO_BRUSH) self.setRect(_rect) self.setZValue(styles.ZENDPOINTITEM + 1)
def mousePressEvent(self, evt: QtGui.QMouseEvent) -> None: image_rect : QRectF=self._pixmap.boundingRect() mouse_pos = self.mapToScene(evt.pos()) if evt.buttons() == QtCore.Qt.LeftButton: if self.current_tool == SELECTION_TOOL.BOX: # create rectangle self.setDragMode(QGraphicsView.NoDrag) self._rectangle_tool_origin=evt.pos() geometry = QRect(self._rectangle_tool_origin,QSize()) self._rectangle_tool_picker.setGeometry(geometry) self._rectangle_tool_picker.show() elif self.current_tool == SELECTION_TOOL.POLYGON: if image_rect.contains(mouse_pos): if self._current_polygon is None: self._current_polygon=EditablePolygon() self._current_polygon.label = self._current_label self._current_polygon.tag = self._dataset self._current_polygon.signals.deleted.connect(self.delete_polygon_slot) self._scene.addItem(self._current_polygon) self._current_polygon.addPoint(mouse_pos) else: self._current_polygon.addPoint(mouse_pos) elif self.current_tool == SELECTION_TOOL.ELLIPSE: if image_rect.contains(mouse_pos): self.setDragMode(QGraphicsView.NoDrag) ellipse_rec=QtCore.QRectF(mouse_pos.x(),mouse_pos.y(),0,0) self._current_ellipse=EditableEllipse() self._current_ellipse.tag = self.dataset self._current_ellipse.label=self._current_label self._current_ellipse.setRect(ellipse_rec) self._scene.addItem(self._current_ellipse) elif self.current_tool == SELECTION_TOOL.FREE: # consider only the points into the image if image_rect.contains(mouse_pos): self.setDragMode(QGraphicsView.NoDrag) self._last_point_drawn=mouse_pos self._current_free_path=QGraphicsPathItem() self._current_free_path.setOpacity(0.6) self._current_free_path.setPen(self._free_Path_pen) painter=QPainterPath() painter.moveTo(self._last_point_drawn) self._current_free_path.setPath(painter) self._scene.addItem(self._current_free_path) elif self.current_tool == SELECTION_TOOL.EXTREME_POINTS: if image_rect.contains(mouse_pos): if not self._extreme_points.full(): def delete_point(idx): del self._extreme_points.queue[idx] idx=self._extreme_points.qsize() editable_pt=EditablePolygonPoint(idx) editable_pt.signals.deleted.connect(delete_point) editable_pt.setPos(mouse_pos) self._scene.addItem(editable_pt) self._extreme_points.put(editable_pt) else: self.setDragMode(QGraphicsView.ScrollHandDrag) super(ImageViewer, self).mousePressEvent(evt)
def drawGlyph(self, scene, glyph, offsetX=0, offsetY=0, color=(255, 255, 255)): path = QPainterPath() path.setFillRule(Qt.WindingFill) for c in self.decomposedPaths(glyph): segs = c.segments path.moveTo(segs[-1].points[-1].x, segs[-1].points[-1].y) for seg in segs: tuples = [(a.x, a.y) for a in seg.points] flattuples = list(sum(tuples, ())) if len(tuples) == 2: path.quadTo(*flattuples) elif len(tuples) == 3: path.cubicTo(*flattuples) else: path.lineTo(*flattuples) line = QGraphicsPathItem() line.setBrush(QColor(*color)) p = QPen() p.setStyle(Qt.NoPen) line.setPen(p) line.setPath(path) reflect = QTransform(1, 0, 0, -1, 0, 0) reflect.translate(offsetX, offsetY) # print(f"Drawing {glyph} at offset {offsetX} {offsetY}") line.setTransform(reflect) scene.addItem(line)
def __init__(self, from_virtual_helix_item: PathVirtualHelixItemT, is_fwd: bool, from_index: int, nearby_idxs: List[int], to_vh_id_num: int, prexoveritem_manager: PreXoverManagerT): """Summary Args: from_virtual_helix_item: Description is_fwd: is this a forward strand? from_index: index of the Virtual Helix this xover is coming from nearby_idxs: to_vh_id_num: Virtual Helix number this Xover point might connect to prexoveritem_manager: Manager of the PreXoverItems """ super(QGraphicsRectItem, self).__init__(BASE_RECT, from_virtual_helix_item) self.adapter = PropertyWrapperObject(self) self._tick_marks = QGraphicsPathItem(self) self._tick_marks.setAcceptHoverEvents(True) self._bond_item = QGraphicsPathItem(self) self._bond_item.hide() self._label = PreXoverLabel(is_fwd, self) self._path = QGraphicsPathItem() self.setZValue(styles.ZPREXOVERITEM) self.setPen(getNoPen()) self.resetItem(from_virtual_helix_item, is_fwd, from_index, nearby_idxs, to_vh_id_num, prexoveritem_manager) self._getActiveTool = from_virtual_helix_item.viewroot( ).manager.activeToolGetter
def paint(self, painter, option, widget=None): """Overload QGraphicsPathItem method.""" new_option = QStyleOptionGraphicsItem(option) # suppress the "selected" state # this avoids the dashed rectangle surrounding the ray when selected new_option.state = QStyle.State_None QGraphicsPathItem.paint(self, painter, new_option, widget)
def small_size(self): global item, new_pathitem, new_path pen.setWidth(5) new_pathitem = QGraphicsPathItem() new_pathitem.setPen(pen) new_path = QPainterPath() item = new_pathitem scene.addItem(item)
def colour(self): global item, new_pathitem, new_path pen.setColor(QColorDialog.getColor()) new_pathitem = QGraphicsPathItem() new_pathitem.setPen(pen) new_path = QPainterPath() item = new_pathitem scene.addItem(item)
def updateNewPath(self): if self.pts: ## list of points self.removeNewPath() ## clean up just in case self.newPath = QGraphicsPathItem(self.sideWays.setPaintPath()) self.newPath.setPen(QPen(QColor(self.color), 3, Qt.DashDotLine)) self.newPath.setZValue(common['pathZ']) self.scene.addItem(self.newPath) ## only one - no group needed self.newPathSet = True
def __init__(self, annotation_item, path, parent=None): """ Extends PyQt5's QGraphicsPathItem to create the general structure of the Grabbable points for resizing shapes. """ QGraphicsPathItem.__init__(self, parent) self.m_annotation_item = annotation_item # set path of item self.setPath(path) self.setAcceptHoverEvents(True) self.setCursor(QCursor(Qt.PointingHandCursor))
def keyPressEvent(self, event): """ Must intercept invalid input events. Make changes here """ a = event.key() # print("forced xover keypress", a) if a in [Qt.Key_Control, Qt.Key_Left, Qt.Key_Right, Qt.Key_Up, Qt.Key_Down]: QGraphicsPathItem.keyPressEvent(self, event) else: self._tool.setFloatingXoverBegin(True)
def __init__(self, parent: QGraphicsItem = None): """ Args: parent: default is ``None`` """ super(PathWorkplaneOutline, self).__init__(parent) self.setPen(getNoPen()) self._path = QGraphicsPathItem(self) self._path.setBrush(getNoBrush()) self._path.setPen(newPenObj(styles.BLUE_STROKE, 0))
def createNetPath(self, brushColor: str, painterPath: QPainterPath, isOccupyPathItem: bool): """ Create a QGraphicsPathItem for a network path Args: brushColor (str) : The color for filling the rectangles painterPath (QPainterPath) : The path to be inserted to the item isOccupyPathItem (bool) : Whether the path is occupied or unoccupied path """ # Generate the path item if not created if isOccupyPathItem: if self.occupiedPathItem is None: self.occupiedPathItem = QGraphicsPathItem(self) pathItem = self.occupiedPathItem else: if self.unoccupiedPathItem is None: self.unoccupiedPathItem = QGraphicsPathItem(self) pathItem = self.unoccupiedPathItem if pathItem is None: pathItem = QGraphicsPathItem(self) # Set the item parameters pathItem.setPath(painterPath) pathItem.setPen(QPen(QColor(self.netColor), self.netThickness, style=Qt.SolidLine)) pathItem.setBrush(QBrush(QColor(brushColor))) pathItem.setZValue(0)
def __init__(self): super(Canvas, self).__init__() global scene scene = QGraphicsScene() self.setScene(scene) self.path1 = QPainterPath() self.path2 = QPainterPath() global viewport viewport = self.viewport() global new_path new_path = QPainterPath() global pathitem1, pathitem2, new_pathitem pathitem1 = QGraphicsPathItem() pathitem2 = QGraphicsPathItem() new_pathitem = QGraphicsPathItem() global pen pen = QPen(Qt.black, 10) pathitem1.setPen(pen) eraser = QPen(Qt.white, 10) pathitem2.setPen(eraser) global item item = pathitem1 scene.addItem(item)
def loadfrom(self): global filename, item, new_path, new_pathitem filename = QFileDialog.getOpenFileName(None, 'Choose file')[0] pixmap = QPixmap(filename) scene.addPixmap(pixmap) new_pathitem = QGraphicsPathItem() new_pathitem.setPen(pen) new_path = QPainterPath() item = new_pathitem scene.addItem(item)
def finish(self): """ return the wrapped up result of the calculations :return: qgraphicsitemgroup """ item = QGraphicsPathItem(self.path) pen = QPen() pen.setWidth(self.strokeWidth) item.setPen(pen) self.group.addToGroup(item) self.prevPos = None return self.group
def mousePressEvent(self, e): pe = e.pos() ps = e.scenePos() pc = self.path().currentPosition() logger.debug( 'DragPoint.mousePressEvent at point (%6.1f, %6.1f) on scene (%6.1f, %6.1f) currentPosition (%6.1f, %6.1f)' % (pe.x(), pe.y(), ps.x(), ps.y(), pc.x(), pc.y())) self.setSelected(True) #print("DragPoint is selected: ", self.isSelected()) QGraphicsPathItem.mousePressEvent(self, e) parent = self.parentItem() if parent is not None: parent.mousePressEvent(e)
def mouseReleaseEvent(self, e): pe = e.pos() ps = e.scenePos() logger.debug( 'DragPoint.mouseReleaseEvent at point (%6.1f, %6.1f) on scene (%6.1f, %6.1f)' % (pe.x(), pe.y(), ps.x(), ps.y())) self.setSelected(False) QGraphicsPathItem.mouseReleaseEvent(self, e) if self._drag_mode == ADD: self.set_drag_mode() if self.parentItem() is not None: self.parentItem().mouseReleaseEvent(e)
def itemChange(self, change, value): return QGraphicsPathItem.itemChange(self, change, value) # for selection changes test against QGraphicsItem.ItemSelectedChange # intercept the change instead of the has changed to enable features. if change == QGraphicsItem.ItemSelectedChange and self.scene(): active_tool = self._getActiveTool() if active_tool.methodPrefix() == "selectTool": sI = self._strand_item viewroot = sI.viewroot() current_filter_dict = viewroot.selectionFilterDict() selection_group = viewroot.strandItemSelectionGroup() # only add if the selection_group is not locked out if value == True and (self._filterName in current_filter_dict or not selection_group.isNormalSelect()): if sI.strandFilter() in current_filter_dict: # print "might add a xoi" if self.group() != selection_group and selection_group.isNormalSelect(): # print "adding an xoi" selection_group.pendToAdd(self) selection_group.setSelectionLock(selection_group) self.setSelectedColor(True) return True else: # print "Doh" return False # end if elif value == True: # print "DOink" return False else: # Deselect # Check if the strand is being added to the selection group still if not selection_group.isPending(self._strand_item): selection_group.pendToRemove(self) self.tempReparent() self.setSelectedColor(False) return False else: # don't deselect it, because the strand is selected still return True # end else # end if elif str(active_tool) == "paint_tool": sI = self._strand_item viewroot = sI.viewroot() current_filter_dict = viewroot.selectionFilterDict() if sI.strandFilter() in current_filter_dict: if not active_tool.isMacrod(): active_tool.setMacrod() self.paintToolMousePress() return False # end if return QGraphicsPathItem.itemChange(self, change, value)
def __init__(self, item1, item2, parent): QGraphicsPathItem.__init__(self) self.setParentItem(parent) self.item1 = item1 self.item2 = item2 self.m_locked = False self.m_lineSelected = False self.setBrush(QColor(0, 0, 0, 0)) self.setGraphicsEffect(None) self.updateLinePos()
def keyPressEvent(self, event): """ Must intercept invalid input events. Make changes here """ a = event.key() # print("forced xover keypress", a) if a in [ Qt.Key_Control, Qt.Key_Left, Qt.Key_Right, Qt.Key_Up, Qt.Key_Down ]: QGraphicsPathItem.keyPressEvent(self, event) else: self._tool.setFloatingXoverBegin(True)
def __init__(self, node1, node2, engine, cost=None): super().__init__() self.node1 = node1 self.node2 = node2 self.engine = engine self.cost = cost self.arrow_length = 15 self.setPen(self.node1.pen) # Crearea unui path invizibil si adaugarea lui in scene self.direct_path = QGraphicsPathItem() self.direct_path.setPen(QPen(QColor(0, 0, 0, 0))) self.engine.view.scene.addItem(self.direct_path)
def initCharPath(self): """ Init the item that holds the character There is one path item that holds the character This method is activated by start line if the char item was not created to create the new and only one """ self.dirty = True self.charPath = QGraphicsPathItem(self) self.charPath.setPen( QPen(QColor(self.shapeColor), self.shapeLineThickness)) self.charPath.setZValue(1) self.charPath.originalPos = self.charPath.pos() self.charPath.setPath(QPainterPath())
def __init__(self, virtual_helix_item, strand, insertion): super(InsertionItem, self).__init__(virtual_helix_item) self.hide() self._strand = strand self._insertion = insertion self._seq_item = QGraphicsPathItem(parent=self) self._is_on_top = is_on_top = virtual_helix_item.isStrandOnTop(strand) y = 0 if is_on_top else _BW self.setPos(_BW * insertion.idx(), y) self.setZValue(styles.ZINSERTHANDLE) self._initLabel() self._initClickArea() self.updateItem() self.show()
def __init__(self, pituus, kulma, scene, sijainti = None, suunta = None): ''' Luo uuden ratapalan, joko sen pituuden ja kulman avulla, jolloin pala lisätään edellisen perään, tai käyttäen koordinaatteja sijainti ja suunta. Tämän konstruktorin toiminta on hieman omalaatuinen, se on selitetty seikkaperäisesti työn dokumentissa. ''' self.scene = scene self.kulma = kulma self.pituus = pituus self.pen = QPen(Qt.black, 2, Qt.SolidLine) if sijainti == None: self.sijainti = self.scene.jatkoPiste else: self.sijainti = sijainti if suunta == None and sijainti == None: lx = self.pituus * math.cos(kulma) ly = self.pituus * math.sin(kulma) self.suunta = QPointF(lx,ly) else: self.kulma = math.atan2(sijainti.y()-suunta.y(), sijainti.x()-suunta.x()) self.pituus = math.sqrt((sijainti.x()-suunta.x())**2 + (sijainti.y()-suunta.y())**2) self.suunta = suunta self.scene.jatkoPiste = self.scene.jatkoPiste + self.suunta self.path = QPainterPath() self.path.lineTo(self.suunta) ''' # Jostain syystä käyrät ei ole ystäviä :( nelio= QRectF() nelio.setCoords(self.sijainti.x(), self.sijainti.y(), self.suunta.x(), self.suunta.y()-self.sijainti.y()) self.path.arcTo(nelio, self.kulma, -self.kulma+math.pi) ''' QGraphicsPathItem.__init__(self, self.path ) self.setPos(self.sijainti) self.setFlag( QGraphicsItem.ItemIsMovable, True) self.setFlag( QGraphicsItem.ItemIsSelectable, True) self.setAcceptDrops(True)
def keyPressEvent(self, event): """ Must intercept invalid input events. Make changes here Use QWidget.changeEvent Slot for intercepting window changes in order to regain focus if necessary in CNMainWindow or CustomGraphicsView classes looking for event.type() QEvent.ActivationChange and using isActiveWindow() or focus to get focus Args: event (TYPE): Description """ if event.key() in [Qt.Key_Control, Qt.Key_Left, Qt.Key_Right, Qt.Key_Up, Qt.Key_Down]: QGraphicsPathItem.keyPressEvent(self, event) elif event.key() == Qt.Key_Escape: self._tool.setFloatingXoverBegin(True) # reset the tool
def create_grid_lines(self): grid_line_width = self.settings.get_value('maps', 'grid_line_width') self.map_grid_path_item = QGraphicsPathItem() line_path = QPainterPath() for map_line in self.map_data.grid_lines: line_path.moveTo(map_line.x1, map_line.y1) line_path.lineTo(map_line.x2, map_line.y2) self.map_grid_path_item = QGraphicsPathItem(line_path) color = QColor().fromRgb(255, 255, 255, 25) self.map_grid_path_item.setPen( QPen( color, grid_line_width / self.scale_ratio ) )
def __init__(self, virtual_helix_item, xover_item, strand3p, idx): """Summary Args: virtual_helix_item (cadnano.gui.views.pathview.virtualhelixitem.VirtualHelixItem): from vhi xover_item (TYPE): Description strand3p (Strand): reference to the 3' strand idx (int): the base index within the virtual helix """ super(ForcedXoverNode3, self).__init__(virtual_helix_item) self._vhi = virtual_helix_item self._xover_item = xover_item self._idx = idx self.is_forward = strand3p.strandSet().isForward() self._is_on_top = self.is_forward self._partner_virtual_helix = virtual_helix_item self._blank_thing = QGraphicsRectItem(_blankRect, self) self._blank_thing.setBrush(QBrush(Qt.white)) self._path_thing = QGraphicsPathItem(self) self.configurePath() self._label = None self.setPen(_NO_PEN) self.setBrush(_NO_BRUSH) self.setRect(_rect) self.setZValue(styles.ZENDPOINTITEM + 1)
def mousePress(self, event): if event.button() != Qt.LeftButton: return QGraphicsPathItem.mousePressEvent(self, event) if event.modifiers() & Qt.ShiftModifier: return # ignore shift click, user is probably trying to merge if self._is_active: from_vh = self._from_vh_item.virtualHelix() to_vh = self._to_vh_item.virtualHelix() from_ss = from_vh.getStrandSetByType(self._strand_type) to_ss = to_vh.getStrandSetByType(self._strand_type) from_strand = from_ss.getStrand(self._idx) to_strand = to_ss.getStrand(self._idx) part = self._from_vh_item.part() # determine if we are a 5' or a 3' end if self.path() in [_PPATH_LU, _PPATH_RD]: # 3' end of strand5p clicked strand5p = from_strand strand3p = to_strand else: # 5' strand5p = to_strand strand3p = from_strand # Gotta clear selections when installing a prexover # otherwise parenting in screwed up self._from_vh_item.viewroot().clearStrandSelections() part.createXover(strand5p, self._idx, strand3p, self._idx) else: event.setAccepted(False)
def __init__(self): # UI Init super(QGraphicsView, self).__init__() self.setAutoFillBackground(True) self.setAttribute(Qt.WA_StyledBackground) self.setStyleSheet( 'QGraphicsView { background-color: rgba(0, 0, 0, 255); }' ) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setContentsMargins(0, 0, 0, 0) self.setTransformationAnchor(self.AnchorViewCenter) self.setFocusPolicy(Qt.StrongFocus) self.setRenderHint(QPainter.Antialiasing) # Class Init self._scene = QGraphicsScene(self) self.setScene(self._scene) self.scale_ratio = 1 self.map_data = None self.map_line_path_items = {} self.map_points_items = [] self.map_points_text_items = [] self.map_grid_path_item = QGraphicsPathItem() self.map_points_player_items = {} self.players = {} # Application Settings self.settings = settings.Settings('parse99')
def __init__(self, part_item: SliceNucleicAcidPartItemT, grid_type: EnumType): """previous_grid_bounds (tuple): a tuple corresponding to the bounds of the grid. Args: part_item: Description grid_type: Description """ super(GridItem, self).__init__(parent=part_item) self.setFlag(QGraphicsItem.ItemClipsChildrenToShape) self._path = None self.part_item = part_item self._path = QGraphicsPathItem(self) self.dots = (styles.DOT_SIZE, styles.DOT_SIZE / 2) # self.allow_snap = part_item.window().action_vhelix_snap.isChecked() self._draw_gridpoint_coordinates = False self.draw_lines = False self.points = [] self.points_dict = dict() self.previous_grid_bounds = None self.bounds = None self.grid_type = None self.setPen(getPenObj(styles.GRAY_STROKE, styles.EMPTY_HELIX_STROKE_WIDTH)) self.setGridType(grid_type) self.previous_grid_type = grid_type
def FillScene(aScene, aProcessGraphics): maxRow = 0 maxCol = 0 for graphic in aProcessGraphics: maxRow = max(maxRow, graphic.row) maxCol = max(maxCol, graphic.col) maxRow = maxRow + 1 maxCol = maxCol + 1 colWidth = 400 rowHeigth = 360 border = 50 sceneWidth = colWidth * maxCol + border * 2 sceneHeight = rowHeigth * maxRow + border * 2 aScene.setSceneRect(QRectF(0, 0, sceneWidth, sceneHeight)) aScene.clear() ## Set process positions for graphic in aProcessGraphics: x = 50 + sceneWidth - (graphic.col + 1) * colWidth y = 50 + graphic.row * rowHeigth graphic.setPos(QPointF(x, y)) aScene.addItem(graphic) ## Add lines for graphic in aProcessGraphics: for inp in graphic.inputs: for child in inp.children: controlOffset = 100 start = child.GetScenePos() control1 = start + QPointF(controlOffset, 0) end = inp.GetScenePos() control2 = end + QPointF(-controlOffset, 0) path = QPainterPath() path.moveTo(start) path.cubicTo(control1, control2, end) line = QGraphicsPathItem(path) line.setZValue(-1000) aScene.addItem(line)
def itemChange(self, change, value): # for selection changes test against QGraphicsItem.ItemSelectedChange # intercept the change instead of the has changed to enable features. if change == QGraphicsItem.ItemSelectedChange and self.scene(): active_tool = self._getActiveTool() if str(active_tool) == "select_tool": s_i = self._strand_item viewroot = s_i.viewroot() current_filter_set = viewroot.selectionFilterSet() selection_group = viewroot.strandItemSelectionGroup() # only add if the selection_group is not locked out if value == True and self.FILTER_NAME in current_filter_set: # if (self.group() != selection_group and # s_i.strandFilter() in current_filter_set): if s_i.strandFilter() in current_filter_set: if self.group() != selection_group or not self.isSelected(): # print("select ep") selection_group.pendToAdd(self) selection_group.setSelectionLock(selection_group) self.setSelectedColor(True) # print("select2 ep") return True else: return False # end if elif value == True: # don't select return False else: # Deselect # print("deselect ep") # Check if strand is being added to the selection group still if not selection_group.isPending(self._strand_item): selection_group.pendToRemove(self) self.tempReparent() self.setSelectedColor(False) return False else: # don't deselect, because the strand is still selected return True # end else # end if elif str(active_tool) == "paint_tool": s_i = self._strand_item viewroot = s_i.viewroot() current_filter_set = viewroot.selectionFilterSet() if s_i.strandFilter() in current_filter_set: if not active_tool.isMacrod(): active_tool.setMacrod() self.paintToolMousePress(None, None, None) # end elif return False # end if return QGraphicsPathItem.itemChange(self, change, value)
def __init__(self, x, y, counter, pen=pg.mkPen('r')): """ :param x: :param y: :param pen: :return: """ x = np.array(x[:])[np.newaxis, :] connect = np.ones(x.shape, dtype=bool) connect[:,-1] = 0 # don't draw the segment between each trace self.path = pg.arrayToQPath(x.flatten(), y.flatten(), connect.flatten()) QGraphicsPathItem.__init__(self, self.path) self.setCacheMode(QGraphicsItem.NoCache) self.setPen(pen) self.not_drawn = True self.counter = counter self.y = y self.last_x = x[0][-1] self.last_y = y[-1]
def initCharPath(self): """ Init the item that holds the character There is one path item that holds the character This method is activated by start line if the char item was not created to create the new and only one """ self.dirty = True self.charPath = QGraphicsPathItem(self) self.charPath.setPen(QPen(QColor(self.shapeColor), self.shapeLineThickness)) self.charPath.setZValue(1) self.charPath.originalPos = self.charPath.pos() self.charPath.setPath(QPainterPath())
def __init__(self, virtual_helix_item, strand, insertion): super(InsertionItem, self).__init__(virtual_helix_item) self.hide() self._strand = strand self._insertion = insertion self._seq_item = QGraphicsPathItem(parent=self) self._is_on_top = is_on_top = strand.isForward() y = 0 if is_on_top else _BW self.setPos(_BW*insertion.idx(), y) self.setZValue(styles.ZINSERTHANDLE) self._initLabel() self._initClickArea() self.updateItem() self.show()
def __init__(self, virtualHelixItem, strand, insertion): super(InsertionItem, self).__init__(virtualHelixItem) self.hide() self._strand = strand self._insertion = insertion self._seqItem = QGraphicsPathItem(parent=self) self._isOnTop = isOnTop = virtualHelixItem.isStrandOnTop(strand) y = 0 if isOnTop else _bw self.setPos(_bw*insertion.idx(), y) self.setZValue(styles.ZINSERTHANDLE) self._initLabel() self._initClickArea() self.updateItem() self.show()
def __init__(self, model_virtual_helix, part_item, viewroot): """Summary Args: id_num (int): VirtualHelix ID number. See `NucleicAcidPart` for description and related methods. part_item (TYPE): Description viewroot (TYPE): Description """ AbstractVirtualHelixItem.__init__(self, model_virtual_helix, part_item) QGraphicsPathItem.__init__(self, parent=part_item.proxy()) self._viewroot = viewroot self._getActiveTool = part_item._getActiveTool self._controller = VirtualHelixItemController(self, self._model_part, False, True) self._handle = VirtualHelixHandleItem(self, part_item, viewroot) self._last_strand_set = None self._last_idx = None self.setFlag(QGraphicsItem.ItemUsesExtendedStyleOption) self.setCacheMode(QGraphicsItem.DeviceCoordinateCache) self.setBrush(getNoBrush()) view = self.view() view.levelOfDetailChangedSignal.connect(self.levelOfDetailChangedSlot) should_show_details = view.shouldShowDetails() pen = newPenObj(styles.MINOR_GRID_STROKE, styles.MINOR_GRID_STROKE_WIDTH) pen.setCosmetic(should_show_details) self.setPen(pen) self.is_active = False self.refreshPath() self.setAcceptHoverEvents(True) # for pathtools self.setZValue(styles.ZPATHHELIX) self._right_mouse_move = False self.drag_last_position = self.handle_start = self.pos()
def _initLabel(self): """Display the length of the insertion.""" self._label = label = QGraphicsTextItem("", parent=self) label.setFont(_font) label.setTextInteractionFlags(Qt.TextEditorInteraction) label.inputMethodEvent = self.inputMethodEventHandler label.keyPressEvent = self.textkeyPressEvent label.mousePressEvent = self.labelMousePressEvent label.mouseDoubleClickEvent = self.mouseDoubleClickEvent label.setTextWidth(-1) self._label = label self._seqItem = QGraphicsPathItem(parent=self) self._seqText = None self.updateItem() self.show()
def __init__(self, from_virtual_helix_item, is_fwd, from_index, to_vh_id_num, prexoveritemgroup, color): """Summary Args: from_virtual_helix_item (cadnano.gui.views.pathview.virtualhelixitem.VirtualHelixItem): Description is_fwd (TYPE): Description from_index (TYPE): Description to_vh_id_num (TYPE): Description prexoveritemgroup (TYPE): Description color (TYPE): Description """ super(QGraphicsRectItem, self).__init__(BASE_RECT, from_virtual_helix_item) self.adapter = PropertyWrapperObject(self) self._bond_item = QGraphicsPathItem(self) self._bond_item.hide() self._label = PreXoverLabel(is_fwd, color, self) self._phos_item = Triangle(FWDPHOS_PP, self) self.setPen(getNoPen()) self.resetItem(from_virtual_helix_item, is_fwd, from_index, to_vh_id_num, prexoveritemgroup, color)
def __init__(self, virtual_helix_item, xover_item, strand3p, idx): super(ForcedXoverNode3, self).__init__(virtual_helix_item) self._vhi = virtual_helix_item self._xover_item = xover_item self._idx = idx self._is_on_top = virtual_helix_item.isStrandOnTop(strand3p) self._is_drawn_5_to_3 = strand3p.strandSet().isDrawn5to3() self._strand_type = strand3p.strandSet().strandType() self._partner_virtual_helix = virtual_helix_item self._blank_thing = QGraphicsRectItem(_blankRect, self) self._blank_thing.setBrush(QBrush(Qt.white)) self._path_thing = QGraphicsPathItem(self) self.configurePath() self.setPen(_NO_PEN) self._label = None self.setPen(_NO_PEN) self.setBrush(_NO_BRUSH) self.setRect(_rect) self.setZValue(styles.ZENDPOINTITEM + 1)
class PathWorkplaneOutline(QGraphicsRectItem): """ """ def __init__(self, parent: QGraphicsItem = None): """ Args: parent: default is ``None`` """ super(PathWorkplaneOutline, self).__init__(parent) self.setPen(getNoPen()) self._path = QGraphicsPathItem(self) self._path.setBrush(getNoBrush()) self._path.setPen(newPenObj(styles.BLUE_STROKE, 0)) # end def def updateAppearance(self): tl = self.rect().topLeft() tl1 = tl + QPointF(0, -BASE_WIDTH/2) tl2 = tl + QPointF(BASE_WIDTH/2, -BASE_WIDTH/2) bl = self.rect().bottomLeft() bl1 = bl + QPointF(0, BASE_WIDTH/2) bl2 = bl + QPointF(BASE_WIDTH/2, BASE_WIDTH/2) tr = self.rect().topRight() tr1 = tr + QPointF(0, -BASE_WIDTH/2) tr2 = tr + QPointF(-BASE_WIDTH/2, -BASE_WIDTH/2) br = self.rect().bottomRight() br1 = br + QPointF(0, BASE_WIDTH/2) br2 = br + QPointF(-BASE_WIDTH/2, BASE_WIDTH/2) pp = QPainterPath() pp.moveTo(tl2) pp.lineTo(tl1) pp.lineTo(bl1) pp.lineTo(bl2) pp.moveTo(tr2) pp.lineTo(tr1) pp.lineTo(br1) pp.lineTo(br2) self._path.setPath(pp)
def itemChange(self, change: QGraphicsItem.GraphicsItemChange, value: Any) -> bool: """Used for selection of the :class:`EndpointItem` Args: change: parameter that is changing value : new value whose type depends on the ``change`` argument Returns: If the change is a ``QGraphicsItem.ItemSelectedChange``:: ``True`` if selected, other ``False`` Otherwise default to :meth:`QGraphicsPathItem.itemChange()` result """ # for selection changes test against QGraphicsItem.ItemSelectedChange # intercept the change instead of the has changed to enable features. if change == QGraphicsItem.ItemSelectedChange and self.scene(): active_tool = self._getActiveTool() if str(active_tool) == "select_tool": s_i = self._strand_item viewroot = s_i.viewroot() current_filter_set = viewroot.selectionFilterSet() selection_group = viewroot.strandItemSelectionGroup() # only add if the selection_group is not locked out if value == True and self.FILTER_NAME in current_filter_set: if all(f in current_filter_set for f in s_i.strandFilter()): if self.group() != selection_group or not self.isSelected(): selection_group.pendToAdd(self) selection_group.setSelectionLock(selection_group) self.setSelectedColor(True) return True else: return False # end if elif value == True: # don't select return False else: # Deselect # print("deselect ep") # Check if strand is being added to the selection group still if not selection_group.isPending(self._strand_item): selection_group.pendToRemove(self) self.tempReparent() self.setSelectedColor(False) return False else: # don't deselect, because the strand is still selected return True # end else # end if elif str(active_tool) == "paint_tool": s_i = self._strand_item viewroot = s_i.viewroot() current_filter_set = viewroot.selectionFilterSet() if all(f in current_filter_set for f in s_i.strandFilter()): if not active_tool.isMacrod(): active_tool.setMacrod() self.paintToolMousePress(None, None, None) # end elif return False # end if return QGraphicsPathItem.itemChange(self, change, value)
class InsertionItem(QGraphicsPathItem): """ This is just the shape of the Insert item """ def __init__(self, virtualHelixItem, strand, insertion): super(InsertionItem, self).__init__(virtualHelixItem) self.hide() self._strand = strand self._insertion = insertion self._seqItem = QGraphicsPathItem(parent=self) self._isOnTop = isOnTop = virtualHelixItem.isStrandOnTop(strand) y = 0 if isOnTop else _bw self.setPos(_bw*insertion.idx(), y) self.setZValue(styles.ZINSERTHANDLE) self._initLabel() self._initClickArea() self.updateItem() self.show() # end def def _initLabel(self): """Display the length of the insertion.""" self._label = label = QGraphicsTextItem("", parent=self) label.setFont(_font) label.setTextInteractionFlags(Qt.TextEditorInteraction) label.inputMethodEvent = self.inputMethodEventHandler label.keyPressEvent = self.textkeyPressEvent label.mousePressEvent = self.labelMousePressEvent label.mouseDoubleClickEvent = self.mouseDoubleClickEvent label.setTextWidth(-1) self._label = label self._seqItem = QGraphicsPathItem(parent=self) self._seqText = None self.updateItem() self.show() # end def def _initClickArea(self): """docstring for _initClickArea""" self._clickArea = cA = QGraphicsRectItem(_defaultRect, self) cA.setPen(_noPen) cA.mousePressEvent = self.mousePressEvent cA.mouseDoubleClickEvent = self.mouseDoubleClickEvent # end def ### PUBLIC SUPPORT METHODS ### def remove(self): """ Called from the following stranditem methods: strandRemovedSlot strandInsertionRemovedSlot refreshInsertionItems """ scene = self.scene() self._label.setTextInteractionFlags(Qt.NoTextInteraction) self._label.clearFocus() scene.removeItem(self._label) self._label = None scene.removeItem(self._seqItem) self._seqItem = None scene.removeItem(self) self._insertion = None self._strand = None # end def def updateItem(self): self._updatePath() self._updateLabel() self._updateSequenceText() self._resetPosition() # end def ### PRIVATE SUPPORT METHODS ### def _focusOut(self): lbl = self._label if lbl == None: return cursor = lbl.textCursor() cursor.clearSelection() lbl.setTextCursor(cursor) lbl.clearFocus() # end def def _resetPosition(self): """ Set the label position based on orientation and text alignment. """ lbl = self._label if lbl == None: return txtOffset = lbl.boundingRect().width()/2 insertion = self._insertion y = -_bw if self._isOnTop else _bw lbl.setPos(_offset2-txtOffset, y) if insertion.length() > 0: lbl.show() else: lbl.hide() # end def def _updateLabel(self): self._label.setPlainText("%d" % (self._insertion.length())) # end def def _updatePath(self): strand = self._strand if strand == None: self.hide() return else: self.show() isOnTop = self._isOnTop if self._insertion.length() > 0: self.setPen(QPen(QColor(strand.oligo().color()), styles.INSERTWIDTH)) self.setBrush(QBrush(Qt.NoBrush)) self.setPath(_insertPath.getInsert(isOnTop)) else: # insertionSize < 0 (a skip) self.setPen(_skipPath.getPen()) self.setPath(_skipPath.getSkip()) # end def def setSequence(self, sequence): self._seqText = sequence self._updateSequenceText() self._seqItem.show() # end def def hideSequence(self): self._seqItem.hide() # end def def _updateSequenceText(self): seqItem = self._seqItem isOnTop = self._isOnTop index = self._insertion.idx() baseText = self._seqText font = styles.SEQUENCEFONT seqFontH = styles.SEQUENCEFONTH insertW = styles.INSERTWIDTH seqFontCharW = styles.SEQUENCEFONTCHARWIDTH # draw sequence on the insert if baseText: # only draw sequences if they exist i.e. not None! lenBT = len(baseText) if isOnTop: angleOffset = 0 else: angleOffset = 180 if lenBT > 20: baseText = baseText[:17] + '...' lenBT = len(baseText) fractionArclenPerChar = (1.0-2.0*_fractionInsertToPad)/(lenBT+1) seqItem.setPen(QPen(Qt.NoPen)) seqItem.setBrush(QBrush(Qt.black)) seqPath = QPainterPath() loopPath = self.path() for i in range(lenBT): frac = _fractionInsertToPad + (i+1)*fractionArclenPerChar pt = loopPath.pointAtPercent(frac) tangAng = loopPath.angleAtPercent(frac) tempPath = QPainterPath() # 1. draw the text tempPath.addText(0,0, font, baseText[i if isOnTop else -i-1]) # 2. center it at the zero point different for top and bottom # strands if not isOnTop: tempPath.translate(0, -seqFontH - insertW) tempPath.translate(QPointF(-seqFontCharW/2., -2 if isOnTop else seqFontH)) mat = QMatrix3x3() # 3. rotate it mat.rotate(-tangAng + angleOffset) rotatedPath = mat.map(tempPath) # 4. translate the rotate object to it's position on the part rotatedPath.translate(pt) seqPath.addPath(rotatedPath) # end for seqItem.setPath(seqPath) # end if # end def ### EVENT HANDLERS ### def mouseDoubleClickEvent(self, event): """Double clicks remove the insertion/skip.""" self._strand.changeInsertion(self._insertion.idx(), 0) def mousePressEvent(self, event): """This needs to be present for mouseDoubleClickEvent to work.""" pass def labelMousePressEvent(self, event): """ Pre-selects the text for editing when you click the label. """ lbl = self._label lbl.setTextInteractionFlags(Qt.TextEditorInteraction) cursor = lbl.textCursor() cursor.setPosition(0) cursor.movePosition(QTextCursor.End, QTextCursor.KeepAnchor) lbl.setTextCursor(cursor) def textkeyPressEvent(self, event): """ Must intercept invalid input events. Make changes here """ a = event.key() text = event.text() if a in [Qt.Key_Space, Qt.Key_Tab]: return elif a in [Qt.Key_Return, Qt.Key_Enter]: self.inputMethodEventHandler(event) return # elif unicode(text).isalpha(): elif text.isalpha(): return else: return QGraphicsTextItem.keyPressEvent(self._label, event) def inputMethodEventHandler(self, event): """ This is run on the label being changed or losing focus """ lbl = self._label if lbl == None: return # test = unicode(lbl.toPlainText()) test = lbl.toPlainText() try: insertionSize = int(test) except: insertionSize = None insertion = self._insertion length = insertion.length() if insertionSize != None and insertionSize != length: self._strand.changeInsertion(insertion.idx(), insertionSize) if insertion.length(): self._resetPosition() else: self._updateLabel() # end if self._focusOut()
class MapCanvas(QGraphicsView): def __init__(self): # UI Init super(QGraphicsView, self).__init__() self.setAutoFillBackground(True) self.setAttribute(Qt.WA_StyledBackground) self.setStyleSheet( 'QGraphicsView { background-color: rgba(0, 0, 0, 255); }' ) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setContentsMargins(0, 0, 0, 0) self.setTransformationAnchor(self.AnchorViewCenter) self.setFocusPolicy(Qt.StrongFocus) self.setRenderHint(QPainter.Antialiasing) # Class Init self._scene = QGraphicsScene(self) self.setScene(self._scene) self.scale_ratio = 1 self.map_data = None self.map_line_path_items = {} self.map_points_items = [] self.map_points_text_items = [] self.map_grid_path_item = QGraphicsPathItem() self.map_points_player_items = {} self.players = {} # Application Settings self.settings = settings.Settings('parse99') def load_map(self, map_name): self._scene.clear() self.map_data = MapData(map_name) self.create_grid_lines() self.create_map_lines() self.create_map_points() self.update_players() self.set_scene_padding(self.map_data.map_grid_geometry.width, self.map_data.map_grid_geometry.height) self.draw() self.centerOn(0, 0) def create_grid_lines(self): grid_line_width = self.settings.get_value('maps', 'grid_line_width') self.map_grid_path_item = QGraphicsPathItem() line_path = QPainterPath() for map_line in self.map_data.grid_lines: line_path.moveTo(map_line.x1, map_line.y1) line_path.lineTo(map_line.x2, map_line.y2) self.map_grid_path_item = QGraphicsPathItem(line_path) color = QColor().fromRgb(255, 255, 255, 25) self.map_grid_path_item.setPen( QPen( color, grid_line_width / self.scale_ratio ) ) def create_map_lines(self): map_line_width = self.settings.get_value('maps', 'map_line_width') # use color as string for dictionary keys to preserve line colours self.map_line_path_items = {} line_path = {} colors = {} for map_line in self.map_data.map_lines: key = str(map_line.r) + ',' \ + str(map_line.g) + ',' \ + str(map_line.b) if key not in line_path.keys(): line_path[key] = QPainterPath() colors[key] = QColor().fromRgb( map_line.r, map_line.g, map_line.b ) line_path[key].moveTo(QPointF(map_line.x1, map_line.y1)) line_path[key].lineTo(QPointF(map_line.x2, map_line.y2)) for key in line_path.keys(): self.map_line_path_items[key] = QGraphicsPathItem(line_path[key]) self.map_line_path_items[key].setPen( QPen( colors[key], map_line_width / self.scale_ratio ) ) def create_map_points(self): self.map_points_text_items = [] self.map_points_items = [] for map_point in self.map_data.map_points: color = QColor().fromRgb(map_point.r, map_point.g, map_point.b) rect = QGraphicsRectItem( QRectF( QPointF(map_point.x, map_point.y), QSizeF(5 / self.scale_ratio, 5 / self.scale_ratio) ) ) rect.setPen(QPen(Qt.black, 1 / self.scale_ratio)) rect.setBrush(color) self.map_points_items.append(rect) text = QGraphicsTextItem(map_point.text) text.setDefaultTextColor(color) text.setPos(map_point.x, map_point.y) text.setFont(QFont('Times New Roman', 8 / self.scale_ratio, 2)) self.map_points_text_items.append(text) def draw(self): # Draw map grid self._scene.addItem(self.map_grid_path_item) # Draw map lines for key in self.map_line_path_items.keys(): self._scene.addItem(self.map_line_path_items[key]) # Draw map points for item in self.map_points_items: self._scene.addItem(item) # Draw map point's text for item in self.map_points_text_items: self._scene.addItem(item) def update_players(self): # Convert lists to sets player_list_set = set(self.players.keys()) # Player points and text should be the same so only use one player_items_set = set(self.map_points_player_items.keys()) # calculate size of player circles circle_size = max(10, 10 / self.scale_ratio) # Draw and/or update all players in players for player in player_list_set: player_data = self.players[player] if player in player_items_set and \ self.map_points_player_items[player] in self._scene.items(): # Update self.map_points_player_items[player_data.name].setRect( player_data.x - circle_size / 2, player_data.y - circle_size / 2, circle_size, circle_size ) else: # Create New Point color = QColor().fromRgb( player_data.r, player_data.g, player_data.b ) circle = QGraphicsEllipseItem( player_data.x - circle_size / 2, player_data.y - circle_size / 2, circle_size, circle_size ) circle.setBrush(color) self.map_points_player_items[player_data.name] = circle self._scene.addItem( self.map_points_player_items[player_data.name] ) # Find/remove players who aren't in players list from the map for key in [player for player in player_items_set if player not in player_list_set]: self._scene.removeItem(self.map_points_player_items[key]) # Center map self.center() def set_scale(self, ratio): # Scale scene self.setTransform(QTransform()) self.scale_ratio = ratio self.scale(self.scale_ratio, self.scale_ratio) # Scale map lines map_line_width = self.settings.get_value('maps', 'map_line_width') for key in self.map_line_path_items.keys(): pen = self.map_line_path_items[key].pen() pen.setWidth( max( map_line_width, map_line_width / self.scale_ratio ) ) self.map_line_path_items[key].setPen(pen) # Scale map grid grid_line_width = self.settings.get_value('maps', 'grid_line_width') pen = self.map_grid_path_item.pen() pen.setWidth( max( grid_line_width, grid_line_width / self.scale_ratio ) ) self.map_grid_path_item.setPen(pen) # Scale map points for i, rect in enumerate(self.map_points_items): rect.setRect( self.map_data.map_points[i].x, self.map_data.map_points[i].y, max(5, 5 / self.scale_ratio), max(5, 5 / self.scale_ratio) ) # Scale map point's text for i, text in enumerate(self.map_points_text_items): text.setFont( QFont( 'Times New Roman', max(8, 8 / self.scale_ratio) ) ) text.setX( self.map_data.map_points[i].x + max(5, 5 / self.scale_ratio) ) # Scale player point circle_size = max(10, 10 / self.scale_ratio) for player in self.map_points_player_items.keys(): self.map_points_player_items[player].setRect( self.players[player].x - circle_size / 2, self.players[player].y - circle_size / 2, circle_size, circle_size ) def set_scene_padding(self, padding_x, padding_y): # Make it so that if you are zoomed out, you can still # drag the map around (not that smooth) rect = self._scene.sceneRect() rect.adjust( -padding_x * 2, -padding_y * 2, padding_x * 2, padding_y * 2 ) self.setSceneRect(rect) def draw_loading_screen(self): pass def fit_to_window(self): pass def center(self): if self.settings.get_value('maps', 'center_on') == 'player': # Center on Player for now by default # Added try/except because initialization causes resize event try: if '__you__' in self.players.keys(): self.centerOn( self.players['__you__'].x, self.players['__you__'].y ) except AttributeError as e: print("MapCanvas().center():", e) def add_player(self, name, time_stamp, location): y, x, z = [float(value) for value in location.strip().split(',')] y = -y x = -x if name not in self.players.keys(): r, g, b = (0, 255, 0) flag = '__other__' user_level = None if name == '__you__': r, g, b = (0, 255, 0) flag = '__you__' user_level = None self.players[name] = Player( name=name, x=x, y=y, z=z, r=r, g=g, b=b, flag=flag, user_level=user_level, time_stamp=time_stamp ) else: self.players[name].x = x self.players[name].y = y self.players[name].z = z self.players[name].time_stamp = time_stamp def wheelEvent(self, event): # Scale based on scroll wheel direction movement = event.angleDelta().y() if movement > 0: self.set_scale(self.scale_ratio + self.scale_ratio * 0.1) else: self.set_scale(self.scale_ratio - self.scale_ratio * 0.1) def keyPressEvent(self, event): # Enable drag mode while control button is being held down if event.modifiers() == Qt.ControlModifier: self.setDragMode(self.ScrollHandDrag) return QGraphicsView.keyPressEvent(self, event) def keyReleaseEvent(self, event): # Disable drag mode when control button released if event.key() == Qt.Key_Control: self.setDragMode(self.NoDrag) return QGraphicsView.keyPressEvent(self, event) def resizeEvent(self, event): self.center() return QGraphicsView.resizeEvent(self, event)
class ForcedXoverNode3(QGraphicsRectItem): """ This is a QGraphicsRectItem to allow actions and also a QGraphicsSimpleTextItem to allow a label to be drawn """ def __init__(self, virtual_helix_item, xover_item, strand3p, idx): super(ForcedXoverNode3, self).__init__(virtual_helix_item) self._vhi = virtual_helix_item self._xover_item = xover_item self._idx = idx self._is_on_top = virtual_helix_item.isStrandOnTop(strand3p) self._is_drawn_5_to_3 = strand3p.strandSet().isDrawn5to3() self._strand_type = strand3p.strandSet().strandType() self._partner_virtual_helix = virtual_helix_item self._blank_thing = QGraphicsRectItem(_blankRect, self) self._blank_thing.setBrush(QBrush(Qt.white)) self._path_thing = QGraphicsPathItem(self) self.configurePath() self.setPen(_NO_PEN) self._label = None self.setPen(_NO_PEN) self.setBrush(_NO_BRUSH) self.setRect(_rect) self.setZValue(styles.ZENDPOINTITEM + 1) # end def def updateForFloatFromVHI(self, virtual_helix_item, strand_type, idx_x, idx_y): """ """ self._vhi = virtual_helix_item self.setParentItem(virtual_helix_item) self._strand_type = strand_type self._idx = idx_x self._is_on_top = self._is_drawn_5_to_3 = True if idx_y == 0 else False self.updatePositionAndAppearance(is_from_strand=False) # end def def updateForFloatFromStrand(self, virtual_helix_item, strand3p, idx): """ """ self._vhi = virtual_helix_item self._strand = strand3p self.setParentItem(virtual_helix_item) self._idx = idx self._is_on_top = virtual_helix_item.isStrandOnTop(strand3p) self._is_drawn_5_to_3 = strand3p.strandSet().isDrawn5to3() self._strand_type = strand3p.strandSet().strandType() self.updatePositionAndAppearance() # end def def strandType(self): return self._strand_type # end def def configurePath(self): self._path_thing.setBrush(QBrush(styles.RED_STROKE)) path = PPR3 if self._is_drawn_5_to_3 else PPL3 offset = -_BASE_WIDTH if self._is_drawn_5_to_3 else _BASE_WIDTH self._path_thing.setPath(path) self._path_thing.setPos(offset, 0) offset = -_BASE_WIDTH if self._is_drawn_5_to_3 else 0 self._blank_thing.setPos(offset, 0) self._blank_thing.show() self._path_thing.show() # end def def refreshXover(self): self._xover_item.refreshXover() # end def def setPartnerVirtualHelix(self, virtual_helix_item): self._partner_virtual_helix = virtual_helix_item # end def def idx(self): return self._idx # end def def virtualHelixItem(self): return self._vhi # end def def point(self): return self._vhi.upperLeftCornerOfBaseType(self._idx, self._strand_type) # end def def floatPoint(self): pt = self.pos() return pt.x(), pt.y() # end def def isOnTop(self): return self._is_on_top # end def def isDrawn5to3(self): return self._is_drawn_5_to_3 # end def def updatePositionAndAppearance(self, is_from_strand=True): """ Sets position by asking the VirtualHelixItem Sets appearance by choosing among pre-defined painterpaths (from normalstrandgraphicsitem) depending on drawing direction. """ self.setPos(*self.point()) n5 = self._xover_item._node5 if is_from_strand: from_strand, from_idx = (n5._strand, n5._idx) if n5 != self else (None, None) if self._strand.canInstallXoverAt(self._idx, from_strand, from_idx): self.configurePath() # We can only expose a 5' end. But on which side? is_left = True if self._is_drawn_5_to_3 else False self._updateLabel(is_left) else: self.hideItems() else: self.hideItems() # end def def updateConnectivity(self): is_left = True if self._is_drawn_5_to_3 else False self._updateLabel(is_left) # end def def remove(self): """ Clean up this joint """ scene = self.scene() scene.removeItem(self._label) self._label = None scene.removeItem(self._path_thing) self._path_thing = None scene.removeItem(self._blank_thing) self._blank_thing = None scene.removeItem(self) # end def def _updateLabel(self, is_left): """ Called by updatePositionAndAppearance during init, or later by updateConnectivity. Updates drawing and position of the label. """ lbl = self._label if self._idx != None: bw = _BASE_WIDTH num = self._partner_virtual_helix.number() tBR = _FM.tightBoundingRect(str(num)) half_label_h = tBR.height()/2.0 half_label_w = tBR.width()/2.0 # determine x and y positions label_x = bw/2.0 - half_label_w if self._is_on_top: label_y = -0.25*half_label_h - 0.5 - 0.5*bw else: label_y = 2*half_label_h + 0.5 + 0.5*bw # adjust x for left vs right label_x_offset = 0.25*bw if is_left else -0.25*bw label_x += label_x_offset # adjust x for numeral 1 if num == 1: label_x -= half_label_w/2.0 # create text item if lbl == None: lbl = QGraphicsSimpleTextItem(str(num), self) lbl.setPos(label_x, label_y) lbl.setBrush(_ENAB_BRUSH) lbl.setFont(_TO_HELIX_NUM_FONT) self._label = lbl lbl.setText( str(self._partner_virtual_helix.number()) ) lbl.show() # end if # end def def hideItems(self): if self._label: self._label.hide() if self._blank_thing: self._path_thing.hide() if self._blank_thing: self._blank_thing.hide()
class ForcedXoverNode3(QGraphicsRectItem): """ This is a QGraphicsRectItem to allow actions and also a QGraphicsSimpleTextItem to allow a label to be drawn Attributes: is_forward (TYPE): Description """ def __init__(self, virtual_helix_item, xover_item, strand3p, idx): """Summary Args: virtual_helix_item (cadnano.gui.views.pathview.virtualhelixitem.VirtualHelixItem): from vhi xover_item (TYPE): Description strand3p (Strand): reference to the 3' strand idx (int): the base index within the virtual helix """ super(ForcedXoverNode3, self).__init__(virtual_helix_item) self._vhi = virtual_helix_item self._xover_item = xover_item self._idx = idx self.is_forward = strand3p.strandSet().isForward() self._is_on_top = self.is_forward self._partner_virtual_helix = virtual_helix_item self._blank_thing = QGraphicsRectItem(_blankRect, self) self._blank_thing.setBrush(QBrush(Qt.white)) self._path_thing = QGraphicsPathItem(self) self.configurePath() self._label = None self.setPen(_NO_PEN) self.setBrush(_NO_BRUSH) self.setRect(_rect) self.setZValue(styles.ZENDPOINTITEM + 1) # end def def updateForFloatFromVHI(self, virtual_helix_item, is_forward, idx_x, idx_y): """ Args: virtual_helix_item (cadnano.gui.views.pathview.virtualhelixitem.VirtualHelixItem): Description is_forward (TYPE): Description idx_x (TYPE): Description idx_y (TYPE): Description """ self._vhi = virtual_helix_item self.setParentItem(virtual_helix_item) self._idx = idx_x self._is_on_top = self.is_forward = True if is_forward else False self.updatePositionAndAppearance(is_from_strand=False) # end def def updateForFloatFromStrand(self, virtual_helix_item, strand3p, idx): """ Args: virtual_helix_item (cadnano.gui.views.pathview.virtualhelixitem.VirtualHelixItem): Description strand3p (Strand): reference to the 3' strand idx (int): the base index within the virtual helix """ self._vhi = virtual_helix_item self._strand = strand3p self.setParentItem(virtual_helix_item) self._idx = idx self._is_on_top = self.is_forward = strand3p.strandSet().isForward() self.updatePositionAndAppearance() # end def def configurePath(self): """Summary Returns: TYPE: Description """ self._path_thing.setBrush(getBrushObj(_PENCIL_COLOR)) path = PPR3 if self.is_forward else PPL3 offset = -_BASE_WIDTH if self.is_forward else _BASE_WIDTH self._path_thing.setPath(path) self._path_thing.setPos(offset, 0) offset = -_BASE_WIDTH if self.is_forward else 0 self._blank_thing.setPos(offset, 0) self._blank_thing.show() self._path_thing.show() # end def def refreshXover(self): """Summary Returns: TYPE: Description """ self._xover_item.refreshXover() # end def def setPartnerVirtualHelix(self, virtual_helix_item): """Summary Args: virtual_helix_item (cadnano.gui.views.pathview.virtualhelixitem.VirtualHelixItem): Description Returns: TYPE: Description """ self._partner_virtual_helix = virtual_helix_item # end def def idx(self): """Summary Returns: TYPE: Description """ return self._idx # end def def virtualHelixItem(self): """Summary Returns: TYPE: Description """ return self._vhi # end def def point(self): """Summary Returns: TYPE: Description """ return self._vhi.upperLeftCornerOfBaseType(self._idx, self.is_forward) # end def def floatPoint(self): """Summary Returns: TYPE: Description """ pt = self.pos() return pt.x(), pt.y() # end def def isForward(self): """Summary Returns: TYPE: Description """ return self.is_forward # end def def updatePositionAndAppearance(self, is_from_strand=True): """ Sets position by asking the VirtualHelixItem Sets appearance by choosing among pre-defined painterpaths (from normalstrandgraphicsitem) depending on drawing direction. Args: is_from_strand (bool, optional): Description """ self.setPos(*self.point()) n5 = self._xover_item._node5 if is_from_strand: from_strand, from_idx = (n5._strand, n5._idx) if n5 != self else (None, None) if self._strand.canInstallXoverAt(self._idx, from_strand, from_idx): self.configurePath() # We can only expose a 5' end. But on which side? is_left = True if self.is_forward else False self._updateLabel(is_left) else: self.hideItems() else: self.hideItems() # end def def remove(self): """Clean up this joint """ scene = self.scene() scene.removeItem(self._label) self._label = None scene.removeItem(self._path_thing) self._path_thing = None scene.removeItem(self._blank_thing) self._blank_thing = None scene.removeItem(self) # end def def _updateLabel(self, is_left): """Called by updatePositionAndAppearance during init. Updates drawing and position of the label. Args: is_left (TYPE): Description """ lbl = self._label if self._idx is not None: bw = _BASE_WIDTH num = self._partner_virtual_helix.idNum() tBR = _FM.tightBoundingRect(str(num)) half_label_h = tBR.height()/2.0 half_label_w = tBR.width()/2.0 # determine x and y positions label_x = bw/2.0 - half_label_w if self._is_on_top: label_y = -0.25*half_label_h - 0.5 - 0.5*bw else: label_y = 2*half_label_h + 0.5 + 0.5*bw # adjust x for left vs right label_x_offset = 0.25*bw if is_left else -0.25*bw label_x += label_x_offset # adjust x for numeral 1 if num == 1: label_x -= half_label_w/2.0 # create text item if lbl is None: lbl = QGraphicsSimpleTextItem(str(num), self) lbl.setPos(label_x, label_y) lbl.setBrush(_ENAB_BRUSH) lbl.setFont(_TO_HELIX_NUM_FONT) self._label = lbl lbl.setText(str(self._partner_virtual_helix.idNum())) lbl.show() # end if # end def def hideItems(self): """Summary Returns: TYPE: Description """ if self._label: self._label.hide() if self._blank_thing: self._path_thing.hide() if self._blank_thing: self._blank_thing.hide()
class InsertionItem(QGraphicsPathItem): """ This is just the shape of the Insert item """ def __init__(self, virtual_helix_item, strand, insertion): super(InsertionItem, self).__init__(virtual_helix_item) self.hide() self._strand = strand self._insertion = insertion self._seq_item = QGraphicsPathItem(parent=self) self._is_on_top = is_on_top = strand.isForward() y = 0 if is_on_top else _BW self.setPos(_BW*insertion.idx(), y) self.setZValue(styles.ZINSERTHANDLE) self._initLabel() self._initClickArea() self.updateItem() self.show() # end def def _initLabel(self): """Display the length of the insertion.""" self._label = InsertionLabel(self) self._seq_item = QGraphicsPathItem(parent=self) self._seq_text = None self.show() # end def def _initClickArea(self): """docstring for _initClickArea""" self._clickArea = cA = QGraphicsRectItem(_DEFAULT_RECT, self) cA.setPen(_NO_PEN) cA.mousePressEvent = self.mousePressEvent cA.mouseDoubleClickEvent = self.mouseDoubleClickEvent # end def ### PUBLIC SUPPORT METHODS ### def remove(self): """ Called from the following stranditem methods: strandRemovedSlot strandInsertionRemovedSlot refreshInsertionItems """ scene = self.scene() self._label.setTextInteractionFlags(Qt.NoTextInteraction) self._label.clearFocus() scene.removeItem(self._label) self._label = None scene.removeItem(self._seq_item) self._seq_item = None scene.removeItem(self) self._insertion = None self._strand = None # end def def updateItem(self): self._updatePath() self._label.updateLabel() self._updateSequenceText() self._label.resetPosition() # end def ### PRIVATE SUPPORT METHODS ### def _updatePath(self): strand = self._strand if strand is None: self.hide() return else: self.show() is_on_top = self._is_on_top if self._insertion.length() > 0: self.setPen(QPen(QColor(strand.oligo().getColor()), styles.INSERTWIDTH)) self.setBrush(QBrush(Qt.NoBrush)) self.setPath(_insert_path.getInsert(is_on_top)) else: # insertion_size < 0 (a skip) self.setPen(_skip_path.getPen()) self.setPath(_skip_path.getSkip()) # end def def setSequence(self, sequence): self._seq_text = sequence self._updateSequenceText() self._seq_item.show() # end def def hideSequence(self): self._seq_item.hide() # end def def _updateSequenceText(self): seq_item = self._seq_item is_on_top = self._is_on_top index = self._insertion.idx() base_text = self._seq_text font = styles.SEQUENCEFONT seq_font_h = styles.SEQUENCEFONTH insert_w = styles.INSERTWIDTH seq_font_char_w = styles.SEQUENCEFONTCHARWIDTH # draw sequence on the insert if base_text: # only draw sequences if they exist i.e. not None! len_BT = len(base_text) if is_on_top: angle_offset = 0 else: angle_offset = 180 if len_BT > 20: base_text = base_text[:17] + '...' len_BT = len(base_text) fraction_arc_len_per_char = (1.0 - 2.0*_FRACTION_INSERT_TO_PAD) / (len_BT + 1) seq_item.setPen(QPen(Qt.NoPen)) seq_item.setBrush(QBrush(Qt.black)) seq_path = QPainterPath() loop_path = self.path() for i in range(len_BT): frac = _FRACTION_INSERT_TO_PAD + (i+1)*fraction_arc_len_per_char pt = loop_path.pointAtPercent(frac) tang_ang = loop_path.angleAtPercent(frac) temp_path = QPainterPath() # 1. draw the text temp_path.addText(0, 0, font, base_text[i if is_on_top else -i-1]) # 2. center it at the zero point different for top and bottom # strands if not is_on_top: temp_path.translate(0, -seq_font_h - insert_w) temp_path.translate(QPointF(-seq_font_char_w / 2., -2 if is_on_top else seq_font_h)) mat = QTransform() # 3. rotate it mat.rotate(-tang_ang + angle_offset) rotated_path = mat.map(temp_path) # 4. translate the rotate object to it's position on the part rotated_path.translate(pt) seq_path.addPath(rotated_path) # end for seq_item.setPath(seq_path) # end if # end def ### EVENT HANDLERS ### def mouseDoubleClickEvent(self, event): """Double clicks remove the insertion/skip.""" self._strand.changeInsertion(self._insertion.idx(), 0) def mousePressEvent(self, event): """This needs to be present for mouseDoubleClickEvent to work.""" pass