class InteractiveItem(QGraphicsRectItem): def __init__(self, *arg, **karg): QGraphicsRectItem.__init__(self, *arg, **karg) self.node = None self.label = None self.setCursor(QtCore.Qt.PointingHandCursor) self.setAcceptsHoverEvents(True) def hoverEnterEvent(self, e): # There are many ways of adding interactive elements. With the # following code, I show/hide a text item over my custom # DynamicItemFace if not self.label: self.label = QGraphicsRectItem() self.label.setParentItem(self) # This is to ensure that the label is rendered over the # rest of item children (default ZValue for items is 0) self.label.setZValue(1) self.label.setBrush(QBrush(QColor("white"))) self.label.text = QGraphicsSimpleTextItem() self.label.text.setParentItem(self.label) self.label.text.setText(self.node.name) self.label.setRect(self.label.text.boundingRect()) self.label.setVisible(True) def hoverLeaveEvent(self, e): if self.label: self.label.setVisible(False)
class InteractiveLetterItem(QGraphicsRectItem): """This is a class""" def __init__(self, *arg, **karg): QGraphicsRectItem.__init__(self, *arg, **karg) self.codon = None self.label = None self.setAcceptsHoverEvents(True) def hoverEnterEvent (self, e): """ when mouse is over""" if not self.label: self.label = QGraphicsRectItem(parent=self) #self.label.setY(-18) self.label.setX(11) self.label.setBrush(QBrush(QColor("white"))) self.label.text = QGraphicsSimpleTextItem(parent=self.label) self.setZValue(1) self.label.text.setText(self.codon) self.label.setRect(self.label.text.boundingRect()) self.label.setVisible(True) def hoverLeaveEvent(self, e): """when mouse leaves area""" if self.label: self.label.setVisible(False) self.setZValue(0)
def showMoveHelper(self, visible=True): """show help text In empty HandBoards""" if visible: if not self.__moveHelper: splitter = QGraphicsRectItem(self) hbCenter = self.rect().center() splitter.setRect(hbCenter.x() * 0.5, hbCenter.y(), hbCenter.x() * 1, 1) helpItems = [splitter] for name, yFactor in [(m18n('Move Exposed Tiles Here'), 0.5), (m18n('Move Concealed Tiles Here'), 1.5)]: helper = QGraphicsSimpleTextItem(name, self) helper.setScale(3) nameRect = QRectF() nameRect.setSize(helper.mapToParent(helper.boundingRect()).boundingRect().size()) center = QPointF(hbCenter) center.setY(center.y() * yFactor) helper.setPos(center - nameRect.center()) if self.sceneRotation() == 180: rotateCenter(helper, 180) helpItems.append(helper) self.__moveHelper = self.scene().createItemGroup(helpItems) self.__moveHelper.setVisible(True) else: if self.__moveHelper: self.__moveHelper.setVisible(False)
class InteractiveLetterItem(QGraphicsRectItem): """This is a class""" def __init__(self, *arg, **karg): QGraphicsRectItem.__init__(self, *arg, **karg) self.codon = None self.label = None self.setAcceptsHoverEvents(True) def hoverEnterEvent(self, e): """ when mouse is over""" if not self.label: self.label = QGraphicsRectItem(parent=self) #self.label.setY(-18) self.label.setX(11) self.label.setBrush(QBrush(QColor("white"))) self.label.text = QGraphicsSimpleTextItem(parent=self.label) self.setZValue(1) self.label.text.setText(self.codon) self.label.setRect(self.label.text.boundingRect()) self.label.setVisible(True) def hoverLeaveEvent(self, e): """when mouse leaves area""" if self.label: self.label.setVisible(False) self.setZValue(0)
class InteractiveItem(QGraphicsRectItem): def __init__(self, *arg, **karg): QGraphicsRectItem.__init__(self, *arg, **karg) self.node = None self.label = None self.setCursor(QtCore.Qt.PointingHandCursor) self.setAcceptsHoverEvents(True) def hoverEnterEvent (self, e): # There are many ways of adding interactive elements. With the # following code, I show/hide a text item over my custom # DynamicItemFace if not self.label: self.label = QGraphicsRectItem() self.label.setParentItem(self) # This is to ensure that the label is rendered over the # rest of item children (default ZValue for items is 0) self.label.setZValue(1) self.label.setBrush(QBrush(QColor("white"))) self.label.text = QGraphicsSimpleTextItem() self.label.text.setParentItem(self.label) self.label.text.setText(self.node.name) self.label.setRect(self.label.text.boundingRect()) self.label.setVisible(True) def hoverLeaveEvent(self, e): if self.label: self.label.setVisible(False)
def computeRect(self): """translate from our rect coordinates to scene coord""" sizeX = self.tileset.faceSize.width() * self.__fixedWidth sizeY = self.tileset.faceSize.height() * self.__fixedHeight if self.showShadows: sizeX += self.tileset.shadowWidth() + 2 * self.tileset.shadowHeight() sizeY += self.tileset.shadowHeight() rect = self.rect() rect.setWidth(sizeX) rect.setHeight(sizeY) self.prepareGeometryChange() QGraphicsRectItem.setRect(self, rect)
class RectangleCurve(OWCurve): """ A plot item that shows a rectangle. This class accepts the same options as :obj:`.PolygonCurve`. The rectangle is calculated as the smallest rectangle that contains all points in ``xData`` and ``yData``. """ def __init__(self, pen = QPen(Qt.black), brush = QBrush(Qt.white), xData = None, yData = None, tooltip = None): OWCurve.__init__(self, xData, yData, tooltip=tooltip) self.set_pen(pen) self.set_brush(brush) self._item = QGraphicsRectItem(self) def update_properties(self): self._item.setRect(self.graph_transform().mapRect(self.data_rect())) self._item.setPen(self.pen()) self._item.setBrush(self.brush())
class GraphicsScene(QGraphicsScene): selectionRectPointChanged = Signal(QPointF) def __init__(self, *args): QGraphicsScene.__init__(self, *args) self.selectionRect = None def mousePressEvent(self, event): QGraphicsScene.mousePressEvent(self, event) def mouseMoveEvent(self, event): if event.buttons() & Qt.LeftButton: screenPos = event.screenPos() buttonDown = event.buttonDownScreenPos(Qt.LeftButton) if (screenPos - buttonDown).manhattanLength() > 2.0: self.updateSelectionRect(event) QGraphicsScene.mouseMoveEvent(self, event) def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton: if self.selectionRect: self.removeItem(self.selectionRect) self.selectionRect = None QGraphicsScene.mouseReleaseEvent(self, event) def updateSelectionRect(self, event): pos = event.scenePos() buttonDownPos = event.buttonDownScenePos(Qt.LeftButton) rect = QRectF(pos, buttonDownPos).normalized() rect = rect.intersected(self.sceneRect()) if not self.selectionRect: self.selectionRect = QGraphicsRectItem() self.selectionRect.setBrush(QColor(10, 10, 10, 20)) self.selectionRect.setPen(QPen(QColor(200, 200, 200, 200))) self.addItem(self.selectionRect) self.selectionRect.setRect(rect) if event.modifiers() & Qt.ControlModifier or \ event.modifiers() & Qt.ShiftModifier: path = self.selectionArea() else: path = QPainterPath() path.addRect(rect) self.setSelectionArea(path) self.selectionRectPointChanged.emit(pos)
class RectangleCurve(OWCurve): """ A plot item that shows a rectangle. This class accepts the same options as :obj:`.PolygonCurve`. The rectangle is calculated as the smallest rectangle that contains all points in ``xData`` and ``yData``. """ def __init__(self, pen=QPen(Qt.black), brush=QBrush(Qt.white), xData=None, yData=None, tooltip=None): OWCurve.__init__(self, xData, yData, tooltip=tooltip) self.set_pen(pen) self.set_brush(brush) self._item = QGraphicsRectItem(self) def update_properties(self): self._item.setRect(self.graph_transform().mapRect(self.data_rect())) self._item.setPen(self.pen()) self._item.setBrush(self.brush())
def setTiles(self): #background brush = QBrush() pix = QPixmap(os.getcwd() + "/robotImages/tile.png") brush.setTexture(pix) brush.setStyle(24) self.setBackgroundBrush(brush) #wall #left left = QGraphicsRectItem() pix = QPixmap(os.getcwd() + "/robotImages/tileVert.png") left.setRect(QtCore.QRectF(0, 0, pix.width(), self.height)) brush.setTexture(pix) brush.setStyle(24) left.setBrush(brush) left.name = 'left' self.addItem(left) #right right = QGraphicsRectItem() right.setRect(self.width - pix.width(), 0, pix.width(), self.height) right.setBrush(brush) right.name = 'right' self.addItem(right) #top top = QGraphicsRectItem() pix = QPixmap(os.getcwd() + "/robotImages/tileHori.png") top.setRect(QtCore.QRectF(0, 0, self.width, pix.height())) brush.setTexture(pix) brush.setStyle(24) top.setBrush(brush) top.name = 'top' self.addItem(top) #bottom bottom = QGraphicsRectItem() bottom.setRect(0, self.height - pix.height(), self.width, pix.height()) bottom.setBrush(brush) bottom.name = 'bottom' self.addItem(bottom)
class MJScene(QGraphicsScene): """our scene with a potential Qt bug fix""" def __init__(self): QGraphicsScene.__init__(self) self.__disableFocusRect = False self._focusBoard = None self.focusRect = QGraphicsRectItem() pen = QPen(QColor(Qt.blue)) pen.setWidth(6) self.focusRect.setPen(pen) self.addItem(self.focusRect) self.focusRect.setZValue(ZValues.marker) self.focusRect.hide() def focusInEvent(self, event): """work around a qt bug. See https://bugreports.qt-project.org/browse/QTBUG-32890 This can be reproduced as follows: ./kajongg.py --game=whatever --autoplay=SomeRuleset such that the human player is the first one to discard a tile. wait until the main screen has been built click with the mouse into the middle of that window press left arrow key this will violate the assertion in GraphicsTileItem.keyPressEvent """ prev = self.focusItem() QGraphicsScene.focusInEvent(self, event) if prev and bool(prev.flags() & QGraphicsItem.ItemIsFocusable) and prev != self.focusItem(): self.setFocusItem(prev) def __focusRectVisible(self): """should we show it?""" game = Internal.field.game board = self._focusBoard return bool(not self.__disableFocusRect and board and board.hasFocus and board.focusTile and game and not game.autoPlay) @property def disableFocusRect(self): """suppress focusrect""" return self.__disableFocusRect @disableFocusRect.setter def disableFocusRect(self, value): """always place or hide, even if value does not change""" self.__disableFocusRect = value if value: self.focusRect.hide() else: self.placeFocusRect() @property def focusBoard(self): """get / set the board that has its focusRect shown""" return self._focusBoard @focusBoard.setter def focusBoard(self, board): """get / set the board that has its focusRect shown""" self._focusBoard = board focusTile = board.focusTile if board else None if focusTile: focusTile.graphics.setFocus() self.placeFocusRect() self.focusRect.setVisible(self.__focusRectVisible()) def placeFocusRect(self): """show a blue rect around tile""" board = self._focusBoard if isAlive(board) and self.__focusRectVisible(): rect = board.tileFaceRect() rect.setWidth(rect.width()*board.focusRectWidth()) self.focusRect.setRect(rect) self.focusRect.setPos(board.focusTile.graphics.pos()) self.focusRect.setRotation(board.sceneRotation()) self.focusRect.setScale(board.scale()) self.focusRect.show() else: self.focusRect.hide() def graphicsTileItems(self): """returns all GraphicsTileItems in the scene""" return (x for x in self.items() if isinstance(x, GraphicsTileItem)) def nonTiles(self): """returns all other items in the scene""" return (x for x in self.items() if not isinstance(x, GraphicsTileItem)) def removeTiles(self): """remove all tiles from scene""" for item in self.graphicsTileItems(): self.removeItem(item) self.focusRect.hide()
class RectangleSelectionAction(UserInteraction): """ Select items in the scene using a Rectangle selection """ def __init__(self, document, *args, **kwargs): UserInteraction.__init__(self, document, *args, **kwargs) # The initial selection at drag start self.initial_selection = None # Selection when last updated in a mouseMoveEvent self.last_selection = None # A selection rect (`QRectF`) self.selection_rect = None # Keyboard modifiers self.modifiers = 0 def mousePressEvent(self, event): pos = event.scenePos() any_item = self.scene.item_at(pos) if not any_item and event.button() & Qt.LeftButton: self.modifiers = event.modifiers() self.selection_rect = QRectF(pos, QSizeF(0, 0)) self.rect_item = QGraphicsRectItem( self.selection_rect.normalized()) self.rect_item.setPen( QPen(QBrush(QColor(51, 153, 255, 192)), 0.4, Qt.SolidLine, Qt.RoundCap)) self.rect_item.setBrush(QBrush(QColor(168, 202, 236, 192))) self.rect_item.setZValue(-100) # Clear the focus if necessary. if not self.scene.stickyFocus(): self.scene.clearFocus() if not self.modifiers & Qt.ControlModifier: self.scene.clearSelection() event.accept() return True else: self.cancel(self.ErrorReason) return False def mouseMoveEvent(self, event): if not self.rect_item.scene(): # Add the rect item to the scene when the mouse moves. self.scene.addItem(self.rect_item) self.update_selection(event) return True def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton: if self.initial_selection is None: # A single click. self.scene.clearSelection() else: self.update_selection(event) self.end() return True def update_selection(self, event): """ Update the selection rectangle from a QGraphicsSceneMouseEvent `event` instance. """ if self.initial_selection is None: self.initial_selection = set(self.scene.selectedItems()) self.last_selection = self.initial_selection pos = event.scenePos() self.selection_rect = QRectF(self.selection_rect.topLeft(), pos) # Make sure the rect_item does not cause the scene rect to grow. rect = self._bound_selection_rect(self.selection_rect.normalized()) # Need that 0.5 constant otherwise the sceneRect will still # grow (anti-aliasing correction by QGraphicsScene?) pw = self.rect_item.pen().width() + 0.5 self.rect_item.setRect(rect.adjusted(pw, pw, -pw, -pw)) selected = self.scene.items(self.selection_rect.normalized(), Qt.IntersectsItemShape, Qt.AscendingOrder) selected = set([item for item in selected if \ item.flags() & Qt.ItemIsSelectable]) if self.modifiers & Qt.ControlModifier: for item in selected | self.last_selection | \ self.initial_selection: item.setSelected((item in selected) ^ (item in self.initial_selection)) else: for item in selected.union(self.last_selection): item.setSelected(item in selected) self.last_selection = set(self.scene.selectedItems()) def end(self): self.initial_selection = None self.last_selection = None self.modifiers = 0 self.rect_item.hide() if self.rect_item.scene() is not None: self.scene.removeItem(self.rect_item) UserInteraction.end(self) def viewport_rect(self): """ Return the bounding rect of the document's viewport on the scene. """ view = self.document.view() vsize = view.viewport().size() viewportrect = QRect(0, 0, vsize.width(), vsize.height()) return view.mapToScene(viewportrect).boundingRect() def _bound_selection_rect(self, rect): """ Bound the selection `rect` to a sensible size. """ srect = self.scene.sceneRect() vrect = self.viewport_rect() maxrect = srect.united(vrect) return rect.intersected(maxrect)
class MJScene(QGraphicsScene): """our scene with a potential Qt bug fix""" def __init__(self): QGraphicsScene.__init__(self) self.__disableFocusRect = False self._focusBoard = None self.focusRect = QGraphicsRectItem() pen = QPen(QColor(Qt.blue)) pen.setWidth(6) self.focusRect.setPen(pen) self.addItem(self.focusRect) self.focusRect.setZValue(ZValues.marker) self.focusRect.hide() def __focusRectVisible(self): """should we show it?""" game = InternalParameters.field.game board = self._focusBoard return bool(not self.__disableFocusRect and board and board.hasFocus and board.focusTile and game and not game.autoPlay) @apply def disableFocusRect(): # pylint: disable=E0202 """suppress focusrect""" def fget(self): # pylint: disable=W0212 return self.__disableFocusRect def fset(self, value): # pylint: disable=W0212 # always place or hide, even if value does not change self.__disableFocusRect = value if value: self.focusRect.hide() else: self.placeFocusRect() return property(**locals()) @apply def focusBoard(): # pylint: disable=E0202 """get / set the board that has its focusRect shown""" def fget(self): # pylint: disable=W0212 return self._focusBoard def fset(self, board): # pylint: disable=W0212 self._focusBoard = board focusTile = board.focusTile if board else None if focusTile: focusTile.graphics.setFocus() self.placeFocusRect() self.focusRect.setVisible(self.__focusRectVisible()) return property(**locals()) def placeFocusRect(self): """show a blue rect around tile""" board = self._focusBoard if isAlive(board) and self.__focusRectVisible(): rect = board.tileFaceRect() rect.setWidth(rect.width()*board.focusRectWidth()) self.focusRect.setRect(rect) self.focusRect.setPos(board.focusTile.graphics.pos()) self.focusRect.setRotation(board.sceneRotation()) self.focusRect.setScale(board.scale()) self.focusRect.show() else: self.focusRect.hide() def graphicsTileItems(self): """returns all GraphicsTileItems in the scene""" return (x for x in self.items() if isinstance(x, GraphicsTileItem)) def nonTiles(self): """returns all other items in the scene""" return (x for x in self.items() if not isinstance(x, GraphicsTileItem)) def removeTiles(self): """remove all tiles from scene""" for item in self.graphicsTileItems(): self.removeItem(item) self.focusRect.hide()
class OWLegendGradient(QGraphicsObject): gradient_width = 20 def __init__(self, palette, values, parent): QGraphicsObject.__init__(self, parent) self.parent = parent self.palette = palette self.values = values self.legend = parent self.label_items = [QGraphicsTextItem(text, self) for text in values] for i in self.label_items: i.setTextWidth(50) self.rect = QRectF() self.gradient_item = QGraphicsRectItem(self) self.gradient = QLinearGradient() self.gradient.setStops([(v * 0.1, self.palette[v * 0.1]) for v in range(11)]) self.orientation = Qt.Horizontal self.set_orientation(Qt.Vertical) def set_orientation(self, orientation): if self.orientation == orientation: return self.orientation = orientation if self.orientation == Qt.Vertical: height = max( [item.boundingRect().height() for item in self.label_items]) total_height = height * max(5, len(self.label_items)) interval = (total_height - self.label_items[-1].boundingRect().height()) / ( len(self.label_items) - 1) self.gradient_item.setRect(10, 0, self.gradient_width, total_height) self.gradient.setStart(10, 0) self.gradient.setFinalStop(10, total_height) self.gradient_item.setBrush(QBrush(self.gradient)) self.gradient_item.setPen(QPen(Qt.NoPen)) y = 0 x = 30 for item in self.label_items: move_item_xy(item, x, y, self.parent.graph.animate_plot) y += interval self.rect = QRectF( 10, 0, self.gradient_width + max([item.boundingRect().width() for item in self.label_items]), self.label_items[0].boundingRect().height() * max(5, len(self.label_items))) else: width = 50 height = max( [item.boundingRect().height() for item in self.label_items]) total_width = width * max(5, len(self.label_items)) interval = (total_width - self.label_items[-1].boundingRect().width()) / ( len(self.label_items) - 1) self.gradient_item.setRect(0, 0, total_width, self.gradient_width) self.gradient.setStart(0, 0) self.gradient.setFinalStop(total_width, 0) self.gradient_item.setBrush(QBrush(self.gradient)) self.gradient_item.setPen(QPen(Qt.NoPen)) x = 0 y = 30 for item in self.label_items: move_item_xy(item, x, y, self.parent.graph.animate_plot) x += interval self.rect = QRectF(0, 0, total_width, self.gradient_width + height) def boundingRect(self): return getattr(self, 'rect', QRectF()) def paint(self, painter, option, widget): pass
def __init__(self, world): QGraphicsPolygonItem.__init__(self) ############################# ### Build graph ############################# graph = pydot.Dot() graph.set_node_defaults(color = 'red', fontcolor = 'red', label = '\<orphan\>') graph.set('overlap', 'prism') # build adjacency graph from world for area in world.areas: # create node for each room node = pydot.Node(area.id) node.set( 'label', area.name ) if area == world.player.currentArea: node.set( 'color', 'blue' ) node.set( 'fontcolor', 'blue' ) else: node.set( 'color', 'black' ) node.set( 'fontcolor', 'black' ) graph.add_node(node) # link to adjacent rooms for feature in area.features: for action in feature.actions: finalEvent = None for event in action.events: if type(event) == events.PlayerMoveEvent: finalEvent = pydot.Edge( src=area.id, dst=event.properties['destination'] ) if finalEvent is not None: graph.add_edge( finalEvent ) ################################ ### Generate SVG from graph ################################ ps = graph.create_svg(prog='neato') ######################################### ### Build graphics items from SVG ######################################### # build xml tree ns = {'svg': 'http://www.w3.org/2000/svg'} doc = ET.fromstring(ps) # grab the root node properties rootNode = doc.xpath('/svg:svg/svg:g[1]', namespaces=ns)[0] polygon = rootNode.xpath('./svg:polygon', namespaces=ns)[0] pointStr = polygon.xpath('./@points', namespaces=ns)[0] penColor = QString(polygon.xpath('./@stroke', namespaces=ns)[0]) fillColor = QString(polygon.xpath('./@fill', namespaces=ns)[0]) # parse root polygon path path = QPolygonF() for pair in pointStr.split(' '): dims = pair.split(',') point = QPointF( float(dims[0]), float(dims[1]) ) path.append(point) self.setPolygon(path) # fill in root node colors if QColor.isValidColor(penColor): self.setPen( QColor(penColor) ) if QColor.isValidColor(fillColor): self.setBrush( QColor(fillColor) ) # build each graph node for xmlNode in rootNode.xpath('./svg:g', namespaces=ns): group = QGraphicsRectItem(self) group.setPen( Qt.transparent ) group.setBrush( Qt.transparent ) if xmlNode.attrib['class'] == 'node': # find the area object name = xmlNode.xpath('./svg:title', namespaces=ns)[0].text group.setData( 0, QString(world.areas[world.areaLookup[name]].id) ) # get the ellipse info ellipseNode = xmlNode.xpath('./svg:ellipse', namespaces=ns)[0] elProps = { k: float(ellipseNode.attrib[k]) for k in ['cx', 'cy', 'rx', 'ry']} rect = QRectF( elProps['cx']-elProps['rx'], elProps['cy']-elProps['ry'], 2*elProps['rx'], 2*elProps['ry']) penColor = QString(ellipseNode.attrib['stroke']) ellipseItem = QGraphicsEllipseItem(rect, group) if QColor.isValidColor(penColor): ellipseItem.setPen( QColor(penColor) ) # get the text info textNode = xmlNode.xpath('./svg:text', namespaces=ns)[0] text = textNode.text textItem = QGraphicsTextItem(text, group) penColor = textNode.attrib.get('fill', 'black') nodePoint = QPointF(float(textNode.attrib['x']), float(textNode.attrib['y'])) textItem.setPos( nodePoint - textItem.boundingRect().center() + QPointF(0.0,-4.0)) if QColor.isValidColor(penColor): textItem.setDefaultTextColor( QColor(penColor) ) group.setRect( ellipseItem.boundingRect() ) group.setFlags( QGraphicsRectItem.ItemIsSelectable ) elif xmlNode.attrib['class'] == 'edge': # parse the line portion of the arrow line = xmlNode.xpath('./svg:path', namespaces=ns)[0] path = QPainterPath() # pull info from xml file linePath = line.attrib['d'] lineColor = line.attrib['stroke'] # parse path coords points = re.findall( '(-?\d+\.\d+),(-?\d+\.\d+)', linePath ) if len(points) != 4: continue startPoint = QPointF( float(points[0][0]), float(points[0][1]) ) path.moveTo(startPoint) curvePoints = [] for pointCoord in points[1:]: curvePoints.append( QPointF(float(pointCoord[0]), float(pointCoord[1])) ) path.cubicTo( curvePoints[0], curvePoints[1], curvePoints[2] ) # construct path item pathItem = QGraphicsPathItem(path, group) if QColor.isValidColor(lineColor): pathItem.setPen( QColor(lineColor) ) polyNode = xmlNode.xpath('./svg:polygon', namespaces=ns)[0] # pull info from xml file pointStr = polyNode.xpath('./@points', namespaces=ns)[0] penColor = QString(polyNode.xpath('./@stroke', namespaces=ns)[0]) fillColor = QString(polyNode.xpath('./@fill', namespaces=ns)[0]) # parse polygon path path = QPolygonF() for pair in pointStr.split(' '): dims = pair.split(',') point = QPointF( float(dims[0]), float(dims[1]) ) path.append(point) # construct polygon item polygonItem = QGraphicsPolygonItem(path, group) if QColor.isValidColor(penColor): polygonItem.setPen( QColor(penColor) ) if QColor.isValidColor(fillColor): polygonItem.setBrush( QColor(fillColor) ) group.setRect( pathItem.boundingRect() and polygonItem.boundingRect() )
class PatternLegendText(QGraphicsTextItem): Type = 70000 + 3 def __init__(self, text, parent = None): super(PatternLegendText, self).__init__(text, parent) # NOTE: need this distinction for cache mode based on # the Qt version otherwise rendering is broken if NO_ITEM_CACHING: self.setCacheMode(QGraphicsItem.NoCache) else: self.setCacheMode(QGraphicsItem.DeviceCoordinateCache) self.setZValue(1) self.setFlag(QGraphicsItem.ItemIsMovable) self.setTextInteractionFlags(Qt.TextEditorInteraction) self._position = self.pos() self._outline = None def hoverEnterEvent(self, event): """ Stuff related to hover enter events. For now we just show a rectangular outline. """ if not self._outline: self._outline = QGraphicsRectItem(self.boundingRect(), self) highlightColor = QColor(Qt.blue) highlightColor.setAlpha(30) self._outline.setBrush(highlightColor) highlightPen = QPen(Qt.blue) highlightPen.setWidth(2) self._outline.setPen(highlightPen) else: self._outline.show() def hoverLeaveEvent(self, event): """ Stuff related to hover leave events. For now we just show a rectangular outline. """ self._outline.hide() def keyPressEvent(self, event): """ Stuff to do during key press events. For now we have to adjust the outline box. """ QGraphicsTextItem.keyPressEvent(self, event) self.adjust_size() def adjust_size(self): """ This function takes care of changing the size of the outline rectangle, e.g., when text is added or removed or during font size changes. """ if self._outline: self._outline.setRect(self.boundingRect()) def mousePressEvent(self, event): """ We reimplement this function to store the position of the item when a user issues a mouse press. """ self._position = self.pos() if (event.modifiers() & Qt.ControlModifier): QApplication.setOverrideCursor(QCursor(Qt.SizeAllCursor)) self.setTextInteractionFlags(Qt.NoTextInteraction) return QGraphicsTextItem.mousePressEvent(self, event) def mouseReleaseEvent(self, event): """ We reimplement this function to check if its position has changed since the last mouse click. If yes we let the canvas know so it can store the action as a Redo/Undo event. """ self.setTextInteractionFlags(Qt.TextEditorInteraction) QApplication.restoreOverrideCursor() # this is needed for undo/redo if self._position != self.pos(): self.scene().canvas_item_position_changed(self, self._position, self.pos()) return QGraphicsTextItem.mouseReleaseEvent(self, event)
class GraphicsView(QGraphicsView): rubber_band = None selection = None def __init__(self, scene, parent=None): super(GraphicsView, self).__init__(parent) self.setScene(scene) self.setRenderHint(QPainter.Antialiasing) self.setRenderHint(QPainter.TextAntialiasing) def wheelEvent(self, event): factor = 1.41 ** (-event.delta() / 240.0) self.scale(factor, factor) def __mousePressEvent(self,event): self.drag_start = event.pos() def __mouseReleaseEvent(self,event): global PIX self.drag_stop = event.pos() im = PIX.pixmap().toImage() start, stop = self.mapToScene(self.drag_start),self.mapToScene(self.drag_stop) logging.debug((start,stop)) augmented = QGraphicsPixmapItem(QPixmap(tempfile)) augmented.setOffset(rect.topLeft()) augmented.setMatrix(QMatrix()) if None != self.selectbox: self.scene().removeItem(self.selectbox) self.selectbox = augmented self.scene().addItem(self.selectbox) def mousePressEvent(self, event): self.start = event.pos() if not self.rubber_band: self.rubber_band = QGraphicsRectItem(None, self.scene()) self.rubber_band.setRect(self.mapToScene(QRect(self.start,QSize())).boundingRect()) self.scene().addItem(self.rubber_band) logging.info(self.__class__.__name__+' press') def mouseMoveEvent(self, event): if self.rubber_band: self.rubber_band.setRect(self.mapToScene(QRect(self.start,event.pos()).normalized()).boundingRect()) logging.info(self.__class__.__name__+' move') def mouseReleaseEvent(self, event): if self.rubber_band: self.doIt(self.rubber_band.rect()) self.scene().removeItem(self.rubber_band) self.rubber_band = None logging.info(self.__class__.__name__+' release') def doIt(self, rect): global PIX pix_rect = PIX.mapToItem(PIX,rect).toPolygon().boundingRect() logging.debug(pix_rect) im = PIX.pixmap().toImage() im = im.copy(pix_rect) tempfile = os.path.join(os.getenv('TMP'),str(uuid.uuid4())+'.jpg') im.save(tempfile, 'JPEG') try: coords = pil.process(tempfile) rect = QRect(QPoint(*coords[0]),QPoint(*coords[1])).normalized() logging.debug(rect) zone = QGraphicsEllipseItem(QRectF(rect)) zone = self.rubber_band.mapFromItem() self.mapFrom() self.scene().addItem(zone) except Exception, err: logging.error(err) finally:
class OWLegendGradient(QGraphicsObject): gradient_width = 20 def __init__(self, palette, values, parent): QGraphicsObject.__init__(self, parent) self.parent = parent self.palette = palette self.values = values self.legend = parent self.label_items = [QGraphicsTextItem(text, self) for text in values] for i in self.label_items: i.setTextWidth(50) self.rect = QRectF() self.gradient_item = QGraphicsRectItem(self) self.gradient = QLinearGradient() self.gradient.setStops([(v*0.1, self.palette[v*0.1]) for v in range(11) ]) self.orientation = Qt.Horizontal self.set_orientation(Qt.Vertical) def set_orientation(self, orientation): if self.orientation == orientation: return self.orientation = orientation if self.orientation == Qt.Vertical: height = max([item.boundingRect().height() for item in self.label_items]) total_height = height * max(5, len(self.label_items)) interval = (total_height - self.label_items[-1].boundingRect().height()) / (len(self.label_items) -1) self.gradient_item.setRect(10, 0, self.gradient_width, total_height) self.gradient.setStart(10, 0) self.gradient.setFinalStop(10, total_height) self.gradient_item.setBrush(QBrush(self.gradient)) self.gradient_item.setPen(QPen(Qt.NoPen)) y = 0 x = 30 for item in self.label_items: move_item_xy(item, x, y, self.parent.graph.animate_plot) y += interval self.rect = QRectF(10, 0, self.gradient_width + max([item.boundingRect().width() for item in self.label_items]), self.label_items[0].boundingRect().height() * max(5, len(self.label_items))) else: width = 50 height = max([item.boundingRect().height() for item in self.label_items]) total_width = width * max(5, len(self.label_items)) interval = (total_width - self.label_items[-1].boundingRect().width()) / (len(self.label_items) -1) self.gradient_item.setRect(0, 0, total_width, self.gradient_width) self.gradient.setStart(0, 0) self.gradient.setFinalStop(total_width, 0) self.gradient_item.setBrush(QBrush(self.gradient)) self.gradient_item.setPen(QPen(Qt.NoPen)) x = 0 y = 30 for item in self.label_items: move_item_xy(item, x, y, self.parent.graph.animate_plot) x += interval self.rect = QRectF(0, 0, total_width, self.gradient_width + height) def boundingRect(self): return getattr(self, 'rect', QRectF()) def paint(self, painter, option, widget): pass
class GradientLegendItem(QGraphicsObject, GraphicsWidgetAnchor): gradient_width = 20 def __init__(self, title, palette, values, parent): QGraphicsObject.__init__(self, parent) GraphicsWidgetAnchor.__init__(self) self.parent = self.legend = parent self.palette = palette self.values = values self.title = QGraphicsTextItem('%s:' % title, self) f = self.title.font() f.setBold(True) self.title.setFont(f) self.title_item = QGraphicsRectItem(self.title.boundingRect(), self) self.title_item.setPen(QPen(Qt.NoPen)) self.title_item.stackBefore(self.title) self.label_items = [QGraphicsTextItem(text, self) for text in values] for i in self.label_items: i.setTextWidth(50) self.rect = QRectF() self.gradient_item = QGraphicsRectItem(self) self.gradient = QLinearGradient() self.gradient.setStops([(v * 0.1, self.palette[v * 0.1]) for v in range(11)]) self.orientation = Qt.Horizontal self.set_orientation(Qt.Vertical) self.setFlag(QGraphicsItem.ItemIgnoresTransformations, True) self.setFlag(QGraphicsItem.ItemIsMovable, True) def set_orientation(self, orientation): return if self.orientation == orientation: return self.orientation = orientation if self.orientation == Qt.Vertical: height = max(item.boundingRect().height() for item in self.label_items) total_height = height * max(5, len(self.label_items)) interval = (total_height - self.label_items[-1].boundingRect().height() ) / (len(self.label_items) - 1) self.gradient_item.setRect(10, 0, self.gradient_width, total_height) self.gradient.setStart(10, 0) self.gradient.setFinalStop(10, total_height) self.gradient_item.setBrush(QBrush(self.gradient)) self.gradient_item.setPen(QPen(Qt.NoPen)) y = -20 # hja, no; dela --> pri boundingRect() zato pristejem +20 x = 0 move_item_xy(self.title, x, y, False) y = 10 x = 30 for item in self.label_items: move_item_xy(item, x, y, False) # self.parent.graph.animate_plot) y += interval self.rect = QRectF(10, 0, self.gradient_width + max(item.boundingRect().width() for item in self.label_items), self.label_items[0].boundingRect().height() * max(5, len(self.label_items))) else: # za horizontalno orientacijo nisem dodajal title-a width = 50 height = max(item.boundingRect().height() for item in self.label_items) total_width = width * max(5, len(self.label_items)) interval = (total_width - self.label_items[-1].boundingRect().width() ) / (len(self.label_items) - 1) self.gradient_item.setRect(0, 0, total_width, self.gradient_width) self.gradient.setStart(0, 0) self.gradient.setFinalStop(total_width, 0) self.gradient_item.setBrush(QBrush(self.gradient)) self.gradient_item.setPen(QPen(Qt.NoPen)) x = 0 y = 30 for item in self.label_items: move_item_xy(item, x, y, False) # self.parent.graph.animate_plot) x += interval self.rect = QRectF(0, 0, total_width, self.gradient_width + height) # noinspection PyPep8Naming def boundingRect(self): width = max(self.rect.width(), self.title_item.boundingRect().width()) height = self.rect.height() + self.title_item.boundingRect().height() return QRectF(self.rect.left(), self.rect.top(), width, height) def paint(self, painter, option, widget): pass
class RectangleSelectionAction(UserInteraction): """ Select items in the scene using a Rectangle selection """ def __init__(self, document, *args, **kwargs): UserInteraction.__init__(self, document, *args, **kwargs) # The initial selection at drag start self.initial_selection = None # Selection when last updated in a mouseMoveEvent self.last_selection = None # A selection rect (`QRectF`) self.selection_rect = None # Keyboard modifiers self.modifiers = 0 def mousePressEvent(self, event): pos = event.scenePos() any_item = self.scene.item_at(pos) if not any_item and event.button() & Qt.LeftButton: self.modifiers = event.modifiers() self.selection_rect = QRectF(pos, QSizeF(0, 0)) self.rect_item = QGraphicsRectItem( self.selection_rect.normalized() ) self.rect_item.setPen( QPen(QBrush(QColor(51, 153, 255, 192)), 0.4, Qt.SolidLine, Qt.RoundCap) ) self.rect_item.setBrush( QBrush(QColor(168, 202, 236, 192)) ) self.rect_item.setZValue(-100) # Clear the focus if necessary. if not self.scene.stickyFocus(): self.scene.clearFocus() if not self.modifiers & Qt.ControlModifier: self.scene.clearSelection() event.accept() return True else: self.cancel(self.ErrorReason) return False def mouseMoveEvent(self, event): if not self.rect_item.scene(): # Add the rect item to the scene when the mouse moves. self.scene.addItem(self.rect_item) self.update_selection(event) return True def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton: if self.initial_selection is None: # A single click. self.scene.clearSelection() else: self.update_selection(event) self.end() return True def update_selection(self, event): """ Update the selection rectangle from a QGraphicsSceneMouseEvent `event` instance. """ if self.initial_selection is None: self.initial_selection = set(self.scene.selectedItems()) self.last_selection = self.initial_selection pos = event.scenePos() self.selection_rect = QRectF(self.selection_rect.topLeft(), pos) # Make sure the rect_item does not cause the scene rect to grow. rect = self._bound_selection_rect(self.selection_rect.normalized()) # Need that 0.5 constant otherwise the sceneRect will still # grow (anti-aliasing correction by QGraphicsScene?) pw = self.rect_item.pen().width() + 0.5 self.rect_item.setRect(rect.adjusted(pw, pw, -pw, -pw)) selected = self.scene.items(self.selection_rect.normalized(), Qt.IntersectsItemShape, Qt.AscendingOrder) selected = set([item for item in selected if \ item.flags() & Qt.ItemIsSelectable]) if self.modifiers & Qt.ControlModifier: for item in selected | self.last_selection | \ self.initial_selection: item.setSelected( (item in selected) ^ (item in self.initial_selection) ) else: for item in selected.union(self.last_selection): item.setSelected(item in selected) self.last_selection = set(self.scene.selectedItems()) def end(self): self.initial_selection = None self.last_selection = None self.modifiers = 0 self.rect_item.hide() if self.rect_item.scene() is not None: self.scene.removeItem(self.rect_item) UserInteraction.end(self) def viewport_rect(self): """ Return the bounding rect of the document's viewport on the scene. """ view = self.document.view() vsize = view.viewport().size() viewportrect = QRect(0, 0, vsize.width(), vsize.height()) return view.mapToScene(viewportrect).boundingRect() def _bound_selection_rect(self, rect): """ Bound the selection `rect` to a sensible size. """ srect = self.scene.sceneRect() vrect = self.viewport_rect() maxrect = srect.united(vrect) return rect.intersected(maxrect)
class PatternLegendText(QGraphicsTextItem): Type = 70000 + 3 def __init__(self, text, itemID=0, parent=None): super(PatternLegendText, self).__init__(text, parent) # NOTE: need this distinction for cache mode based on # the Qt version otherwise rendering is broken if NO_ITEM_CACHING: self.setCacheMode(QGraphicsItem.NoCache) else: self.setCacheMode(QGraphicsItem.DeviceCoordinateCache) self.itemID = itemID self.setZValue(1) self.setFlag(QGraphicsItem.ItemIsMovable) self.setTextInteractionFlags(Qt.TextEditorInteraction) self._position = self.pos() self._outline = None def hoverEnterEvent(self, event): """ Stuff related to hover enter events. For now we just show a rectangular outline. """ if not self._outline: self._outline = QGraphicsRectItem(self.boundingRect(), self) highlightColor = QColor(Qt.blue) highlightColor.setAlpha(30) self._outline.setBrush(highlightColor) highlightPen = QPen(Qt.blue) highlightPen.setWidth(2) self._outline.setPen(highlightPen) else: self._outline.show() def hoverLeaveEvent(self, event): """ Stuff related to hover leave events. For now we just show a rectangular outline. """ self._outline.hide() def keyPressEvent(self, event): """ Stuff to do during key press events. For now we have to adjust the outline box. """ QGraphicsTextItem.keyPressEvent(self, event) self.adjust_size() def adjust_size(self): """ This function takes care of changing the size of the outline rectangle, e.g., when text is added or removed or during font size changes. """ if self._outline: self._outline.setRect(self.boundingRect()) def mousePressEvent(self, event): """ We reimplement this function to store the position of the item when a user issues a mouse press. """ self._position = self.pos() if (event.modifiers() & Qt.ControlModifier): QApplication.setOverrideCursor(QCursor(Qt.SizeAllCursor)) self.setTextInteractionFlags(Qt.NoTextInteraction) return QGraphicsTextItem.mousePressEvent(self, event) def mouseReleaseEvent(self, event): """ We reimplement this function to check if its position has changed since the last mouse click. If yes we let the canvas know so it can store the action as a Redo/Undo event. """ self.setTextInteractionFlags(Qt.TextEditorInteraction) QApplication.restoreOverrideCursor() # this is needed for undo/redo if self._position != self.pos(): self.scene().canvas_item_position_changed(self, self._position, self.pos()) return QGraphicsTextItem.mouseReleaseEvent(self, event)