def addWP(self, wp): if wp.command in [mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, mavutil.mavlink.MAV_CMD_NAV_LOITER_TO_ALT, mavutil.mavlink.MAV_CMD_NAV_LOITER_TURNS, mavutil.mavlink.MAV_CMD_NAV_LOITER_TIME, mavutil.mavlink.MAV_CMD_NAV_LOITER_UNLIM, mavutil.mavlink.MAV_CMD_NAV_LAND]: #point rad = self.__wp_diameter * 0.5 ellipse = QGraphicsEllipseItem(wp.y - rad, -wp.x - rad, self.__wp_diameter, self.__wp_diameter, self.__mission_layer) ellipse.setBrush(QBrush(QColor(255, 255, 255))) e_pen = QPen(QColor(255, 255, 255)) e_pen.setWidth(0) ellipse.setPen(e_pen) self.__mission_layer.addToGroup(ellipse) #label label = QGraphicsTextItem(str(wp.seq), self.__mission_layer) label.setZValue(2) label.setDefaultTextColor(Qt.white) label.setPos(wp.y + rad, -wp.x - rad) label.setScale(0.00002) #bit hacky -- really should scale based on #current zoom, but I'm in a hurry. self.__mission_layer.addToGroup(label) label.show()
def __init__(self, x, y, diameter, parent=None, ID=None): QGraphicsEllipseItem.__init__(self, x, y, diameter, diameter, parent) self.setBrush(Qt.white) self._ref = references.textReference(ID) self.setToolTip(references.tooltip(self._ref)) self.setPen(QPen(Qt.black, 2)) self.setAcceptHoverEvents(True)
def __init__(self, model_virtual_helix, part_item): """ Args: id_num (int): VirtualHelix ID number. See `NucleicAcidPart` for description and related methods. part_item (cadnano.gui.views.sliceview.nucleicacidpartitem.NucleicAcidPartItem): the part item """ AbstractVirtualHelixItem.__init__(self, model_virtual_helix, part_item) QGraphicsEllipseItem.__init__(self, parent=part_item) self._controller = VirtualHelixItemController(self, self._model_part, False, True) self.hide() model_part = self._model_part x, y = model_part.locationQt(self._id_num, part_item.scaleFactor()) # set position to offset for radius # self.setTransformOriginPoint(_RADIUS, _RADIUS) self.setCenterPos(x, y) self.wedge_gizmos = {} self._added_wedge_gizmos = set() # self._prexo_gizmos = [] self.setAcceptHoverEvents(True) self.setZValue(_ZVALUE) # handle the label specific stuff self._label = self.createLabel() self.setNumber() self.old_pen = None self.is_active = False self.updateAppearance() self.show() self._right_mouse_move = False
def __init__(self, *args): super(Demo, self).__init__(*args) loadUi('MainWindow.ui', self) scene = QGraphicsScene() rectItem = QGraphicsRectItem(QRectF(0, 0, 320, 240)) rectItem.setBrush(Qt.red) #rectItem.setPen(Qt.NoPen) rectItem.setFlag(QGraphicsItem.ItemIsMovable) scene.addItem(rectItem) ellipseItem = QGraphicsEllipseItem(QRectF(0, 0, 200, 200)) ellipseItem.setBrush(Qt.blue) #ellipseItem.setPen(Qt.NoPen) ellipseItem.setFlag(QGraphicsItem.ItemIsMovable) scene.addItem(ellipseItem) rectSizeGripItem = SizeGripItem(SimpleResizer(rectItem), rectItem) ellipseSizeGripItem = SizeGripItem(SimpleResizer(ellipseItem), ellipseItem) graphicsView = QGraphicsView(self) graphicsView.setScene(scene) self.setCentralWidget(graphicsView)
def __init__(self, id, graphicsGraphView): # Parent constructor(s) GraphicsNode.__init__(self, id, graphicsGraphView) QGraphicsEllipseItem.__init__(self) # Init text node self.graphicsTextNode.setParentItem(self) self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable) self.centerTextInShape()
def __init__(self, label = ""): QGraphicsEllipseItem.__init__(self) self.text = label self.textItem = GraphicsTextItem(self.text, parent = self) self.textItem.setTextInteractionFlags(Qt.TextEditorInteraction) self.setRect(self.textItem.boundingRect().marginsAdded(QMarginsF(10,10,10,10))) self.setFlags(QGraphicsItem.ItemIsSelectable) self.observers = set() self.edgeInConstruction = None
def drawInstanceNode(self, ): if not (self.INtestItem is None): self.INscene.removeItem(self.INtestItem) npen = self.instanceNodeFormat.pen() nbrush = self.instanceNodeFormat.brush() self.INtestItem = QGraphicsEllipseItem(QRectF( 5, 5, self.instanceNodeFormat.formatDict["nodeWidth"], self.instanceNodeFormat.formatDict["nodeHeight"]), parent=None) self.INtestItem.setBrush(nbrush) self.INtestItem.setPen(npen) self.INscene.addItem(self.INtestItem)
def __init__(self): super(painter, self).__init__() self.setFixedSize(self.width, self.height + self.textLineHeight) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.scene = QGraphicsScene() self.setScene(self.scene) # center het text item self.centerTextItem = QGraphicsTextItem() self.centerTextItem.setPos(self.width / 4 - self.fontSize, 0) self.centerTextItem.setZValue(self.baseZValue + 1) self.scene.addItem(self.centerTextItem) # center anchor item centerX = self.width / 2 centerY = self.height / 2 self.ellipseItem = QGraphicsEllipseItem( 0, 0, self.ellipseRadius * 2, self.ellipseRadius * 2 ) self.horLineItem = QGraphicsLineItem(0, 0, self.anchorLineSize, 0) self.verLineItem = QGraphicsLineItem(0, 0, 0, self.anchorLineSize) self.ellipseItem.setPos( centerX - self.ellipseRadius, centerY - self.ellipseRadius ) self.horLineItem.setPos(centerX - self.anchorLineSize / 2, centerY) self.verLineItem.setPos(centerX, centerY - self.anchorLineSize / 2) self.ellipseItem.setPen(QColor(Qt.white)) self.horLineItem.setPen(QColor(Qt.white)) self.verLineItem.setPen(QColor(Qt.white)) self.ellipseItem.setZValue(self.baseZValue + 1) self.horLineItem.setZValue(self.baseZValue + 1) self.verLineItem.setZValue(self.baseZValue + 1) self.scene.addItem(self.ellipseItem) self.scene.addItem(self.horLineItem) self.scene.addItem(self.verLineItem) # camera item self.cameraBuffer = QPixmap(self.width, self.height + self.textLineHeight) self.cameraItem = QGraphicsPixmapItem() if self.useBlur: self.gusBlurEffect = QGraphicsBlurEffect() self.gusBlurEffect.setBlurRadius(self.blurRaduis) self.cameraItem.setGraphicsEffect(self.gusBlurEffect) self.cameraItem.setPos(0, 0) self.cameraItem.setZValue(self.baseZValue) self.scene.addItem(self.cameraItem) # het text item self.hetTextBuffer = QPixmap(self.width, self.textLineHeight) self.hetTextItem = QGraphicsPixmapItem() self.hetTextItem.setPos(0, self.height) self.hetTextItem.setZValue(self.baseZValue) self.scene.addItem(self.hetTextItem)
def __init__(self, _icon_top_file, _icon_bottom_file, _win): super().__init__() self.index = 0 self.active = False self.win = _win width = 80 self.width = width height = 250 self.height = height height_ratio = 8 width_ratio = 4 points = [QPointF(width / 2, 0), QPointF(width, height / height_ratio), QPointF((width_ratio - 1) * width / width_ratio, height / height_ratio), QPointF((width_ratio - 1) * width / width_ratio, (height_ratio - 1) * height / height_ratio), QPointF(width, (height_ratio - 1) * height / height_ratio), QPointF(width / 2, height), QPointF(0, (height_ratio - 1) * height / height_ratio), QPointF(width / width_ratio, (height_ratio - 1) * height / height_ratio), QPointF(width / width_ratio, height / height_ratio), QPointF(0, height / height_ratio), QPointF(width / 2, 0) ] needle = QPolygonF(points) self.setPolygon(needle) self.setBrush(IDLE_BRUSH) self.setPen(ON_PEN) self.value_point = QGraphicsEllipseItem(width / 2 - 5, height / 2 - 5, 10, 10) self.value_point.setPen(BG_PEN) self.value_point.setBrush(FG_COL) self.value_point.setParentItem(self) self.value_point.setZValue(10) self.value_point_raw = QGraphicsEllipseItem(width / 2 - 3, height / 2 - 3, 6, 6) self.value_point_raw.setPen(BG_PEN) self.value_point_raw.setBrush(FG_COL_2) self.value_point_raw.setParentItem(self) self.value_point_raw.setZValue(9) script_dir = os.path.dirname(os.path.realpath(__file__)) icon_top_path = script_dir + os.path.sep + "img" + os.path.sep + _icon_top_file icon_bottom_path = script_dir + os.path.sep + "img" + os.path.sep + _icon_bottom_file self.top = QGraphicsPixmapItem(self) self.top.setPixmap(QPixmap(icon_top_path)) self.top.setPos(width / 2 - 8, -18) self.top.setScale(0.5) self.top.setOpacity(0.5) self.bottom = QGraphicsPixmapItem(self) self.bottom.setPixmap(QPixmap(icon_bottom_path)) self.bottom.setPos(width / 2 - 8, height + 2) self.bottom.setScale(0.5) self.bottom.setOpacity(0.5)
def mouseDoubleClickEvent(self, event): self._focused = not self._focused if self._focused: self.scene().setSceneRect(self.sceneBoundingRect()) else: self.scene().setSceneRect(self.scene().itemsBoundingRect()) if len(self.scene().views()) > 0: view = self.scene().views()[0] view.fitInView(self.scene().sceneRect(), Qt.KeepAspectRatio) QGraphicsEllipseItem.mouseDoubleClickEvent(self, event)
def __init__(self): QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.round = 50 # set range. self.gScene = QGraphicsScene(0, 0, self.ui.graphicsView.width() - 5, self.ui.graphicsView.height() - 5, self.ui.graphicsView) print 'graphics View x %f', self.ui.graphicsView.width() print 'graphics View y %f', self.ui.graphicsView.height() self.ui.graphicsView.setScene(self.gScene) # test circle self.circle = QGraphicsEllipseItem() red = QBrush(Qt.red) pen = QPen(Qt.black) pen.setWidth(6) # test line self.x_line = QGraphicsLineItem(self.gScene.width() / 2, 0, self.gScene.width() / 2, self.gScene.height()) self.gScene.addItem(self.x_line) self.y_line = QGraphicsLineItem(0, self.gScene.width() / 2, self.gScene.height(), self.gScene.width() / 2) self.gScene.addItem(self.y_line) #self.circle2 = DrawCircles(int(self.gScene.width()/2), int(self.gScene.height()/2)) #self.gScene.addItem(self.circle2) print 'gScene View x %f', self.gScene.width() / 2 print 'gScene View y %f', self.gScene.height() / 2 self.circle = self.gScene.addEllipse( self.gScene.width() / 2 - self.round, self.gScene.height() / 2 - self.round, self.round * 2, self.round * 2, pen, red) # check Item argv. self.g_item = QGraphicsRectItem(self.gScene.width() / 2, self.gScene.height() / 2, 100, 100) self.gScene.addItem(self.g_item) self.g1_item = QGraphicsRectItem(self.gScene.width() / 2, self.gScene.height() / 2, 100, 100) self.gScene.addItem(self.g1_item) # self.gScene.addItem(self.circles) self.show()
def __init__(self, label=""): QGraphicsEllipseItem.__init__(self) self.text = label self.textItem = GraphicsTextItem(self.text, parent=self) self.textItem.setTextInteractionFlags(Qt.TextEditorInteraction) self.setRect(self.textItem.boundingRect().marginsAdded( QMarginsF(10, 10, 10, 10))) self.setFlags(QGraphicsItem.ItemIsSelectable) self.observers = set() self.edgeInConstruction = None
def setInitial(self, initial): if initial: if self.initGraphics is None: self.initGraphics = QGraphicsEllipseItem( -StateGraphicsItem.INIT_WIDTH / 2, -StateGraphicsItem.INIT_WIDTH / 2, StateGraphicsItem.INIT_WIDTH, StateGraphicsItem.INIT_WIDTH, self) else: self.initGraphics.setParentItem(self) else: if self.initGraphics is not None: self.initGraphics.setParentItem(None)
def setRightPoints(self, e): if self.state == "left_set": ## if it contains points already self.rightPoint = self.gfxRight.mapToScene(e.pos()) greenPen = QPen(QtCore.Qt.green) greenBrush = QBrush(QtCore.Qt.green) self.rightPointItem = QGraphicsEllipseItem(self.rightPoint.x(), self.rightPoint.y(), 20, 20) self.rightPointItem.setPen(greenPen) self.rightPointItem.setBrush(greenBrush) self.endSetImg.addItem(self.rightPointItem) self.state = "right_set"
def __init__(self, r, x, y, color, line_width): self._radius = r self._pos = QPointF(x, y) super().__init__() self.rect = QRectF(x - r, y - r, 2 * r, 2 * r) self.disc = QGraphicsEllipseItem() self.disc.setRect(self.rect) #self.disc.setPos(QPointF(x-r, y-r)) #self.rect.moveTo(QPointF(x-r, y-r)) self.disc.setBrush(QtGui.QBrush(color)) pen = QPen() pen.setWidthF(line_width) self.disc.setPen(pen)
def __init__(self, r, x, y, color, line_width): self._radius = r self._pos = QPointF(x, y) super().__init__() # The supporting rectangle self.rect = QRectF(x - r, y - r, 2 * r, 2 * r) # The underlying QGraphicsEllipseItem self.disc = QGraphicsEllipseItem() self.disc.setRect(self.rect) self.disc.setBrush(QtGui.QBrush(color)) pen = QPen() pen.setWidthF(line_width) self.disc.setPen(pen) self._visible = 1
class RDisc(QObject): def __init__(self, r, x, y, color, line_width): self._radius = r self._pos = QPointF(x, y) super().__init__() self.rect = QRectF(x - r, y - r, 2 * r, 2 * r) self.disc = QGraphicsEllipseItem() self.disc.setRect(self.rect) #self.disc.setPos(QPointF(x-r, y-r)) #self.rect.moveTo(QPointF(x-r, y-r)) self.disc.setBrush(QtGui.QBrush(color)) pen = QPen() pen.setWidthF(line_width) self.disc.setPen(pen) def x(self): return self._pos.x() def y(self): return self._pos.y() @pyqtProperty(QPointF) def pos(self): return self._pos @pos.setter def pos(self, value): self.rect = QRectF(value.x() - self._radius, value.y() - self._radius, 2 * self._radius, 2 * self._radius) self.disc.setRect(self.rect) self._pos = value
def __init__(self, parent=None): super(ASCGraphicsView, self).__init__(parent) self.scene = QGraphicsScene(self) self.raw_img_item = QGraphicsPixmapItem() self.raw_img_item.setZValue(0) self.anno_img_item = QGraphicsPixmapItem() self.anno_img_item.setZValue(1) self.cross_bar_v_line_item = QGraphicsLineItem() self.cross_bar_h_line_item = QGraphicsLineItem() self.cross_bar_v_line_item.setZValue(100) self.cross_bar_h_line_item.setZValue(100) self.cross_bar_v_line_item.setPen( QPen(Qt.blue, 0, Qt.DotLine, Qt.FlatCap, Qt.RoundJoin)) self.cross_bar_h_line_item.setPen( QPen(Qt.blue, 0, Qt.DotLine, Qt.FlatCap, Qt.RoundJoin)) self.paint_brush_circle_item = QGraphicsEllipseItem() self.paint_brush_rect_item = QGraphicsPolygonItem() self.paint_brush_circle_item.setZValue(10) self.paint_brush_rect_item.setZValue(11) self.paint_brush_circle_item.setVisible(False) self.paint_brush_rect_item.setVisible(False) self.paint_brush_circle_item.setPen( QPen(Qt.red, 0, Qt.DotLine, Qt.FlatCap, Qt.RoundJoin)) self.paint_brush_rect_item.setPen( QPen(Qt.red, 0, Qt.DotLine, Qt.FlatCap, Qt.RoundJoin)) self.scene.addItem(self.raw_img_item) self.scene.addItem(self.anno_img_item) self.scene.addItem(self.cross_bar_v_line_item) self.scene.addItem(self.cross_bar_h_line_item) self.scene.addItem(self.paint_brush_circle_item) self.scene.addItem(self.paint_brush_rect_item) self.setScene(self.scene) self.setViewport(QOpenGLWidget()) self._last_button_press = Qt.NoButton self._last_pos_middle_button = None self._last_pos_right_button = None self._brush_stats = {'type': BRUSH_TYPE_NO_BRUSH, 'size': 5} self.setResizeAnchor(QGraphicsView.AnchorViewCenter) self.slice_scroll_bar = None self.image_size = None self.is_valid = False
def drawNode(self, ): if not (self.testItem is None): self.scene.removeItem(self.testItem) nodeWidth = self.nodeFormat.formatDict["nodeWidth"] nodeHeight = self.nodeFormat.formatDict["nodeHeight"] pen = self.nodeFormat.pen() brush = self.nodeFormat.brush() self.testItem = QGraphicsEllipseItem(QRectF(5, 5, nodeWidth + 5, nodeHeight + 5), parent=None) self.testItem.setBrush(brush) self.testItem.setPen(pen) self.scene.addItem(self.testItem) self.graphicsView.setSceneRect(1, 1, 500, 500)
def drawWPCircle(self, wp): if self.__wp_loiter_radius is None: print("Can't draw WP loiter circles; wp_loiter_radius not set.") return rad_deg = acs_math.gps_meters_to_degrees_lat(abs(self.__wp_loiter_radius), wp.x, wp.y) diameter = rad_deg * 2.0 ellipse = QGraphicsEllipseItem(wp.y - rad_deg, -wp.x - rad_deg, diameter, diameter, self.__mission_layer) #ellipse.setBrush(QBrush(QColor(255, 255, 255))) e_pen = QPen(QColor(255, 255, 255)) e_pen.setWidth(0.00002) ellipse.setPen(e_pen) self.__mission_layer.addToGroup(ellipse)
def __init__(self, parent=None): super(GameWindow, self).__init__(parent) # enables key event handling self.setFocusPolicy(Qt.StrongFocus) self.keys_pressed = set() self.size = 32 self.setWindowTitle('Donkey Kong') self.setGeometry(300, 150, 10 * self.size + 5, 20 * self.size + 5) self.is_game_over = False self.center() self.scene = QGraphicsScene(self) view = QGraphicsView(self.scene) self.setCentralWidget(view) self.design = [['e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e'], ['e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e'], ['e', 'e', 'e', 'b', 'b', 'l', 'b', 'b', 'e', 'e'], ['e', 'e', 'e', 'e', 'e', 'l', 'e', 'e', 'e', 'e'], ['e', 'e', 'e', 'e', 'e', 'l', 'e', 'e', 'e', 'e'], ['e', 'e', 'e', 'e', 'e', 'l', 'e', 'e', 'e', 'e'], ['e', 'e', 'e', 'e', 'e', 'l', 'e', 'e', 'e', 'e'], ['b', 'b', 'l', 'b', 'b', 'l', 'b', 'b', 'e', 'e'], ['e', 'e', 'l', 'e', 'e', 'e', 'e', 'e', 'e', 'e'], ['e', 'e', 'l', 'e', 'e', 'e', 'e', 'e', 'e', 'e'], ['e', 'e', 'l', 'e', 'e', 'e', 'e', 'e', 'e', 'e'], ['e', 'e', 'l', 'b', 'b', 'b', 'b', 'b', 'l', 'b'], ['e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'l', 'e'], ['e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'l', 'e'], ['e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'l', 'e'], ['e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'l', 'e'], ['e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'l', 'e'], ['e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'l', 'e'], ['e', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'l', 'e'], ['b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'l', 'b']] # e - empty, b - beam, l - ladder self.drawScene() self.player = QGraphicsEllipseItem(9 * self.size, 19 * self.size, self.size, self.size) self.player.setBrush(Qt.green) self.player_i = 9 self.player_j = 19 self.scene.addItem(self.player) self.show()
def showCoords(self, event): try: self.removeItem(self.text) self.removeItem(self.dot) except AttributeError: pass p = self.MainWindow.View.mapToScene(event.x(), event.y()) self.dot = QGraphicsEllipseItem(int(p.x()) - 3, int(p.y()) - 3, 6, 6) self.dot.setBrush(Qt.blue) self.addItem(self.dot) self.text = QGraphicsSimpleTextItem( "x%s_y%s" % (str(int(p.x()) + 5), str(int(p.y()) + 5))) self.text.setBrush(Qt.red) self.text.setPos(p.x(), p.y()) self.addItem(self.text)
def mousePressEvent(self, event, image_item): pos = event.scenePos() self._ann.update({ self._prefix + 'x': pos.x(), self._prefix + 'y': pos.y() }) self._ann.update(self._default_properties) if self._commit: image_item.addAnnotation(self._ann) self._item = QGraphicsEllipseItem( QRectF(pos.x() - 2, pos.y() - 2, 5, 5)) self._item.setPen(self.pen()) self.annotationFinished.emit() event.accept()
def _add_ellipse(self, radius, scale_factor, pen, use_brush=False): r = scale_factor * radius item = QGraphicsEllipseItem(-r, -r, r * 2, r * 2, self) item.setPen(_map_physical_pen_to_scene(pen, scale_factor)) if use_brush: item.setBrush(QBrush(pen.color())) item.setZValue(Z.NEW_MANUAL_ELEMENT_PIN) self._items_info.append(_PinItemInfo(item, radius, pen))
class PoolItemCircle(PoolItem): name = constants.ITEM def __init__(self, *args, **kwargs): PoolItem.__init__(self, *args, **kwargs) self.setFlag(QGraphicsItem.ItemIsMovable, True) self.bgColor = QGraphicsEllipseItem(self) self.bgColor.setFlag(QGraphicsItem.ItemStacksBehindParent, True) self.bgColor.setRect(((self.gobj.boundingRect().width() + PoolItem.fontMetrics.width(' ')) / 2) - 5, self.gobj.boundingRect().height() / 2 - 5, 10, 10) def setDisplayProperties(self, x, y, textcolor, bgcolor): self.setGeometry( x, y, self.gobj.boundingRect().width() + PoolItem.fontMetrics.width(' '), self.gobj.boundingRect().height()) self.bgColor.setBrush( QtGui.QBrush( QtGui.QColor(bgcolor.red(), bgcolor.green(), bgcolor.blue(), 255))) def updateRect(self, ratio): width = self.gobj.boundingRect().width() + PoolItem.fontMetrics.width( ' ') height = self.gobj.boundingRect().height() adjustw = width * ratio adjusth = height * ratio self.bgColor.setRect(width / 2 - abs(adjustw / 2), height / 2 - abs(adjusth / 2), adjustw, adjusth) self.updateValue(self.gobj) def returnEllispeSize(self): self.bgColor.setRect(((self.gobj.boundingRect().width() + PoolItem.fontMetrics.width(' ')) / 2) - 5, self.gobj.boundingRect().height() / 2 - 5, 10, 10) def refresh(self, scale): fontsize = KineticsDisplayItem.defaultFontSize * scale font = QtGui.QFont(KineticsDisplayItem.defaultFontName) if (fontsize < 1): fontsize = self.gobj.font().pointSize() font.setPointSize(fontsize) self.gobj.setFont(font) def MooseRef(self): return self.gobj.mobj
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 itemChange(self, change, value): #print('%s.itemChange' % (self.__class__.__name__), ' change: %d, value:' % change, value) valnew = QGraphicsEllipseItem.itemChange(self, change, value) if change == self.ItemSelectedHasChanged: #self.set_control_points_visible(visible=True) self.set_control_points_visible(visible=self.isSelected()) return valnew
def __init__(self, manager): """Summary Args: manager (TYPE): Description """ super(AbstractSliceTool, self).__init__(parent=manager.viewroot) """ Pareting to viewroot to prevent orphan _line_item from occuring """ self.sgv = None self.manager = manager self._active = False self._last_location = None self._line_item = QGraphicsLineItem(self) self._line_item.hide() self._vhi = None self.hide() self.is_started = False self.angles = [math.radians(x) for x in range(0, 360, 30)] self.vectors = self.setVectors() self.part_item = None self.vhi_hint_item = QGraphicsEllipseItem(_DEFAULT_RECT, self) self.vhi_hint_item.setPen(_MOD_PEN) self.vhi_hint_item.setZValue(styles.ZPARTITEM)
def __init__(self, map, *args): super().__init__(*args) self.map = map self.position = map.center self.providers = deque([ 'osm', 'stamen-terrain', 'stamen-toner-lite', 'stamen-toner', 'stamen-watercolor', 'ms-aerial', 'ms-hybrid', 'ms-road', 'bluemarble', ]) self.refresh_map = asyncio.Event() scene = QGraphicsScene() self.scene = scene self.setScene(scene) self.map_layer = QGraphicsPixmapItem() scene.addItem(self.map_layer) self.circle = QGraphicsEllipseItem(0, 0, 20, 20) pen = QPen(QColor(255, 0, 0, 128)) pen.setWidth(2) self.circle.setPen(pen) scene.addItem(self.circle) self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
def onActionMove(self, offline): self.sender().data() self.current_action["type"]= ActionType.MoveToPosition self.current_action["value"] = self.sender().data() self.current_action['offline'] = offline if len(self.univers.selectedWarriors()) > 1 : if self.dispatch_item!= None : self.scene.removeItem(self.moveShape) self.dispatch_item = QGraphicsEllipseItem() if self.sender().data()<=0: #pour un mouvement normal en vert brush = QBrush(QColor(0,255,0,125)) pen = QPen(QColor(0,255,0)) elif offline == True: # pour un placement en vert brush = QBrush(QColor(255,0,0,125)) pen = QPen(QColor(255,0,0)) else: #pour une teleportation en bleue brush = QBrush(QColor(0,0,255,125)) pen = QPen(QColor(0,0,255)) self.dispatch_item.setRect(QRectF(-self.width_movable_region/2,-self.height_movable_region/2,self.width_movable_region,self.height_movable_region)) self.dispatch_item.setPen(pen) self.dispatch_item.setBrush(brush) self.dispatch_item.setZValue(2) self.scene.addItem(self.dispatch_item) if self.sender().data()<=0 and offline == False: self.viewport().setCursor(QCursor(QPixmap(":/icons/32x32/action_teleport"))) elif offline == True: self.viewport().setCursor(QCursor(QPixmap(":/icons/32x32/action_placement"))) else: self.viewport().setCursor(QCursor(QPixmap(":/icons/32x32/action_move"))) self.mode_action = Mode.Move
def remplirScene(self): scene = self.scene rectGris = scene.addRect(0, 0, 200, 150, brush=QBrush(Qt.lightGray)) self.rectGris = rectGris self.texte = scene.addText("") dy = rectGris.rect().height() - self.texte.sceneBoundingRect().height() self.texte.setPos(rectGris.x(), rectGris.y() + dy) self.texte.setDefaultTextColor(Qt.cyan) scene.addItem(self.texte) d = 48. # diametre smiley ox = 4. # largeur oeil oy = 6. # hauteur oeil smiley = scene.addEllipse(-d / 2, -d / 2, d, d, brush=QBrush(Qt.yellow)) yeux = [QGraphicsEllipseItem(-ox/2.,-oy/2.,ox,oy,parent=smiley) \ for i in range(2)] yeux[0].setPos(-d / 6, -d / 8) yeux[1].setPos(+d / 6, -d / 8) brush = QBrush(Qt.black) for oeil in yeux: oeil.setBrush(brush) smiley.setPos(rectGris.mapToScene(rectGris.rect().center())) smiley.setRotation(20) smiley.setScale(1.5) for item in scene.items(): item.setFlag(QGraphicsItem.ItemIsMovable) item.setFlag(QGraphicsItem.ItemIsSelectable)
def __init__(self, img_arr, binary_array, parent=None, title='ImageWindow'): super(OverlayImageWindow, self).__init__(parent) self.setWindowTitle(title) self.img_arr = img_arr self.binary_array = binary_array win = pg.GraphicsLayoutWidget() self.vb = pg.ViewBox(enableMouse=False, enableMenu=False) self.img_item = DragImageItem(img_arr[0]) pos = np.array([0., 1.]) color = np.array([[0., 0., 0., 0.], [1., 0., 0., self.alpha]]) cm = pg.ColorMap(pos, color) lut = cm.getLookupTable(0., 1.) self.olay_updated.connect(self.update_overlay) self.overlay_item = pg.ImageItem(binary_array[0]) self.overlay_item.setLookupTable(lut) self.vb.addItem(self.img_item) self.vb.addItem(self.overlay_item) self.vb.setAspectLocked() win.addItem(self.vb) self.circle = QGraphicsEllipseItem(30., 30., 0., 0.) self.vb.addItem(self.circle) hist = pg.HistogramLUTItem() hist.setImageItem(self.img_item) win.addItem(hist) win.setStyleSheet("background-color:black;") self.setCentralWidget(win)
def __init__(self, x1, y1, x2, y2): QGraphicsEllipseItem.__init__(self, x1, y1, x2, y2) self.point_to = 0 self.point_from = 0 self.path_point = 0 self.path_point_to = 0 self.tbl = QTableWidget(1, 2) item = QTableWidgetItem("0:00") self.tbl.setItem(0, 0, item) item = QTableWidgetItem("0:00") self.tbl.setItem(0, 1, item) self.tbl.setFixedWidth(219) item = QTableWidgetItem("time of origin") self.tbl.setHorizontalHeaderItem(0, item) item = QTableWidgetItem("path time") self.tbl.setHorizontalHeaderItem(1, item)
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(): viewroot = self._viewroot current_filter_dict = viewroot.selectionFilterDict() selection_group = viewroot.vhiHandleSelectionGroup() # only add if the selection_group is not locked out if value == True and self._filter_name in current_filter_dict: if self.group() != selection_group: 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 selection_group.pendToRemove(self) self.setSelectedColor(False) return False # end else # end if return QGraphicsEllipseItem.itemChange(self, change, value)
def attach_attribute(self, l, txt, id, type, parent, w, h, txt_geo, child): self.con_list.append(QGraphicsLineItem(parent)) self.atr_shape_list.append(QGraphicsEllipseItem(parent)) self.con_list[-1].setLine(l) self.con_list[-1].setPen(self.at_connection_pen) self.atr_shape_list[-1].setRect( QRectF(l.x1() - w / 2, l.y2() - h, w, h)) self.atr_shape_list[-1].setPen(self.attribute_pen) self.atr_shape_list[-1].setBrush(self.attribute_brush) self.atr_txt_list.append(self.scene.addWidget(QLineEdit())) self.atr_txt_list[-1].setParentItem(self.atr_shape_list[-1]) self.atr_txt_list[-1].setGeometry(txt_geo) self.atr_txt_list[-1].widget().setFixedWidth(txt_geo.width()) self.atr_txt_list[-1].widget().setFixedHeight(txt_geo.height()) self.atr_txt_list[-1].widget().setStyleSheet(self.txt_style) if (type == 'Prime' or type == 'prime'): self.atr_txt_list[-1].widget().setStyleSheet( '''QWidget{text-decoration:underline;font-weight:bold;}''') self.atr_txt_list[-1].setPos( l.x2() - self.txt_atr_geometry.width() / 2, l.y2() - 0.75 * h) self.atr_txt_list[-1].widget().setText(txt) widget = self.atr_txt_list[-1].widget() self.atr_txt_list[-1].widget().editingFinished.connect( lambda: ContainerItem.trial(self, id, widget, child))
def __init__(self, obj, parent=None, scene=None,\ brush=QBrush(), pen=QPen(Qt.blue, 0, Qt.SolidLine)) : """Adds QGraphics(Rect)Item to the scene. Parameters obj : QPointF or shape type e.g. QRectF obj is QPointF - shape parameters are defined at first mouse click obj is QRectF - it will be drawn as is """ logger.debug('In DragEllipse') rect = obj if isinstance(obj, QRectF) else\ QRectF(obj, obj + QPointF(5,5)) if isinstance(obj, QPointF) else\ None if rect is None: logger.warning('DragEllipse - wrong init object type:', str(obj)) return self._dragtype = ELLIPSE parent_for_base = None QGraphicsEllipseItem.__init__(self, rect, parent_for_base) #DragBase.__init__(self, parent, brush, pen) # is called inside QGraphicsEllipseItem logger.debug('In DragEllipse - superclass initialization is done') if isinstance(obj, QPointF): self._drag_mode = ADD logger.debug('set elf._drag_mode = ADD, ADD:%d _drag_mode:%d' % (ADD, self._drag_mode)) if scene is not None: scene.addItem(self) if self._drag_mode == ADD: self.grabMouse() # makes available mouseMoveEvent logger.debug('In DragEllipse mode grabMouse()') self.setAcceptHoverEvents(True) #self.setAcceptTouchEvents(True) self.setAcceptedMouseButtons(Qt.LeftButton) self.setPen(self._pen_pos) self.setBrush(self._brush) # Flags: ItemIsPanel, ItemClipsChildrenToShape, ItemIsSelectable, # ItemIsMovable, itemClipsToShape, ItemSendsScenePositionChanges self.setFlags(self.ItemIsSelectable)
def loadFromJson(self): if (os.stat("database.txt").st_size == 0): return with open('database.txt') as json_file: graph = json.load(json_file) for p in graph['nodes']: circle = QGraphicsEllipseItem(-20, -20, 40, 40) circle.setFlag(QGraphicsItem.ItemIsMovable) circle.name = p["name"] circle.setPos(float(p["x"]), float(p["y"])) circle.setToolTip(circle.name) self.nodesMap.append(circle)
def addPointToPath(self, x, y): widthEllipse = 20 heightEllipse = 20 EllipseX = x - widthEllipse / 2 EllipseY = y - heightEllipse / 2 if (len(Unit.PATH) != 0): lastPoint = Unit.PATH[len(Unit.PATH) - 1] line = QGraphicsLineItem(lastPoint[0], lastPoint[1], x, y) line.setPen(QPen(QBrush(QColor(128, 0, 0)), 5)) self.addItem(line) Unit.PATH.append([x, y]) item = QGraphicsEllipseItem(EllipseX, EllipseY, widthEllipse, heightEllipse) item.setBrush(QColor(0, 0, 128)) self.addItem(item)
def mousePressEvent(self, event: QGraphicsSceneMouseEvent): """Handler for user mouse press. Args: event: Contains item, scene, and screen coordinates of the the event, and previous event. """ if self.grid.allow_snap: part_item = self.grid.part_item tool = part_item._getActiveTool() if tool.FILTER_NAME not in part_item.part().document().filter_set: return tool_method_name = tool.methodPrefix() + "MousePress" if hasattr(self, tool_method_name): getattr(self, tool_method_name)(tool, part_item, event) else: QGraphicsEllipseItem.mousePressEvent(self, event)
def __init__(self, x: float, y: float, descr: str = ""): super().__init__(draggable=True, selectable=True, unique_selection=True) self._r = self.normal_size self.setPos(QPointF(x, y)) # We must describe how to draw our own component # Our own component will be just a circle self._item = QGraphicsEllipseItem(-self._r, -self._r, self._r * 2, self._r * 2, self) # .. yellow circle self._item.setBrush(QBrush(QColor(0xFFFF00))) # Add description to our object - it will be used in "click" callback function self._descr = descr
def __init__(self, name, side, parent): self.parent = parent self.logger = parent.logger self.name = name self.side = side self.createdAtSide = side self.posCallbacks = [] self.connectionList = [] self.id = self.parent.parent.parent().idGen.getID() self.color = "white" self.ashColorR = QColor(239, 57, 75) self.ashColorB = QColor(20, 83, 245) QGraphicsEllipseItem.__init__(self, QRectF(-4, -4, 7.0, 7.0), parent) self.innerCircle = QGraphicsEllipseItem(-4, -4, 6, 6, self) self.innerCircle.setPen(QPen(QColor(0, 0, 0, 0), 0)) self.visibleColor = QColor(0, 0, 0) # This if is only for input/output having different colors if name == "i": self.innerCircle.setBrush(self.visibleColor) if name == "o": self.innerCircle.setBrush(self.visibleColor) self.setCursor(QCursor(QtCore.Qt.CrossCursor)) # self.setCursor(QCursor(QtCore.Qt.PointingHandCursor)) # The Port itself is larger than only the innerCircle self.setBrush(QBrush(QtCore.Qt.white)) # Hacky fix for no border of ellipse p1 = QPen(QColor(0, 0, 0, 0), 0) self.setPen(p1) self.setFlag(self.ItemSendsScenePositionChanges, True) self.setAcceptHoverEvents(True) # QUndo framework related self.savePos = None self.savedPos = False
def drawEllipse(self): rect = self.setRect() #self.ellipseitem = QGraphicsEllipseItem(rect) self.ellipseitem = EllipseItem(rect, self.undoStack) self.ellipseitem.setPen(QPen(self.color, 2)) self.ellipseitem.setFlag(QGraphicsItem.ItemIsSelectable) self.ellipseitem.setFlag(QGraphicsItem.ItemIsMovable) self.scene.addItem(self.ellipseitem) return self.ellipseitem
def __init__(self): super().__init__() self.center_x = 0 self.center_y = 0 self.radius = 1 self.now = datetime.utcfromtimestamp(0) # build the clock face self.circle = QGraphicsEllipseItem(self.root) self.lines = [] for _ in range(0, 60): self.lines.append(QGraphicsLineItem(self.root)) self.hours_hand = QGraphicsLineItem(self.root) self.minutes_hand = QGraphicsLineItem(self.root) self.seconds_hand = QGraphicsLineItem(self.root) self.hand_circle = QGraphicsEllipseItem(self.root)
def selectToolMousePress(self, tool, part_item, event): """Summary Args: tool (TYPE): Description part_item (TYPE): Description event (TYPE): Description """ part = part_item.part() part.setSelected(True) # print("monkey") alt_event = GridEvent(self, self.offset) tool.selectOrSnap(part_item, alt_event, event) return QGraphicsEllipseItem.mousePressEvent(self, event)
def selectToolMousePress(self, tool: SelectGridToolT, part_item: GridNucleicAcidPartItemT, event: QGraphicsSceneMouseEvent): """ Args: tool: :class:`SelectGridTool` part_item: :class:`GridNucleicAcidPartItem` event: the mouse event """ part = part_item.part() part.setSelected(True) # print("GridPoint MousePress for select") alt_event = GridEvent(self, self.offset) tool.selectOrSnap(part_item, alt_event, event) return QGraphicsEllipseItem.mousePressEvent(self, event)
def __init__(self, posX=0, posY=0, radX=30, radY=30, parent=None): super().__init__() self.posX = posX self.posY = posY self.radX = radX self.radY = radY self.parent = parent self.ellipse = QGraphicsEllipseItem(posX, posY, radX, radY) self.sheet = QPixmap('linkEdit.png') self.stand = [] self.step = 0 self.state = 0 self.animation_timer = QTimer() self.animation_timer.timeout.connect(self.animate) self.animation_timer.setInterval(1000) self.animation_timer.start()
def itemChange(self, change: QGraphicsItem.GraphicsItemChange, value: Any) -> bool: """Used for selection of the :class:`VirtualHelixHandleItem` 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:`QGraphicsEllipseItem.itemChange()` result """ if change == QGraphicsItem.ItemSelectedChange and self.scene(): viewroot = self._viewroot current_filter_set = viewroot.selectionFilterSet() selection_group = viewroot.vhiHandleSelectionGroup() # print("filter set", current_filter_set, self.FILTER_NAME) # only add if the selection_group is not locked out if value == True and self.FILTER_NAME in current_filter_set: # noqa if self.group() != selection_group: if not selection_group.isPending(self): selection_group.pendToAdd(self) selection_group.setSelectionLock(selection_group) self.setSelectedColor(True) return False # only select if mode says so return True else: return False # end if elif value == True: # noqa # print("don't select", value) # don't select return False else: # Deselect # print("Deselect", value) selection_group.pendToRemove(self) self.setSelectedColor(False) return False # end else # end if else: return QGraphicsEllipseItem.itemChange(self, change, value)
def itemChange(self, change, value): """For selection changes test against QGraphicsItem.ItemSelectedChange intercept the change instead of the has changed to enable features. Args: change (TYPE): Description value (TYPE): Description """ if change == QGraphicsItem.ItemSelectedChange and self.scene(): viewroot = self._viewroot current_filter_set = viewroot.selectionFilterSet() selection_group = viewroot.vhiHandleSelectionGroup() # print("filter set", current_filter_set, self.FILTER_NAME) # only add if the selection_group is not locked out if value == True and self.FILTER_NAME in current_filter_set: # noqa if self.group() != selection_group: if not selection_group.isPending(self): selection_group.pendToAdd(self) selection_group.setSelectionLock(selection_group) self.setSelectedColor(True) return False # only select if mode says so return True else: return False # end if elif value == True: # noqa # print("don't select", value) # don't select return False else: # Deselect # print("Deselect", value) selection_group.pendToRemove(self) self.setSelectedColor(False) return False # end else # end if else: return QGraphicsEllipseItem.itemChange(self, change, value)
class ProtoObj(object): def __init__(self, posX=0, posY=0, radX=30, radY=30, parent=None): super().__init__() self.posX = posX self.posY = posY self.radX = radX self.radY = radY self.parent = parent self.ellipse = QGraphicsEllipseItem(posX, posY, radX, radY) self.sheet = QPixmap('linkEdit.png') self.stand = [] self.step = 0 self.state = 0 self.animation_timer = QTimer() self.animation_timer.timeout.connect(self.animate) self.animation_timer.setInterval(1000) self.animation_timer.start() def initObj(self): self.ellipse.setPos(self.posX, self.posY) self.ellipse.setPen(QPen(Qt.transparent, 1)) self.ellipse.setBrush(QBrush(Qt.darkGreen)) self.ellipse.setZValue(0) self.ellipse.setOpacity(1) effect = QGraphicsDropShadowEffect(self.parent) effect.setBlurRadius(15) effect.setColor(Qt.black) self.ellipse.setGraphicsEffect(effect) self.stand.append(self.sheet.copy(10, 15, 100, 120)) self.stand.append(self.sheet.copy(130, 15, 100, 120)) self.stand.append(self.sheet.copy(250, 15, 100, 120)) self.pix = self.parent.m_scene.addPixmap(self.stand[0]) self.pix.setPos(self.posX, self.posY) self.pix.setOffset(-20, -56) self.pix.setZValue(2) self.pix.setScale(1) def getObj(self): return [self.ellipse] def moveObj(self, velX, velY): self.posX += velX self.posY += velY self.pix.setPos(self.posX, self.posY) def animate(self): if self.state == 0: self.step += 1 if self.step > 2: self.step = 0 'standing' #self.pix = self.parent.m_scene.addPixmap(self.stand[self.step]) self.pix.setPixmap(self.stand[self.step]) self.pix.setPos(self.posX, self.posY) #self.pix.setOffset(-20, -70) self.pix.setZValue(2)
class MapWindow( QtWidgets.QGraphicsView ): level_changed = QtCore.pyqtSignal( int ) minus_level = QtCore.pyqtSignal() major_level = QtCore.pyqtSignal() center_changed = QtCore.pyqtSignal( float, float ) update_labels = QtCore.pyqtSignal( float, float, int, int, int, int ) rotation_changed = QtCore.pyqtSignal( int ) double_click = QtCore.pyqtSignal( QtCore.QPointF ) contextMenu = QtCore.pyqtSignal( QtCore.QPointF, QtWidgets.QMenu ) mode_free = QtCore.pyqtSignal() #move_heroes = QtCore.pyqtSignal() def __init__( self,univers, parent=None ): ''' Initialisation of the QGraphicsView ''' super( MapWindow, self ).__init__( parent ) self.univers = univers self.univers.askForMap.connect(self.goToHeros) # scene coordinates self.scene_coord = None self.settings = Config().instance.settings # add a scene self.first_selection = True self.scene = MapScene( self ) self.setScene( self.scene ) # zoom_in = QShortcut() # zoom_in.setKey("Ctrl+A") # zoom_in.activated.connect.onZoomIn() # zoom_out = QShortcut() # zoom_out.setKey("Ctrl+Q") # zoom_out.activated.connect.onZoomOut() # init the flags self.setFlags() # manual drag self.pressed_pos = None self.origin = None self.destination = None self.cursor_shape = self.viewport().cursor().shape() # add a layer manager self.manager = LayerManager( self.scene,self.univers, self ) # update tiles with timer self.timer = QtCore.QTimer() # self.timer.setSingleShot( True ) self.timer.timeout.connect( self.updateTiles ) self.timer.start( 50 ) # calculations made outside self.computing = Computing() # init scale on foreground #self.foreground_items = ForegroundItems() self.rotate_value = 0 # center mode self.mode = None self.observer_x, self.observer_y = 0, 0 self.mode_action = Mode.Normal # members variables used in viewportEvent #self.touch_event = TouchEvent( self ) self.drag = {} self.distances = [] self.distance_line = QtWidgets.QGraphicsLineItem() self.draw_distance = False #move warriors self.dispatch_item = None self.shape = "Circle" self.changeSizeMoveShape = False self.width_movable_region = 100000 self.height_movable_region = 100000 self.marker_item = None self.marker_items = [] self.color_mode = ColorMode.Empire layers_list = self.settings.value("map/instanciated_layers",[]) first = True print ('len layer_list',len(layers_list), layers_list) for layer in layers_list: print ('layer list item : ',layer) self.onLayerAdded(layer,first) first = False self.current_action = {} def viewportEvent( self, event ): ''' viewport event manager ''' if event.type() == QtCore.QEvent.TouchBegin or event.type() == QtCore.QEvent.TouchUpdate or event.type() == QtCore.QEvent.TouchEnd: if self.scene_coord and self.mode == 'Free' and not self.draw_distance : self.touch_event.touchEvent( event ) return True return super( MapWindow, self ).viewportEvent( event ) def changeColorMode (self,mode): self.color_mode = mode print ('change color mode',mode) def setFlags( self ): ''' set graphics view flags ''' # remove scrollbar displaying #self.setHorizontalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff ) #self.setVerticalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff ) # scale regarding the cursor self.setTransformationAnchor( QtWidgets.QGraphicsView.AnchorViewCenter ) # resize maintaining view center self.setResizeAnchor( QtWidgets.QGraphicsView.AnchorViewCenter ) # OpenGL viewport #if Config().opengl_isActivated: # pass # self.setViewport( QtOpenGL.QGLWidget( QtOpenGL.QGLFormat( QtOpenGL.QGL.SampleBuffers ) ) ) # move entities without streak self.setViewportUpdateMode( QtWidgets.QGraphicsView.FullViewportUpdate ) # to send cursor informations self.setMouseTracking( True ) self.setDragMode( QtWidgets.QGraphicsView.ScrollHandDrag ) def initGraphicsView( self, projection_name, level, lat, lon ): ''' init the graphics view with the projection ''' # set the QGraphicsScene self.scene_coord = getattr( projection, str( projection_name ) )() self.scene_coord.setLevel( level ) self.setSceneRect( self.scene_coord.getSceneRect() ) # init view's scale scale_factor = 1.0 / self.scene_coord.getResolution() self.scale( scale_factor, scale_factor ) # init view's position self.centerOnLatLong( lat, lon ) def viewFromScratch( self ): ''' reset if the layers widget become empty again ''' self.resetTransform() self.scene_coord.reset() self.scene_coord = None self.update_labels.emit( 0, 0, 0, 0, 0, 0 ) # def drawForeground( self, painter, rect ): # ''' draw the scale on the foreground ''' # if self.scene_coord: # p = self.mapToScene( 0, 0 ) # lat1, lon1 = self.scene_coord.MetersToLatLon( p.x(), p.y() ) # p = self.mapToScene( self.width(), 0 ) # lat2, lon2 = self.scene_coord.MetersToLatLon( p.x(), p.y() ) # self.foreground_items.paintScale( painter, -self.rotate_value, lat1, lon1, lat2, lon2, self.width(), self.height(), self.scene_coord.getResolution() ) def updateTiles( self ): ''' update displaying ''' if 'dist' in self.drag: if self.drag['dist'].manhattanLength() < 100: self.drag = {} self.timer.start( 50 ) else: length = self.drag['end'] - self.drag['begin'] drag_pos = QtCore.QPointF( self.drag['dist'].x(), self.drag['dist'].y() ) # QPoint to QPointF, required to centerOn self.centerOn( self.getSceneViewCenter() + drag_pos ) self.drag['dist'] = self.drag['dist'] / ( 1 + length ) self.timer.start( 10 ) self.manager.update( self.getSceneBoundingBox() ) def centerOnLatLong( self, lat, lon ): ''' center the view on the latitude/longitude parameters ''' if self.scene_coord: mx, my = self.scene_coord.LatLonToScene( lat, lon ) self.centerOn( mx, my ) def goToHeros (self,lat,lon): self.centerOnLatLong(lat, lon) def getSceneViewCenter( self ): ''' return the point in the view center ''' return self.mapToScene( self.viewport().rect() ).boundingRect().center() # more accurate with boundingRect def centerOnObserver( self ): ''' center the view on the observer ''' if self.viewport().cursor().shape() == QtCore.Qt.ClosedHandCursor: self.mode_free.emit() # on se deplace dans la scene : passage automatique en mode 'Free' else: self.centerOn( self.observer_x, self.observer_y ) self.update() def getSceneBoundingBox( self ): ''' get the part of the scene viewable ''' rect_viewport = QtCore.QRect( 0, 0, self.width(), self.height() ) poly_scene = self.mapToScene( rect_viewport ) return poly_scene.boundingRect() def wheelEvent( self, event=None, scale_center=None, scale_factor=None ): ''' Scale event ''' if self.scene_coord: if event: scale_factor = 1 if event.angleDelta().y() > 0: scale_factor += ( self.scene_coord.getResolution() / self.scene_coord.getLevelResolution( self.scene_coord.getLevel() + 1 ) ) / 50 else: scale_factor -= ( self.scene_coord.getLevelResolution( self.scene_coord.getLevel() - 1 ) / self.scene_coord.getResolution() ) / 50 self.scale( scale_factor, scale_factor ) else: center_before_scale = self.mapToScene( scale_center.toPoint() ) self.scale( scale_factor, scale_factor ) center_after_scale = self.mapToScene( scale_center.toPoint() ) shift = center_after_scale - center_before_scale self.centerOn( self.getSceneViewCenter() - shift ) # update items resolution self.scene_coord.setRealResolution( self.scene_coord.getRealResolution() / scale_factor ) res = self.scene_coord.getRealResolution() for item in self.marker_items: item.setScale( res ) current_level = self.scene_coord.getLevel() view_scale, new_level = self.computing.hasToChangeLevel( self.transform(), self.scene_coord.getResolution(), self.scene_coord.getLevelResolution( current_level - 1 ), current_level ) if new_level: self.updateLevel( view_scale, new_level ) def keyPressEvent(self, event): if event.key()== QtCore.Qt.Key_Control: self.setDragMode( QtWidgets.QGraphicsView.RubberBandDrag ) if self.dispatch_item != None : if event.key() == QtCore.Qt.Key_Shift : self.changeSizeMoveShape = True elif event.key() == QtCore.Qt.Key_A and self.changeSizeMoveShape == True : self.width_movable_region = self.width_movable_region+ 100000 self.height_movable_region = self.height_movable_region+ 100000 self.dispatch_item.setRect(QRectF(-self.width_movable_region/2,-self.height_movable_region/2,self.width_movable_region,self.height_movable_region)) elif event.key() == QtCore.Qt.Key_Q and self.changeSizeMoveShape == True : self.width_movable_region = self.width_movable_region- 100000 self.height_movable_region = self.height_movable_region- 100000 self.dispatch_item.setRect(QRectF(-self.width_movable_region/2,-self.height_movable_region/2,self.width_movable_region,self.height_movable_region)) def keyReleaseEvent(self, event): if event.key()== QtCore.Qt.Key_Control: self.setDragMode( QtWidgets.QGraphicsView.ScrollHandDrag ) if self.dispatch_item != None : if event.key() == QtCore.Qt.Key_Shift : self.changeSizeMoveShape = False def mousePressEvent( self, event ): ''' allows target or view displacement ''' print ('mouse press event') super( MapWindow, self ).mousePressEvent( event ) if self.mode_action == Mode.Normal: if self.scene_coord: if self.draw_distance and not self.origin: self.origin = self.destination = self.mapToScene( event.pos() ) elif self.mode_action == Mode.Move : print ('....action move') if len(self.univers.selectedWarriors())> 1: self.scene.removeItem(self.dispatch_item) self.dispatch_item = None l_positions = self.univers.dispatchCircleWarriors (self.scene_coord,self.mapToScene( event.pos() ),self.width_movable_region/2) else: print ('type de left',type(self.univers.selectedWarriors()),len(self.univers.selectedWarriors())) mx,my = self.mapToScene( event.pos()).x(),self.mapToScene( event.pos()).y() pos_dest = self.scene_coord.SceneToLatLon(mx,my) pos_dest = QPointF(-pos_dest[0],pos_dest[1]) l_positions = [pos_dest] self.univers.addAction(self.current_action["type"],self.current_action["value"],self.univers.getSelectionList(),l_positions, self.current_action["offline"]) self.mode_action = Mode.Normal elif self.mode_action == Mode.Attack: pass elif self.mode_action == Mode.Heal : pass # else: # # on fait le dispatch # print ('on fait le dispatch on est en coordonne scene') # self.univers.dispatchCircleWarriors (self.scene_coord,self.mapToScene( event.pos() ),self.width_movable_region/2) # # # self.scene.removeItem(self.moveShape) # self.moveShape = None def mouseMoveEvent( self, event ): ''' allows target or view displacement or carrier displacement ''' super( MapWindow, self ).mouseMoveEvent( event ) if self.origin: self.destination = self.mapToScene( event.pos() ) if self.distance_line.scene() == self.scene: self.scene.removeItem( self.distance_line ) self.distance_line = self.computing.drawDistance( self.origin, self.destination, self.scene_coord, self.rotate_value ) self.scene.addItem( self.distance_line ) elif self.scene_coord: self.collectAndSendCursorInformations() if self.mode_action == Mode.Move and len(self.univers.selectedWarriors())> 1: if self.changeSizeMoveShape == True : self.incrSizeMoveShape = self.mapToScene( event.pos() ) - self.dispatch_item.pos() self.width_movable_region = self.width_movable_region + self.incrSizeMoveShape.x() self.height_movable_region= self.width_movable_region self.dispatch_item.setRect(QRectF(-self.width_movable_region/2,-self.height_movable_region/2,self.width_movable_region,self.height_movable_region)) else: pos = self.mapToScene( event.pos() ) #self.moveShape.setRect(QRectF(pos.x(),pos.y(),self.width_movable_region*1000,self.height_movable_region*1000)) self.dispatch_item.setPos(QPointF(pos.x(),pos.y())) item = self.itemAt(event.pos()) if item and type(item) == TempleItem: self.dispatch_item.hide() else: self.dispatch_item.show() #self.setCursor(QtCore.Qt.ArrowCursor) def mouseReleaseEvent( self, event ): ''' allows target or view displacement ''' super( MapWindow, self ).mouseReleaseEvent( event ) if self.scene_coord: self.pressed_pos = None if self.origin: if event.button() != QtCore.Qt.RightButton: self.origin = self.destination self.distances.append( self.distance_line ) self.distance_line = QtWidgets.QGraphicsLineItem() else: if self.distance_line.scene() == self.scene: self.scene.removeItem( self.distance_line ) if len( self.distances ): line_item = self.distances.pop( len( self.distances ) - 1 ) line = line_item.line() self.origin = line.p1() if line_item.scene() == self.scene: self.scene.removeItem( line_item ) if not len( self.distances ): self.origin = self.destination = None elif event.button() == QtCore.Qt.LeftButton: self.updateLatLongCenter() if event.button() == QtCore.Qt.LeftButton: self.manager.releaseEvent( event.pos(), self.mapToScene( event.pos() ) ) def menuHeros(self,event): #====== Menu Move ========== print ('context menu event de heros') menu_move = QMenu("Move") moveNormal = QAction("Normal",None) moveNormal.setData(1.0) moveNormal.triggered.connect(self.onActionMoveNormal) menu_move.addAction(moveNormal) moveSlow= QAction("Slow",None) moveSlow.setData(0.5) moveSlow.triggered.connect(self.onActionMoveNormal) menu_move.addAction(moveSlow) # moveVerySlow= QAction("Very Slow",None) # moveVerySlow.setData(0.25) # moveVerySlow.triggered.connect(self.onActionMove) # menu_move.addAction(moveVerySlow) moveFast= QAction("Fast",None) moveFast.setData(2.0) moveFast.triggered.connect(self.onActionMoveNormal) menu_move.addAction(moveFast) # moveVeryFast= QAction("Very Fast",None) # moveVeryFast.setData(4.0) # moveVeryFast.triggered.connect(self.onActionMove) # menu_move.addAction(moveVeryFast) actionTeleport= QAction("Teleport",None) actionTeleport.setData(0.0) actionTeleport.triggered.connect(self.onActionMoveNormal) menu_move.addAction(actionTeleport) #========== Menu Actions ======== menu_actions = QMenu("Action") actionAttack= QAction("Attack",None) menu_actions.addAction(actionAttack) actionHeal= QAction("Soigne",None) menu_actions.addAction(actionHeal) #======== MENU GENERAL ================ menu = QMenu() # ok = True # for w in self.univers.selectedWarriors(): # for action in self.univers.list_actions.values(): # if action.LeftPartContainHeros(w.id): # ok = False # break # if ok == True : action_running = False for w in self.univers.selectedWarriors(): if w.attribs['status']!= "repos": print ("mmmmmmmmm",w.attribs['status']) action_running = True if action_running == True : actionCancel= QAction("Cancel",None) actionCancel.triggered.connect(self.onActionCancel) menu.addAction(actionCancel) else: menu.addMenu(menu_move) menu.addMenu(menu_actions) actionPlacement= QAction("Placement",None) actionPlacement.triggered.connect(self.onActionPlacement) actionPlacement.setData(0.0) # en placement on teleport forcement menu.addAction(actionPlacement) if len(self.univers.selectedWarriors())==1 : if self.univers.selectedWarriors()[0].attribs['HP']== 0: actionRebirth= QAction("Rebirth",None) menu.addAction(actionRebirth) else: actionKill= QAction("Kill",None) menu.addAction(actionKill) #menu.exec_(event.screenPos()) #event.accept() menu.exec_(event.globalPos()) def onActionCancel (self): liste_id = [] for w in self.univers.selectedWarriors(): liste_id.append(w.id) self.univers.setCancelledHeroesId(liste_id) def onActionPlacement (self): self.onActionMove(True) def onActionMoveNormal (self): self.onActionMove(False) def onActionMove(self, offline): self.sender().data() self.current_action["type"]= ActionType.MoveToPosition self.current_action["value"] = self.sender().data() self.current_action['offline'] = offline if len(self.univers.selectedWarriors()) > 1 : if self.dispatch_item!= None : self.scene.removeItem(self.moveShape) self.dispatch_item = QGraphicsEllipseItem() if self.sender().data()<=0: #pour un mouvement normal en vert brush = QBrush(QColor(0,255,0,125)) pen = QPen(QColor(0,255,0)) elif offline == True: # pour un placement en vert brush = QBrush(QColor(255,0,0,125)) pen = QPen(QColor(255,0,0)) else: #pour une teleportation en bleue brush = QBrush(QColor(0,0,255,125)) pen = QPen(QColor(0,0,255)) self.dispatch_item.setRect(QRectF(-self.width_movable_region/2,-self.height_movable_region/2,self.width_movable_region,self.height_movable_region)) self.dispatch_item.setPen(pen) self.dispatch_item.setBrush(brush) self.dispatch_item.setZValue(2) self.scene.addItem(self.dispatch_item) if self.sender().data()<=0 and offline == False: self.viewport().setCursor(QCursor(QPixmap(":/icons/32x32/action_teleport"))) elif offline == True: self.viewport().setCursor(QCursor(QPixmap(":/icons/32x32/action_placement"))) else: self.viewport().setCursor(QCursor(QPixmap(":/icons/32x32/action_move"))) self.mode_action = Mode.Move def contextMenuEvent(self,event): #super(MapWindow,self).contextMenuEvent(event) if len(self.univers.selectedWarriors()) != 0 : self.menuHeros(event) # testAction = QAction('Move', None) # testAction.triggered.connect(self.onMoveMode) # actionAddTemple = QAction('Add Temple', None) # actionAddTemple.triggered.connect(self.onAddTemple) # menu.addAction(actionAddTemple) # menu.exec_(event.globalPos()) def onAddTemple (self): print ('add temple') #todo return False # def contextMenuEvent( self, event ): # super(MapWindow,self).contextMenuEvent(event) # print ('k') # if not self.draw_distance : # context_menu = QtWidgets.QMenu( self ) # styleSheet = \ # ''' # QMenu{ background-color:white; border:1px solid black;} # QMenu::item {padding:2px 25px 2px 20px;background-color:transparent;} # QMenu:item::selected{border-color:darkblue;background:#33CCBB;} # ''' # context_menu.setStyleSheet( styleSheet ) # # location_marker = QtWidgets.QAction( 'Add a location marker', context_menu ) # # pos = self.mapToScene( event.pos() ) # # location_marker.setObjectName( str( pos.x() ) + ' ' + str( pos.y() ) ) # # location_marker.triggered.connect( self.onLocationMarkerAdded ) # # context_menu.addAction( location_marker ) # # # res = self.scene_coord.getRealResolution() # # for row, item in enumerate( self.marker_items ): # # rect = QtCore.QRectF( item.pos(), QtCore.QSizeF( item.pixmap().width() * res, item.pixmap().height() * res ) ) # # if rect.contains( self.mapToScene( event.pos() ) ): # # remove_marker = QtWidgets.QAction( 'Remove marker', context_menu ) # # remove_marker.setObjectName( str( row ) ) # # remove_marker.triggered.connect( self.onRemoveMarker ) # # context_menu.addAction( remove_marker ) # context_menu.addSeparator() # self.contextMenu.emit( self.mapToScene( event.pos() ), context_menu ) # context_menu.exec_( event.globalPos() ) def mouseDoubleClickEvent( self, event ): ''' change tracking point or carrier position''' self.double_click.emit( self.mapToScene( event.pos() ) ) def resizeEvent( self, event ): ''' window is resizing ''' super( MapWindow, self ).resizeEvent( event ) if self.scene_coord: self.updateLatLongCenter() def updateLatLongCenter( self ): ''' centering the view after latitude/longitude change ''' scene_bounding_box = self.getSceneBoundingBox() center_position_x, center_position_y = self.computing.getCenter( scene_bounding_box ) lat, lon = self.scene_coord.MetersToLatLon( center_position_x, center_position_y ) self.center_changed.emit( lat, lon ) def updateLevel( self, scale, level, fromGraphicsView=True ): ''' update the current level ''' self.scale( scale, scale ) self.scene_coord.setLevel( level ) if fromGraphicsView: self.level_changed.emit( level ) else: self.scene_coord.setRealResolution( self.scene_coord.getResolution() ) # update items resolution for item in self.marker_items: item.setScale( self.scene_coord.getRealResolution() ) def collectAndSendCursorInformations( self ): ''' update the labels value ''' # mouse position mouse_position = self.mapToScene( self.mapFromGlobal( self.cursor().pos() ) ) # lat long lx, ly = self.scene_coord.MetersToLatLon( mouse_position.x(), mouse_position.y() ) # meters mx, my = self.scene_coord.MetersToScene( mouse_position.x(), mouse_position.y() ) # tiles tx, ty = self.scene_coord.MetersToTile( mouse_position.x(), mouse_position.y() ) self.update_labels.emit( lx, ly, mx, my, tx, ty ) # def onLocationMarkerAdded( self ): # pixmap = QtGui.QPixmap( ':/icons 16x16/resources/16x16/marker.png' ) # self.marker_item = MarkerItem( pixmap ) # self.marker_item.setZValue( sys.maxint ) # res = self.scene_coord.getRealResolution() # self.marker_item.setScale( res ) # # sender = self.sender() # x, y = sender.objectName().split( ' ' ) # rect = self.marker_item.boundingRect() # self.marker_item.setPos( float( x ) - 0.5 * rect.width(), float( y ) - rect.height() ) # # self.scene.addItem( self.marker_item ) # # self.marker_items.append( self.marker_item ) # # def onRemoveMarker( self ): # sender = self.sender() # item = self.marker_items[int( sender.objectName() )] # if item: # if item.scene() == self.scene: # self.scene.removeItem( item ) # self.marker_items.remove( item ) def onLevelChanged( self, level ): ''' scaling after a change of spin box level ''' if self.scene_coord: scale = self.computing.getViewScale( self.transform(), self.scene_coord.getLevelResolution( level ) ) self.updateLevel( scale, level, False ) def onLastLayerRemoved( self, layer ): ''' the last layer was removed (slot) ''' self.onLayerRemoved( layer ) self.viewFromScratch() def onLayerAdded( self, layer, first ): ''' a layer was added (slot) ''' if first == True: print ('init graphicsView') self.initGraphicsView( 'WebMercator', int(self.settings.value("map/initial_level",6)), float(self.settings.value("map/initial_lat",48.858093)), float(self.settings.value("map/initial_lon",2.294694)) ) self.manager.addLayer( layer ) print ('add layer finished ',layer) def onLayerRemoved( self, layer ): ''' a layer was removed (slot) ''' self.manager.removeLayer( layer ) def onRotationSliderValueChanged( self, value ): ''' update rotation value ''' self.rotate( value ) self.rotate_value += value for item in self.marker_items: item.setRotation( -self.rotate_value ) self.manager.updateRotation( self.rotate_value ) def onResetRotation( self ): ''' reset rotaiton value ''' self.rotate( -self.rotate_value ) self.rotate_value = 0 for item in self.marker_items: item.setRotation( self.rotate_value ) self.manager.updateRotation( self.rotate_value ) def updateRotation( self, rotation_value ): self.rotate( rotation_value ) self.rotate_value += rotation_value for item in self.marker_items: # item.setRotation( rotation_value ) item.setRotation( -self.rotate_value ) self.rotation_changed.emit( self.rotate_value ) self.manager.updateRotation( self.rotate_value ) def onCarrierPositionChanged( self, c_mx, c_my, alt=0.0 ): ''' update observer coordinates if it's the carrier ''' if self.mode == 'CenterOnCarrierOrientNorth' or self.mode == 'CenterOnCarrier': self.observer_x, self.observer_y = c_mx, c_my self.centerOnObserver() def onCarrierRotationChanged( self, rotation_value ): ''' update observer rotation if needed ''' if self.mode == 'CenterOnCarrier' or self.mode == 'CenterOnBarycenter': rotation_value = M.degrees( -rotation_value ) self.rotate( rotation_value - self.rotate_value ) self.rotate_value = rotation_value self.rotation_changed.emit( self.rotate_value ) self.manager.updateRotation( self.rotate_value ) def onTargetPositionChanged( self, mx, my ): ''' update observer coordinates if it's the target''' if self.mode == 'CenterOnTarget': self.observer_x, self.observer_y = mx, my self.centerOnObserver() def onBarycenterPositionChanged( self, c_mx, c_my, mx, my ): ''' update observer coordinates if it's baryenter between carrier and target ''' if self.mode == 'CenterOnBarycenterOrientNorth' or self.mode == 'CenterOnBarycenter': self.observer_x, self.observer_y = ( c_mx + mx ) / 2.0, ( c_my + my ) / 2.0 self.centerOnObserver() self.optimizeObserverLevel( c_mx, c_my, mx, my ) def optimizeObserverLevel( self, c_mx, c_my, mx, my ): scene_bounding_box = self.getSceneBoundingBox() if not scene_bounding_box.contains( c_mx, c_my ) or not scene_bounding_box.contains( mx, my ): self.minus_level.emit() # else: # res = self.scene_coord.getRealResolution() # res_level_up = self.scene_coord.getLevelResolution( self.scene_coord.getLevel() + 1 ) # scale_factor = res_level_up / res # w, h = scene_bounding_box.width(), scene_bounding_box.height() # scene_bounding_box = scene_bounding_box.adjusted( 0.5 * w * scale_factor, 0.5 * h * scale_factor, -0.5 * w * scale_factor, -0.5 * h * scale_factor ) # if scene_bounding_box.contains( c_mx, c_my ) or scene_bounding_box.contains( mx, my ): # self.major_level.emit() def setMode( self, mode ): ''' update observer mode ''' self.mode = mode if self.mode == 'CenterOnCarrierOrientNorth' or self.mode == 'CenterOnTarget' or self.mode == 'CenterOnBarycenterOrientNorth': self.onResetRotation() self.rotation_changed.emit( self.rotate_value ) def getManager( self ): ''' return the layer manager ''' return self.manager # def getTouchEvent( self ): # ''' return the touch event manager ''' # return self.touch_event def getSceneCoord( self ): ''' return the projection manager ''' return self.scene_coord def setDrawDistance( self, activated ): self.draw_distance = activated if not self.draw_distance: for line_item in self.distances: if line_item.scene() == self.scene: self.scene.removeItem( line_item ) self.distances = [] self.origin = self.destination = None if self.distance_line.scene() == self.scene: self.scene.removeItem( self.distance_line ) self.viewport().setCursor( self.cursor_shape ) else: self.cursor_shape = self.viewport().cursor().shape() self.viewport().setCursor( QtCore.Qt.CrossCursor )
class MapWindow(QGraphicsView): """ Qt widget based on QGraphicsView to display map image and control map with keyboard. :var map: Map object. :var position: Current position on the map. """ def __init__(self, map, *args): super().__init__(*args) self.map = map self.position = map.center self.providers = deque([ 'osm', 'stamen-terrain', 'stamen-toner-lite', 'stamen-toner', 'stamen-watercolor', 'ms-aerial', 'ms-hybrid', 'ms-road', 'bluemarble', ]) self.refresh_map = asyncio.Event() scene = QGraphicsScene() self.scene = scene self.setScene(scene) self.map_layer = QGraphicsPixmapItem() scene.addItem(self.map_layer) self.circle = QGraphicsEllipseItem(0, 0, 20, 20) pen = QPen(QColor(255, 0, 0, 128)) pen.setWidth(2) self.circle.setPen(pen) scene.addItem(self.circle) self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) def centerOn(self, x, y): """ Center on (x, y) coordinates, which reflect current map position and draw current position marker. """ super().centerOn(x, y) self.circle.setRect(x - 10, y - 10, 20, 20) def keyPressEvent(self, event): """ Handle key press events - '-' to zoom out - '+'/'=' to zoom in - 'n' to use next map provider - 'p' to use previous map provider - 'r' to refresh map - 'q' to quit """ key = event.key() if key == QtCore.Qt.Key_Minus: self.map.zoom -= 1 self.refresh_map.set() elif key == QtCore.Qt.Key_Plus or key == QtCore.Qt.Key_Equal: self.map.zoom += 1 self.refresh_map.set() elif key == QtCore.Qt.Key_Q: loop.stop() elif key == QtCore.Qt.Key_N: self.providers.rotate(-1) p = self.providers[0] self.map.provider = geotiler.find_provider(p) self.refresh_map.set() elif key == QtCore.Qt.Key_P: self.providers.rotate(1) p = self.providers[0] self.map.provider = geotiler.find_provider(p) self.refresh_map.set() elif key == QtCore.Qt.Key_R: self.refresh_map.set() def resizeEvent(self, event): """ On resize event redraw the map. """ scroll_map(self, self.position)
class EndpointItem(QGraphicsPathItem): _filter_name = "endpoint" def __init__(self, strand_item, cap_type, is_drawn5to3): """The parent should be a StrandItem.""" super(EndpointItem, self).__init__(strand_item.virtualHelixItem()) self._strand_item = strand_item self._getActiveTool = strand_item._getActiveTool self._cap_type = cap_type self._low_drag_bound = None self._high_drag_bound = None self._mod_item = None self._initCapSpecificState(is_drawn5to3) self.setPen(QPen()) # for easier mouseclick self._click_area = cA = QGraphicsRectItem(_DEFAULT_RECT, self) self._click_area.setAcceptHoverEvents(True) cA.hoverMoveEvent = self.hoverMoveEvent cA.mousePressEvent = self.mousePressEvent cA.mouseMoveEvent = self.mouseMoveEvent cA.setPen(_NO_PEN) self.setFlag(QGraphicsItem.ItemIsSelectable) # end def # def __repr__(self): # return "%s" % self.__class__.__name__ ### SIGNALS ### ### SLOTS ### ### ACCESSORS ### def idx(self): """Look up base_idx, as determined by strandItem idxs and cap type.""" if self._cap_type == 'low': return self._strand_item.idxs()[0] else: # high or dual, doesn't matter return self._strand_item.idxs()[1] # end def def partItem(self): return self._strand_item.partItem() # end def def disableEvents(self): self._click_area.setAcceptHoverEvents(False) self.mouseMoveEvent = QGraphicsPathItem.mouseMoveEvent self.mousePressEvent = QGraphicsPathItem.mousePressEvent # end def def window(self): return self._strand_item.window() ### PUBLIC METHODS FOR DRAWING / LAYOUT ### def updatePosIfNecessary(self, idx): """Update position if necessary and return True if updated.""" group = self.group() self.tempReparent() x = int(idx * _BASE_WIDTH) if x != self.x(): self.setPos(x, self.y()) if group: group.addToGroup(self) return True else: if group: group.addToGroup(self) return False def safeSetPos(self, x, y): """ Required to ensure proper reparenting if selected """ group = self.group() self.tempReparent() self.setPos(x,y) if group: group.addToGroup(self) # end def def resetEndPoint(self, is_drawn5to3): self.setParentItem(self._strand_item.virtualHelixItem()) self._initCapSpecificState(is_drawn5to3) upperLeftY = 0 if is_drawn5to3 else _BASE_WIDTH self.setY(upperLeftY) # end def def showMod(self, mod_id, color): self._mod_item = QGraphicsEllipseItem(MOD_RECT, self) self.changeMod(mod_id, color) self._mod_item.show() # print("Showing {}".format(mod_id)) # end def def changeMod(self, mod_id, color): self._mod_id = mod_id self._mod_item.setBrush(QBrush(QColor(color))) # end def def destroyMod(self): self.scene().removeItem(self._mod_item) self._mod_item = None self._mod_id = None # end def def destroy(self): scene = self.scene() if self._mod_item is not None: self.destroyMod() scene.removeItem(self._click_area) self._click_area = None scene.removeItem(self) # end def ### PRIVATE SUPPORT METHODS ### def _initCapSpecificState(self, is_drawn5to3): c_t = self._cap_type if c_t == 'low': path = PP_L5 if is_drawn5to3 else PP_L3 elif c_t == 'high': path = PP_R3 if is_drawn5to3 else PP_R5 elif c_t == 'dual': path = PP_53 if is_drawn5to3 else PP_35 self.setPath(path) # end def def _getNewIdxsForResize(self, base_idx): """Returns a tuple containing idxs to be passed to the """ c_t = self._cap_type if c_t == 'low': return (base_idx, self._strand_item.idxs()[1]) elif c_t == 'high': return (self._strand_item.idxs()[0], base_idx) elif c_t == 'dual': raise NotImplementedError ### EVENT HANDLERS ### def mousePressEvent(self, event): """ Parses a mousePressEvent, calling the approproate tool method as necessary. Stores _moveIdx for future comparison. """ self.scene().views()[0].addToPressList(self) self._strand_item.virtualHelixItem().setActive(self.idx()) self._moveIdx = self.idx() active_tool_str = self._getActiveTool().methodPrefix() tool_method_name = active_tool_str + "MousePress" if hasattr(self, tool_method_name): # if the tool method exists modifiers = event.modifiers() getattr(self, tool_method_name)(modifiers, event, self.idx()) def hoverLeaveEvent(self, event): self._strand_item.hoverLeaveEvent(event) # end def def hoverMoveEvent(self, event): """ Parses a mousePressEvent, calling the approproate tool method as necessary. Stores _moveIdx for future comparison. """ vhi_num = self._strand_item._virtual_helix_item.number() oligo_length = self._strand_item._model_strand.oligo().length() msg = "%d[%d]\tlength: %d" % (vhi_num, self.idx(), oligo_length) self.partItem().updateStatusBar(msg) active_tool_str = self._getActiveTool().methodPrefix() if active_tool_str == 'pencilTool': return self._strand_item.pencilToolHoverMove(event, self.idx()) def mouseMoveEvent(self, event): """ Parses a mouseMoveEvent, calling the approproate tool method as necessary. Updates _moveIdx if it changed. """ tool_method_name = self._getActiveTool().methodPrefix() + "MouseMove" if hasattr(self, tool_method_name): # if the tool method exists idx = int(floor((self.x() + event.pos().x()) / _BASE_WIDTH)) if idx != self._moveIdx: # did we actually move? modifiers = event.modifiers() self._moveIdx = idx getattr(self, tool_method_name)(modifiers, idx) def customMouseRelease(self, event): """ Parses a mouseReleaseEvent, calling the approproate tool method as necessary. Deletes _moveIdx if necessary. """ tool_method_name = self._getActiveTool().methodPrefix() + "MouseRelease" if hasattr(self, tool_method_name): # if the tool method exists modifiers = event.modifiers() x = event.pos().x() getattr(self, tool_method_name)(modifiers, x) # call tool method if hasattr(self, '_move_idx'): del self._moveIdx ### TOOL METHODS ### def addSeqToolMousePress(self, modifiers, event, idx): """ Checks that a scaffold was clicked, and then calls apply sequence to the clicked strand via its oligo. """ m_strand = self._strand_item._model_strand if m_strand.isScaffold(): olgLen, seqLen = self._getActiveTool().applySequence(m_strand.oligo()) if olgLen: msg = "Populated %d of %d scaffold bases." % (min(seqLen, olgLen), olgLen) if olgLen > seqLen: d = olgLen - seqLen msg = msg + " Warning: %d bases have no sequence." % d elif olgLen < seqLen: d = seqLen - olgLen msg = msg + " Warning: %d sequence bases unused." % d self.partItem().updateStatusBar(msg) # end def def modsToolMousePress(self, modifiers, event, idx): """ Checks that a scaffold was clicked, and then calls apply sequence to the clicked strand via its oligo. """ m_strand = self._strand_item._model_strand self._getActiveTool().applyMod(m_strand, idx) # end def def breakToolMouseRelease(self, modifiers, x): """Shift-click to merge without switching back to select tool.""" m_strand = self._strand_item._model_strand if modifiers & Qt.ShiftModifier: m_strand.merge(self.idx()) # end def def eraseToolMousePress(self, modifiers, event, idx): """Erase the strand.""" m_strand = self._strand_item._model_strand m_strand.strandSet().removeStrand(m_strand) # end def def insertionToolMousePress(self, modifiers, event, idx): """Add an insert to the strand if possible.""" m_strand = self._strand_item._model_strand m_strand.addInsertion(idx, 1) # end def def paintToolMousePress(self, modifiers, event, idx): """Add an insert to the strand if possible.""" m_strand = self._strand_item._model_strand if m_strand.isStaple(): color = self.window().path_color_panel.stapColorName() else: color = self.window().path_color_panel.scafColorName() m_strand.oligo().applyColor(color) # end def def pencilToolHoverMove(self, idx): """Pencil the strand is possible.""" m_strand = self._strand_item._model_strand vhi = self._strand_item._virtual_helix_item active_tool = self._getActiveTool() if not active_tool.isFloatingXoverBegin(): temp_xover = active_tool.floatingXover() temp_xover.updateFloatingFromStrandItem(vhi, m_strand, idx) # if m_strand.idx5Prime() == idx: # tempXover.hide3prime() # end def def pencilToolMousePress(self, modifiers, event, idx): """Break the strand is possible.""" m_strand = self._strand_item._model_strand vhi = self._strand_item._virtual_helix_item part_item = vhi.partItem() active_tool = self._getActiveTool() if active_tool.isFloatingXoverBegin(): if m_strand.idx5Prime() == idx: return temp_xover = active_tool.floatingXover() temp_xover.updateBase(vhi, m_strand, idx) active_tool.setFloatingXoverBegin(False) # tempXover.hide5prime() else: active_tool.setFloatingXoverBegin(True) # install Xover active_tool.attemptToCreateXover(vhi, m_strand, idx) # end def # def selectToolMousePress(self, modifiers, event): # """ # Set the allowed drag bounds for use by selectToolMouseMove. # """ # print "mouse press ep", self.parentItem() # # print "%s.%s [%d]" % (self, util.methodName(), self.idx()) # self._low_drag_bound, self._high_drag_bound = \ # self._strand_item._model_strand.getResizeBounds(self.idx()) # s_i = self._strand_item # viewroot = s_i.viewroot() # selection_group = viewroot.strandItemSelectionGroup() # selection_group.setInstantAdd(True) # self.setSelected(True) # # end def def selectToolMousePress(self, modifiers, event, idx): """ Set the allowed drag bounds for use by selectToolMouseMove. """ # print "%s.%s [%d]" % (self, util.methodName(), self.idx()) self._low_drag_bound, self._high_drag_bound = \ self._strand_item._model_strand.getResizeBounds(self.idx()) s_i = self._strand_item viewroot = s_i.viewroot() current_filter_dict = viewroot.selectionFilterDict() if s_i.strandFilter() in current_filter_dict \ and self._filter_name in current_filter_dict: selection_group = viewroot.strandItemSelectionGroup() mod = Qt.MetaModifier if not (modifiers & mod): selection_group.clearSelection(False) selection_group.setSelectionLock(selection_group) selection_group.pendToAdd(self) selection_group.processPendingToAddList() return selection_group.mousePressEvent(event) # end def def selectToolMouseMove(self, modifiers, idx): """ Given a new index (pre-validated as different from the prev index), calculate the new x coordinate for self, move there, and notify the parent strandItem to redraw its horizontal line. """ idx = util.clamp(idx, self._low_drag_bound, self._high_drag_bound) # x = int(idx * _BASE_WIDTH) # self.setPos(x, self.y()) # self._strand_item.updateLine(self) # end def def selectToolMouseRelease(self, modifiers, x): """ If the positional-calculated idx differs from the model idx, it means we have moved and should notify the model to resize. If the mouse event had a key modifier, perform special actions: shift = attempt to merge with a neighbor alt = extend to max drag bound """ m_strand = self._strand_item._model_strand base_idx = int(floor(self.x() / _BASE_WIDTH)) # if base_idx != self.idx(): # new_idxs = self._getNewIdxsForResize(base_idx) # m_strand.resize(new_idxs) if modifiers & Qt.AltModifier: if self._cap_type == 'low': new_idxs = self._getNewIdxsForResize(self._low_drag_bound) else: new_idxs = self._getNewIdxsForResize(self._high_drag_bound) m_strand.resize(new_idxs) elif modifiers & Qt.ShiftModifier: self.setSelected(False) self.restoreParent() m_strand.merge(self.idx()) # end def def skipToolMousePress(self, modifiers, event, idx): """Add an insert to the strand if possible.""" m_strand = self._strand_item._model_strand m_strand.addInsertion(idx, -1) # end def def restoreParent(self, pos=None): """ Required to restore parenting and positioning in the partItem """ # map the position # print "restoring parent ep" self.tempReparent(pos) self.setSelectedColor(False) self.setSelected(False) # end def def tempReparent(self, pos=None): vhItem = self._strand_item.virtualHelixItem() if pos == None: pos = self.scenePos() self.setParentItem(vhItem) tempP = vhItem.mapFromScene(pos) self.setPos(tempP) # end def def setSelectedColor(self, value): if value == True: color = styles.SELECTED_COLOR else: oligo = self._strand_item.strand().oligo() color = QColor(oligo.color()) if oligo.shouldHighlight(): color.setAlpha(128) brush = self.brush() brush.setColor(color) self.setBrush(brush) # end def def updateHighlight(self, brush): if not self.isSelected(): self.setBrush(brush) # end def 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_dict = viewroot.selectionFilterDict() selection_group = viewroot.strandItemSelectionGroup() # only add if the selection_group is not locked out if value == True and self._filter_name in current_filter_dict: # if self.group() != selection_group \ # and s_i.strandFilter() in current_filter_dict: if s_i.strandFilter() in current_filter_dict: 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 # 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_dict = viewroot.selectionFilterDict() if s_i.strandFilter() in current_filter_dict: 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) # end def def modelDeselect(self, document): strand = self._strand_item.strand() test = document.isModelStrandSelected(strand) low_val, high_val = document.getSelectedStrandValue(strand) if test \ else (False, False) if self._cap_type == 'low': out_value = (False, high_val) else: out_value = (low_val, False) if not out_value[0] and not out_value[1] and test: document.removeStrandFromSelection(strand) elif out_value[0] or out_value[1]: document.addStrandToSelection(strand, out_value) self.restoreParent() # end def def modelSelect(self, document): strand = self._strand_item.strand() test = document.isModelStrandSelected(strand) low_val, high_val = document.getSelectedStrandValue(strand) if test \ else (False, False) if self._cap_type == 'low': out_value = (True, high_val) else: out_value = (low_val, True) self.setSelected(True) self.setSelectedColor(True) document.addStrandToSelection(strand, out_value) # end def def paint(self, painter, option, widget): painter.setPen(self.pen()) painter.setBrush(self.brush()) painter.drawPath(self.path())
def paint(self, *args, **kwargs): QGraphicsEllipseItem.paint(self, *args, **kwargs) for obs in self.observers: obs.obsUpdate()
class AbstractSliceTool(QGraphicsObject): """Summary Attributes: angles (TYPE): Description FILTER_NAME (str): Description is_started (bool): Description manager (TYPE): Description part_item (TYPE): Description sgv (TYPE): Description vectors (TYPE): Description """ _RADIUS = styles.SLICE_HELIX_RADIUS _CENTER_OF_HELIX = QPointF(_RADIUS, _RADIUS) FILTER_NAME = 'virtual_helix' # _CENTER_OF_HELIX = QPointF(0. 0.) """Abstract base class to be subclassed by all other pathview tools.""" def __init__(self, manager): """Summary Args: manager (TYPE): Description """ super(AbstractSliceTool, self).__init__(parent=manager.viewroot) """ Pareting to viewroot to prevent orphan _line_item from occuring """ self.sgv = None self.manager = manager self._active = False self._last_location = None self._line_item = QGraphicsLineItem(self) self._line_item.hide() self._vhi = None self.hide() self.is_started = False self.angles = [math.radians(x) for x in range(0, 360, 30)] self.vectors = self.setVectors() self.part_item = None self.vhi_hint_item = QGraphicsEllipseItem(_DEFAULT_RECT, self) self.vhi_hint_item.setPen(_MOD_PEN) self.vhi_hint_item.setZValue(styles.ZPARTITEM) # end def ######################## Drawing ####################################### def setVectors(self): """Summary Returns: TYPE: Description """ rad = self._RADIUS return [QLineF(rad, rad, rad*(1. + 2.*math.cos(x)), rad*(1. + 2.*math.sin(x)) ) for x in self.angles] # end def def setVirtualHelixItem(self, virtual_helix_item): """Summary Args: virtual_helix_item (cadnano.gui.views.sliceview.virtualhelixitem.VirtualHelixItem): Description Returns: TYPE: Description """ rad = self._RADIUS self._vhi = virtual_helix_item li = self._line_item li.setParentItem(virtual_helix_item) li.setLine(rad, rad, rad, rad) # li.setLine(0., 0., 0., 0.) # end def def setSelectionFilter(self, filter_name_list): if 'virtual_helix' in filter_name_list: self.vhi_hint_item.setPen(_MOD_PEN) else: self.vhi_hint_item.setPen(_INACTIVE_PEN) # end def def resetTool(self): """Summary Returns: TYPE: Description """ self._line_item.setParentItem(self) def idNum(self): """Summary Returns: TYPE: Description """ if self._vhi is not None: return self._vhi.idNum() def setPartItem(self, part_item): """Summary Args: part_item (TYPE): Description Returns: TYPE: Description """ self.vhi_hint_item.setParentItem(part_item) self.part_item = part_item # end def def boundingRect(self): """Required to prevent NotImplementedError() """ return QRectF() def eventToPosition(self, part_item, event): """take an event and return a position as a QPointF update widget as well Args: part_item (TYPE): Description event (TYPE): Description """ if self.is_started: pos = self.findNearestPoint(part_item, event.scenePos()) else: pos = event.pos() self.vhi_hint_item.setPos( pos - QPointF(_RADIUS - DELTA, _RADIUS - DELTA)) return pos # end def def setHintPos(self, pos): self.vhi_hint_item.setPos( pos - QPointF(_RADIUS - DELTA, _RADIUS - DELTA)) # end def def findNearestPoint(self, part_item, target_scenepos): """ Args: part_item (TYPE): Description target_scenepos (TYPE): Description """ li = self._line_item pos = li.mapFromScene(target_scenepos) line = li.line() mouse_point_vec = QLineF(self._CENTER_OF_HELIX, pos) # Check if the click happened on the origin VH if mouse_point_vec.length() < self._RADIUS: # return part_item.mapFromScene(target_scenepos) return None angle_min = 9999 direction_min = None for vector in self.vectors: angle_new = mouse_point_vec.angleTo(vector) if angle_new < angle_min: direction_min = vector angle_min = angle_new if direction_min is not None: li.setLine(direction_min) return part_item.mapFromItem(li, direction_min.p2()) else: print("default point") line.setP2(pos) li.setLine(line) return part_item.mapFromItem(li, pos) # end def def findNextPoint(self, part_item, target_part_pos): """ Args: part_item (TYPE): Description target_part_pos (TYPE): Description """ li = self._line_item pos = li.mapFromItem(part_item, target_part_pos) for i, vector in enumerate(self.vectors): if vector.p2() == pos: return part_item.mapFromItem(li, self.vectors[i - 1].p2()) # origin VirtualHelixItem is overlapping destination VirtualHelixItem return part_item.mapFromItem(li, self.vectors[0].p2()) # end def def hideLineItem(self): """Summary Returns: TYPE: Description """ self.vhi_hint_item.hide() li = self._line_item li.hide() li.setParentItem(self) line = li.line() line.setP2(self._CENTER_OF_HELIX) li.setLine(line) # li.hide() self.is_started = False # end def # def hoverEnterEvent(self, event): # self.vhi_hint_item.show() # #print("Slice VHI hoverEnterEvent") # # def hoverMoveEvent(self, event): # # print("Slice VHI hoverMoveEvent") # def hoverLeaveEvent(self, event): # # self.vhi_hint_item.hide() # #print("Slice VHI hoverLeaveEvent") def hoverMoveEvent(self, part_item, event): """Summary Args: part_item (TYPE): Description event (TYPE): Description Returns: TYPE: Description """ # self.vhi_hint_item.setPos( event.pos()- # QPointF(_RADIUS - DELTA, _RADIUS - DELTA)) pos = self.eventToPosition(part_item, event) return pos # end def def setActive(self, will_be_active, old_tool=None): """ Called by SliceToolManager.setActiveTool when the tool becomes active. Used, for example, to show/hide tool-specific ui elements. Args: will_be_active (TYPE): Description old_tool (None, optional): Description """ if self._active and not will_be_active: self.deactivate() self._active = will_be_active self.sgv = self.manager.window.slice_graphics_view if hasattr(self, 'getCustomContextMenu'): # print("connecting ccm") try: # Hack to prevent multiple connections self.sgv.customContextMenuRequested.disconnect() except: pass self.sgv.customContextMenuRequested.connect(self.getCustomContextMenu) # end def def deactivate(self): """Summary Returns: TYPE: Description """ if hasattr(self, 'getCustomContextMenu'): # print("disconnecting ccm") self.sgv.customContextMenuRequested.disconnect(self.getCustomContextMenu) self.sgv = None self.is_started = False self.hideLineItem() self._vhi = None self.part_item = None self.hide() self._active = False # end def def isActive(self): """Returns isActive """ return self._active
def setupScene(self): self.m_scene.setSceneRect(-300, -200, 600, 460) linearGrad = QLinearGradient(QPointF(-100, -100), QPointF(100, 100)) linearGrad.setColorAt(0, QColor(255, 255, 255)) linearGrad.setColorAt(1, QColor(192, 192, 255)) self.setBackgroundBrush(linearGrad) radialGrad = QRadialGradient(30, 30, 30) radialGrad.setColorAt(0, Qt.yellow) radialGrad.setColorAt(0.2, Qt.yellow) radialGrad.setColorAt(1, Qt.transparent) pixmap = QPixmap(60, 60) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) painter.setPen(Qt.NoPen) painter.setBrush(radialGrad) painter.drawEllipse(0, 0, 60, 60) painter.end() self.m_lightSource = self.m_scene.addPixmap(pixmap) self.m_lightSource.setZValue(2) for i in range(-2, 3): for j in range(-2, 3): if (i + j) & 1: item = QGraphicsEllipseItem(0, 0, 50, 50) else: item = QGraphicsRectItem(0, 0, 50, 50) item.setPen(QPen(Qt.black, 1)) item.setBrush(QBrush(Qt.white)) effect = QGraphicsDropShadowEffect(self) effect.setBlurRadius(8) item.setGraphicsEffect(effect) item.setZValue(1) item.setPos(i * 80, j * 80) self.m_scene.addItem(item) self.m_items.append(item)
def __init__(self, rect, parent=None): super(QGraphicsEllipseItem, self).__init__(rect, parent) self._parent = parent self.setPen(getNoPen()) iw = _ITEM_WIDTH = 3 x = _RECT.width() - 2*rect_gain - 2*styles.SLICE_HELIX_STROKE_WIDTH - 1 y = _RECT.center().y() prexo_items = {} fwd_angles = [0, 240, 120] fwd_colors = ['#cc0000', '#00cc00', '#0000cc'] for i in range(len(fwd_angles)): item = QGraphicsEllipseItem(x, y, iw, iw, self) item.setPen(getNoPen()) item.setBrush(getBrushObj(fwd_colors[i])) item.setTransformOriginPoint(_RECT.center()) item.setRotation(fwd_angles[i]) prexo_items[i] = item rev_angles = [150, 30, 270] rev_colors = ['#800000cc', '#80cc0000', '#8000cc00'] # rev_colors = ['#ff00ff', '#3399ff', '#ff6600'] for i in range(len(fwd_angles)): item = QGraphicsEllipseItem(x, y, iw, iw, self) item.setPen(getPenObj(rev_colors[i],0.5)) item.setBrush(getNoBrush()) item.setTransformOriginPoint(_RECT.center()) item.setRotation(rev_angles[i]) prexo_items[i] = item
class EndpointItem(QGraphicsPathItem): FILTER_NAME = "endpoint" def __init__(self, strand_item: PathStrandItemT, cap_type: str, # low, high, dual is_drawn5to3: bool): """The parent should be a StrandItem.""" super(EndpointItem, self).__init__(strand_item.virtualHelixItem()) self._strand_item = strand_item self._getActiveTool = strand_item._getActiveTool self.cap_type = cap_type self._low_drag_bound = None self._high_drag_bound = None self._mod_item = None self._isdrawn5to3 = is_drawn5to3 self._initCapSpecificState(is_drawn5to3) p = QPen() p.setCosmetic(True) self.setPen(p) # for easier mouseclick self._click_area = cA = QGraphicsRectItem(_DEFAULT_RECT, self) self._click_area.setAcceptHoverEvents(True) cA.hoverMoveEvent = self.hoverMoveEvent cA.mousePressEvent = self.mousePressEvent cA.mouseMoveEvent = self.mouseMoveEvent cA.setPen(_NO_PEN) self.setFlag(QGraphicsItem.ItemIsSelectable) # end def ### SIGNALS ### ### SLOTS ### ### ACCESSORS ### def idx(self) -> int: """Look up ``base_idx``, as determined by :class:`StrandItem `idxs and cap type.""" if self.cap_type == 'low': return self._strand_item.idxs()[0] else: # high or dual, doesn't matter return self._strand_item.idxs()[1] # end def def partItem(self) -> PathNucleicAcidPartItemT: return self._strand_item.partItem() # end def def disableEvents(self): self._click_area.setAcceptHoverEvents(False) self.mouseMoveEvent = QGraphicsPathItem.mouseMoveEvent self.mousePressEvent = QGraphicsPathItem.mousePressEvent # end def def window(self) -> WindowT: return self._strand_item.window() ### PUBLIC METHODS FOR DRAWING / LAYOUT ### def updatePosIfNecessary(self, idx: int) -> Tuple[bool, SelectionItemGroup]: """Update position if necessary and return ``True`` if updated.""" group = self.group() self.tempReparent() x = int(idx * _BASE_WIDTH) if x != self.x(): self.setPos(x, self.y()) # if group: # group.addToGroup(self) return True, group else: # if group: # group.addToGroup(self) return False, group def safeSetPos(self, x: float, y: float): """ Required to ensure proper reparenting if selected """ group = self.group() self.tempReparent() self.setPos(x, y) if group: group.addToGroup(self) # end def def resetEndPoint(self, is_drawn5to3: bool): self.setParentItem(self._strand_item.virtualHelixItem()) self._initCapSpecificState(is_drawn5to3) upperLeftY = 0 if is_drawn5to3 else _BASE_WIDTH self.setY(upperLeftY) # end def def showMod(self, mod_id: str, color: str): self._mod_item = QGraphicsEllipseItem(MOD_RECT, self) self.changeMod(mod_id, color) self._mod_item.show() # print("Showing {}".format(mod_id)) # end def def changeMod(self, mod_id: str, color: str): self._mod_id = mod_id self._mod_item.setBrush(QBrush(getColorObj(color))) # end def def destroyMod(self): self.scene().removeItem(self._mod_item) self._mod_item = None self._mod_id = None # end def def destroyItem(self): '''Remove this object and references to it from the view ''' scene = self.scene() if self._mod_item is not None: self.destroyMod() scene.removeItem(self._click_area) self._click_area = None scene.removeItem(self) # end def ### PRIVATE SUPPORT METHODS ### def _initCapSpecificState(self, is_drawn5to3: bool): c_t = self.cap_type if c_t == 'low': path = PP_L5 if is_drawn5to3 else PP_L3 elif c_t == 'high': path = PP_R3 if is_drawn5to3 else PP_R5 elif c_t == 'dual': path = PP_53 if is_drawn5to3 else PP_35 self.setPath(path) # end def ### EVENT HANDLERS ### def mousePressEvent(self, event: QGraphicsSceneMouseEvent): """Parses a :meth:`mousePressEvent`, calling the appropriate tool method as necessary. Stores ``_move_idx`` for future comparison. """ self.scene().views()[0].addToPressList(self) idx = self._strand_item.setActiveEndpoint(self.cap_type) self._move_idx = idx active_tool_str = self._getActiveTool().methodPrefix() tool_method_name = active_tool_str + "MousePress" if hasattr(self, tool_method_name): # if the tool method exists modifiers = event.modifiers() getattr(self, tool_method_name)(modifiers, event, self.idx()) def hoverLeaveEvent(self, event: QGraphicsSceneHoverEvent): self._strand_item.hoverLeaveEvent(event) # end def def hoverMoveEvent(self, event: QGraphicsSceneHoverEvent): """Parses a :meth:`hoverMoveEvent`, calling the approproate tool method as necessary. """ vhi_num = self._strand_item.idNum() oligo_length = self._strand_item._model_strand.oligo().length() msg = "%d[%d]\tlength: %d" % (vhi_num, self.idx(), oligo_length) self.partItem().updateStatusBar(msg) active_tool_str = self._getActiveTool().methodPrefix() if active_tool_str == 'createTool': return self._strand_item.createToolHoverMove(event, self.idx()) elif active_tool_str == 'addSeqTool': return self.addSeqToolHoverMove(event, self.idx()) def mouseMoveEvent(self, event: QGraphicsSceneMouseEvent): """Parses a :meth:`mouseMoveEvent`, calling the appropriate tool method as necessary. Updates ``_move_idx`` if it changed. """ tool_method_name = self._getActiveTool().methodPrefix() + "MouseMove" if hasattr(self, tool_method_name): # if the tool method exists idx = int(floor((self.x() + event.pos().x()) / _BASE_WIDTH)) if idx != self._move_idx: # did we actually move? modifiers = event.modifiers() self._move_idx = idx getattr(self, tool_method_name)(modifiers, idx) def customMouseRelease(self, event: QMouseEvent): """Parses a :meth:`mouseReleaseEvent` from view, calling the appropriate tool method as necessary. Deletes ``_move_idx`` if necessary. """ tool_method_name = self._getActiveTool().methodPrefix() + "MouseRelease" if hasattr(self, tool_method_name): # if the tool method exists modifiers = event.modifiers() x = event.pos().x() getattr(self, tool_method_name)(modifiers, x) # call tool method if hasattr(self, '_move_idx'): del self._move_idx ### TOOL METHODS ### def modsToolMousePress(self, modifiers: Qt.KeyboardModifiers, event: QGraphicsSceneMouseEvent, idx: int): """ Checks that a scaffold was clicked, and then calls apply sequence to the clicked strand via its oligo. """ m_strand = self._strand_item._model_strand self._getActiveTool().applyMod(m_strand, idx) # end def def breakToolMouseRelease(self, modifiers: Qt.KeyboardModifiers, x): """Shift-click to merge without switching back to select tool.""" m_strand = self._strand_item._model_strand if modifiers & Qt.ShiftModifier: m_strand.merge(self.idx()) # end def def eraseToolMousePress(self, modifiers: Qt.KeyboardModifiers, event: QGraphicsSceneMouseEvent, idx: int): """Erase the strand.""" m_strand = self._strand_item._model_strand m_strand.strandSet().removeStrand(m_strand) # end def def insertionToolMousePress(self, modifiers: Qt.KeyboardModifiers, event: QGraphicsSceneMouseEvent, idx: int): """Add an insert to the strand if possible.""" m_strand = self._strand_item._model_strand m_strand.addInsertion(idx, 1) # end def def paintToolMousePress(self, modifiers: Qt.KeyboardModifiers, event: QGraphicsSceneMouseEvent, idx: int): """Add an insert to the strand if possible.""" m_strand = self._strand_item._model_strand if qApp.keyboardModifiers() & Qt.ShiftModifier: color = self.window().path_color_panel.shiftColorName() else: color = self.window().path_color_panel.colorName() m_strand.oligo().applyColor(color) # end def def addSeqToolMousePress(self, modifiers: Qt.KeyboardModifiers, event: QGraphicsSceneMouseEvent, idx: int): oligo = self._strand_item._model_strand.oligo() add_seq_tool = self._getActiveTool() add_seq_tool.applySequence(oligo) # end def def addSeqToolHoverMove(self, event: QGraphicsSceneHoverEvent, idx: int): # m_strand = self._model_strand # vhi = self._strand_item._virtual_helix_item add_seq_tool = self._getActiveTool() add_seq_tool.hoverMove(self, event, flag=self._isdrawn5to3) # end def def addSeqToolHoverLeave(self, event: QGraphicsSceneHoverEvent): self._getActiveTool().hoverLeaveEvent(event) # end def def createToolHoverMove(self, idx: int): """Create the strand is possible.""" m_strand = self._strand_item._model_strand vhi = self._strand_item._virtual_helix_item active_tool = self._getActiveTool() if not active_tool.isFloatingXoverBegin(): temp_xover = active_tool.floatingXover() temp_xover.updateFloatingFromStrandItem(vhi, m_strand, idx) # end def def createToolMousePress(self, modifiers: Qt.KeyboardModifiers, event: QGraphicsSceneMouseEvent, idx: int): """Break the strand is possible.""" m_strand = self._strand_item._model_strand vhi = self._strand_item._virtual_helix_item active_tool = self._getActiveTool() if active_tool.isFloatingXoverBegin(): if m_strand.idx5Prime() == idx: return else: temp_xover = active_tool.floatingXover() temp_xover.updateBase(vhi, m_strand, idx) active_tool.setFloatingXoverBegin(False) else: active_tool.setFloatingXoverBegin(True) # install Xover active_tool.attemptToCreateXover(vhi, m_strand, idx) # end def def selectToolMousePress(self, modifiers: Qt.KeyboardModifiers, event: QGraphicsSceneMouseEvent, idx: int): """Set the allowed drag bounds for use by selectToolMouseMove. """ # print("%s.%s [%d]" % (self, util.methodName(), self.idx())) self._low_drag_bound, self._high_drag_bound = self._strand_item._model_strand.getResizeBounds(self.idx()) 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()) and self.FILTER_NAME in current_filter_set): selection_group = viewroot.strandItemSelectionGroup() mod = Qt.MetaModifier if not (modifiers & mod): selection_group.clearSelection(False) selection_group.setSelectionLock(selection_group) selection_group.pendToAdd(self) selection_group.processPendingToAddList() return selection_group.mousePressEvent(event) # end def def selectToolMouseMove(self, modifiers: Qt.KeyboardModifiers, idx: int): """ Given a new index (pre-validated as different from the prev index), calculate the new x coordinate for self, move there, and notify the parent strandItem to redraw its horizontal line. """ # end def def selectToolMouseRelease(self, modifiers: Qt.KeyboardModifiers, x): """ If the positional-calculated idx differs from the model idx, it means we have moved and should notify the model to resize. If the mouse event had a key modifier, perform special actions: shift = attempt to merge with a neighbor alt = extend to max drag bound """ m_strand = self._strand_item._model_strand if modifiers & Qt.ShiftModifier: self.setSelected(False) self.restoreParent() m_strand.merge(self.idx()) # end def def skipToolMousePress(self, modifiers: Qt.KeyboardModifiers, event: QGraphicsSceneMouseEvent, idx: int): """Add an insert to the strand if possible.""" m_strand = self._strand_item._model_strand m_strand.addInsertion(idx, -1) # end def def restoreParent(self, pos: QPointF = None): """ Required to restore parenting and positioning in the partItem """ # map the position self.tempReparent(pos=pos) self.setSelectedColor(False) self.setSelected(False) # end def def tempReparent(self, pos: QPointF = None): vh_item = self._strand_item.virtualHelixItem() if pos is None: pos = self.scenePos() self.setParentItem(vh_item) temp_point = vh_item.mapFromScene(pos) self.setPos(temp_point) # end def def setSelectedColor(self, use_default: bool): if use_default == True: color = getColorObj(styles.SELECTED_COLOR) else: oligo = self._strand_item.strand().oligo() if oligo.shouldHighlight(): color = getColorObj(oligo.getColor(), alpha=128) else: color = getColorObj(oligo.getColor()) brush = self.brush() brush.setColor(color) self.setBrush(brush) # end def def updateHighlight(self, brush: QBrush): if not self.isSelected(): self.setBrush(brush) # end def 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) # end def def modelDeselect(self, document: DocT): """A strand is selected based on whether its low or high endpoints are selected. this value is a tuple ``(is_low, is_high)`` of booleans """ strand = self._strand_item.strand() test = document.isModelStrandSelected(strand) low_val, high_val = document.getSelectedStrandValue(strand) if test else (False, False) if self.cap_type == 'low': out_value = (False, high_val) else: out_value = (low_val, False) if not out_value[0] and not out_value[1] and test: document.removeStrandFromSelection(strand) elif out_value[0] or out_value[1]: document.addStrandToSelection(strand, out_value) self.restoreParent() # end def def modelSelect(self, document: DocT): """A strand is selected based on whether its low or high endpoints are selected. this value is a tuple ``(is_low, is_high)`` of booleans """ strand = self._strand_item.strand() test = document.isModelStrandSelected(strand) low_val, high_val = document.getSelectedStrandValue(strand) if test else (False, False) if self.cap_type == 'low': out_value = (True, high_val) else: out_value = (low_val, True) self.setSelected(True) self.setSelectedColor(True) document.addStrandToSelection(strand, out_value) # end def def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget: QWidget): painter.setPen(self.pen()) painter.setBrush(self.brush()) painter.drawPath(self.path())
def showMod(self, mod_id, color): self._mod_item = QGraphicsEllipseItem(MOD_RECT, self) self.changeMod(mod_id, color) self._mod_item.show()