def paintEvent(self, event): painter = QPainter(self) if self.pixmap: size = self.pixmap.size() aspect = float(size.width()) / size.height() if aspect > 1: # Image is wider than it is tall - centre vertically left = 0 width = self.width() height = self.height() / aspect top = (self.height() - height) / 2 else: # Image is taller than it is wide - centre horizontally top = 0 height = self.height() width = self.width() * aspect left = (self.width() - width) / 2 painter.drawPixmap(QRect(left, top, width, height), self.pixmap) if self.focus: # self.focus contains coords between 0 and 1 - translate these # to pixels pixels = QRectF(left + self.focus.left() * width, top + self.focus.top() * height, self.focus.width() * width, self.focus.height() * height) # Outer box in white painter.setPen(QPen(Qt.white, 1, Qt.SolidLine)) painter.drawRect(pixels) # Inner box in black painter.setPen(QPen(Qt.black, 1, Qt.SolidLine)) painter.drawRect(pixels.adjusted(1, 1, -1, -1))
class SelectionRectangle(QGraphicsItem): def __init__(self, parent = None): super().__init__(parent) self.setZValue(10000) self.mRectangle = QRectF() def setRectangle(self, rectangle): self.prepareGeometryChange() self.mRectangle = rectangle def boundingRect(self): return self.mRectangle.adjusted(-1, -1, 2, 2) def paint(self, painter, option, widget = None): if (self.mRectangle.isNull()): return # Draw a shadow black = QColor(Qt.black) black.setAlpha(128) pen = QPen(black, 2, Qt.DotLine) pen.setCosmetic(True) painter.setPen(pen) painter.drawRect(self.mRectangle.translated(1, 1)) # Draw a rectangle in the highlight color highlight = QApplication.palette().highlight().color() pen.setColor(highlight) highlight.setAlpha(32) painter.setPen(pen) painter.setBrush(highlight) painter.drawRect(self.mRectangle)
def _draw_textdoc(self, rect): """Draw the QTextDocument of an item. Args: rect: The QRect to clip the drawing to. """ # We can't use drawContents because then the color would be ignored. # See: https://qt-project.org/forums/viewthread/21492 clip = QRectF(0, 0, rect.width(), rect.height()) self._painter.save() if self._opt.state & QStyle.State_Selected: option = 'completion.item.selected.fg' elif not self._opt.state & QStyle.State_Enabled: option = 'completion.category.fg' else: option = 'completion.fg' try: self._painter.setPen(config.get('colors', option)) except configexc.NoOptionError: self._painter.setPen(config.get('colors', 'completion.fg')) ctx = QAbstractTextDocumentLayout.PaintContext() ctx.palette.setColor(QPalette.Text, self._painter.pen().color()) if clip.isValid(): self._painter.setClipRect(clip) ctx.clip = clip self._doc.documentLayout().draw(self._painter, ctx) self._painter.restore()
def drawRow(row, sx, sy, last_end=False): x = sx y = sy keys = row rw = w - sx i = 0 for k in keys: rect = QRectF(x, y, kw, kw) if i == len(keys) - 1 and last_end: rect.setWidth(rw) p.drawRoundedRect(rect, rx, rx) p.setPen(Qt.black) rect.adjust(5, 1, 0, 0) p.setFont(self.lowerFont) p.drawText( rect, Qt.AlignLeft | Qt.AlignBottom, self.regular_text(k)) p.setFont(self.upperFont) p.drawText( rect, Qt.AlignLeft | Qt.AlignTop, self.shift_text(k)) rw = rw - space - kw x = x + space + kw i = i + 1 p.setPen(pen) return (x, rw)
def validateRect(self, r: QRectF, resizeDirections): left = r.left() top = r.top() right = left + r.width() bottom = top + r.height() # The qBound() is used for enforcement of the minimum and maximum sizes. # It's derived after solving the following inequalities (example is for # left-resizing): # minWidth <= newWidth <= maxWidth # minWidth <= right-newLeft <= maxWidth # minWidth-right <= -newLeft <= maxWidth-right # right-minWidth >= newLeft >= right-maxWidth # Ditto for the other 3 directions. def qBound(minVal, current, maxVal): return max(min(current, maxVal), minVal) if resizeDirections.horizontal == ResizeDirectionHorizontal.Left: left = qBound(right - self.maximumSize.width(), left, right - self.minimumSize.width()) elif resizeDirections.horizontal == ResizeDirectionHorizontal.Right: right = qBound(self.minimumSize.width() + left, right, self.maximumSize.width() + left) if resizeDirections.vertical == ResizeDirectionVertical.Top: top = qBound(bottom - self.maximumSize.height(), top, bottom - self.minimumSize.height()) elif resizeDirections.vertical == ResizeDirectionVertical.Bottom: bottom = qBound(self.minimumSize.height() + top, bottom, self.maximumSize.height() + top) return QRectF(left, top, right - left, bottom - top)
def _draw_textdoc(self, rect, col): """Draw the QTextDocument of an item. Args: rect: The QRect to clip the drawing to. """ # We can't use drawContents because then the color would be ignored. clip = QRectF(0, 0, rect.width(), rect.height()) self._painter.save() if self._opt.state & QStyle.State_Selected: color = config.val.colors.completion.item.selected.fg elif not self._opt.state & QStyle.State_Enabled: color = config.val.colors.completion.category.fg else: colors = config.val.colors.completion.fg # if multiple colors are set, use different colors per column color = colors[col % len(colors)] self._painter.setPen(color) ctx = QAbstractTextDocumentLayout.PaintContext() ctx.palette.setColor(QPalette.Text, self._painter.pen().color()) if clip.isValid(): self._painter.setClipRect(clip) ctx.clip = clip self._doc.documentLayout().draw(self._painter, ctx) self._painter.restore()
def _fetch_tile_layer(self, timestamp, ims, transform, tile_nr, stack_id, ims_req, cache): """ Fetch a single tile from a layer (ImageSource). Parameters ---------- timestamp The timestamp at which ims_req was created ims The layer (image source) we're fetching from transform The transform to apply to the fetched data, before storing it in the cache tile_nr The ID of the fetched tile stack_id The stack ID of the tile we're fetching (e.g. which T-slice and Z-slice this tile belongs to) ims_req A request object (e.g. GrayscaleImageRequest) with a wait() method that produces an item of the appropriate type for the layer (i.e. either a QImage or a QGraphicsItem) cache The value of self._cache at the time the ims_req was created. (The cache can be replaced occasionally. See TileProvider._onSizeChanged().) """ try: try: with cache: layerTimestamp = cache.layerTimestamp(stack_id, ims, tile_nr) except KeyError: # May not be a timestamp yet (especially when prefetching) layerTimestamp = 0 tile_rect = QRectF(self.tiling.imageRects[tile_nr]) if timestamp > layerTimestamp: img = ims_req.wait() if isinstance(img, QImage): img = img.transformed(transform) elif isinstance(img, QGraphicsItem): # FIXME: It *seems* like applying the same transform to QImages and QGraphicsItems # makes sense here, but for some strange reason it isn't right. # For QGraphicsItems, it seems obvious that this is the correct transform. # I do not understand the formula that produces 'transform', which is used for QImage tiles. img.setTransform(QTransform.fromTranslate(tile_rect.left(), tile_rect.top()), combine=True) img.setTransform(self.tiling.data2scene, combine=True) else: assert False, "Unexpected image type: {}".format(type(img)) with cache: try: cache.updateTileIfNecessary(stack_id, ims, tile_nr, timestamp, img) except KeyError: pass if stack_id == self._current_stack_id and cache is self._cache: self.sceneRectChanged.emit(tile_rect) except BaseException: sys.excepthook(*sys.exc_info())
def updateSceneRect(self): #Is called when there is a change in the scene #Update scene size to fit the current layout of the graph if not self.lockScene: rect = self.itemsBoundingRect() rect = QRectF(rect.x() - 50, rect.y() - 50, rect.width() + 100, rect.height() + 100) self.setSceneRect(rect) else: self.lockScene = False
def rect(self, rect: QRectF, shaded: int=0) -> None: if shaded: diff = 6 if isinstance(shaded,bool) and shaded == True else shaded self._painter.setPen(self._fgs) rect.translate(diff, diff) self._painter.drawRect(rect) rect.translate(-diff, -diff) self._painter.setPen(self._bg) self._painter.drawRect(rect)
def setNetBoxDimensions(self, rect: QRectF): """ Set net box dimensions The net box is the rectangle that compose the network drawn to show the occupy matrix """ self.netRectHeight = rect.height() / self.netRows self.netRectWidth = rect.width() / self.netCols self.left = rect.left() self.top = rect.top()
def text(self, text: str, pos: QRectF, color: QColor=None, size: int=20, shaded: int=0, bold: bool=False,shrinkToFit=10) -> None: if not isinstance(text,str): text = "{}".format(text) self._font.setPointSize(size) if bold: self._font.setWeight(QFont.Black) else: self._font.setWeight(QFont.Bold) self._painter.setFont(self._font) fm = QFontMetrics(self._font) if pos.width() == 0: pos.setWidth(fm.width(text)) if pos.height() == 0: pos.setHeight(fm.height()) if size > shrinkToFit: # if fm.width(text) > pos.width() or fm.height() > pos.height()+2: self.text(text,pos,color,size-1,shaded,bold,shrinkToFit) return if shaded: diff = size//4 if isinstance(shaded,bool) and shaded == True else shaded self._painter.setPen(self._fgs) pos2 = pos.translated(diff, diff) self._painter.drawText(pos2, Qt.AlignCenter, text) p = QPen(color if color is not None else self._fg) self._painter.setPen(p) self._painter.drawText(pos, Qt.AlignCenter, text)
def repaintRegion(self, region, layer): renderer = self.mMapDocument.renderer() margins = self.mMapDocument.map().drawMargins() for r in region.rects(): boundingRect = QRectF(renderer.boundingRect(r)) self.update(QRectF(renderer.boundingRect(r).adjusted(-margins.left(), -margins.top(), margins.right(), margins.bottom()))) boundingRect.translate(layer.offset()) self.update(boundingRect)
def updateSceneRect(self): mapSize = self.mMapDocument.renderer().mapSize() sceneRect = QRectF(0, 0, mapSize.width(), mapSize.height()) margins = self.mMapDocument.map().computeLayerOffsetMargins() sceneRect.adjust(-margins.left(), -margins.top(), margins.right(), margins.bottom()) self.setSceneRect(sceneRect) self.mDarkRectangle.setRect(sceneRect)
def scroll_to_index(view_cls, idx, select=True): old_value = view_cls.verticalScrollBar().value() view_cls.setUpdatesEnabled(False) view_cls.verticalScrollBar().setValue(0) idx_rect = view_cls.visualRect(idx) view_cls.verticalScrollBar().setValue(old_value) view_cls.setUpdatesEnabled(True) rect = QRectF(idx_rect) if app_constants.DEBUG: print("Scrolling to index:", rect.getRect()) view_cls.k_scroller.ensureVisible(rect, 0, 0) if select: view_cls.setCurrentIndex(idx)
def __init__(self, mapObject, renderer, parent = None): super().__init__(parent) self.mMapObject = mapObject self.mRenderer = renderer position = mapObject.position() pixelPos = renderer.pixelToScreenCoords_(position) boundingRect = QRectF(renderer.boundingRect(mapObject)) boundingRect.translate(-pixelPos) self.mBoundingRect = boundingRect self.setPos(pixelPos) self.setRotation(mapObject.rotation())
class MapObjectLabel(QGraphicsItem): def __init__(self, object, parent = None): super().__init__(parent) self.mBoundingRect = QRectF() self.mObject = object self.setFlags(QGraphicsItem.ItemIgnoresTransformations | QGraphicsItem.ItemIgnoresParentOpacity) def syncWithMapObject(self, renderer): nameVisible = self.mObject.isVisible() and self.mObject.name()!='' self.setVisible(nameVisible) if (not nameVisible): return metrics = QFontMetricsF(QGuiApplication.font()) boundingRect = metrics.boundingRect(self.mObject.name()) boundingRect.translate(-boundingRect.width() / 2, -labelDistance) boundingRect.adjust(-labelMargin*2, -labelMargin, labelMargin*2, labelMargin) pixelPos = renderer.pixelToScreenCoords_(self.mObject.position()) bounds = objectBounds(self.mObject, renderer) # Adjust the bounding box for object rotation transform = QTransform() transform.translate(pixelPos.x(), pixelPos.y()) transform.rotate(self.mObject.rotation()) transform.translate(-pixelPos.x(), -pixelPos.y()) bounds = transform.mapRect(bounds) # Center the object name on the object bounding box pos = QPointF((bounds.left() + bounds.right()) / 2, bounds.top()) self.setPos(pos + self.mObject.objectGroup().offset()) if (self.mBoundingRect != boundingRect): self.prepareGeometryChange() self.mBoundingRect = boundingRect def boundingRect(self): return self.mBoundingRect.adjusted(0, 0, 1, 1) def paint(self, painter, arg2, arg3): color = MapObjectItem.objectColor(self.mObject) painter.setRenderHint(QPainter.Antialiasing) painter.setBrush(Qt.black) painter.setPen(Qt.NoPen) painter.drawRoundedRect(self.mBoundingRect.translated(1, 1), 4, 4) painter.setBrush(color) painter.drawRoundedRect(self.mBoundingRect, 4, 4) textPos = QPointF(-(self.mBoundingRect.width() - labelMargin*4) / 2, -labelDistance) painter.drawRoundedRect(self.mBoundingRect, 4, 4) painter.setPen(Qt.black) painter.drawText(textPos + QPointF(1,1), self.mObject.name()) painter.setPen(Qt.white) painter.drawText(textPos, self.mObject.name())
def drawBackground(self, painter, rect): # Shadow. sceneRect = self.sceneRect() rightShadow = QRectF(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height()) bottomShadow = QRectF(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5) if rightShadow.intersects(rect) or rightShadow.contains(rect): painter.fillRect(rightShadow, Qt.darkGray) if bottomShadow.intersects(rect) or bottomShadow.contains(rect): painter.fillRect(bottomShadow, Qt.darkGray) # Fill. gradient = QLinearGradient(sceneRect.topLeft(), sceneRect.bottomRight()) gradient.setColorAt(0, Qt.white) gradient.setColorAt(1, Qt.lightGray) painter.fillRect(rect.intersected(sceneRect), QBrush(gradient)) painter.setBrush(Qt.NoBrush) painter.drawRect(sceneRect) # Text. textRect = QRectF(sceneRect.left() + 4, sceneRect.top() + 4, sceneRect.width() - 4, sceneRect.height() - 4) message = "Click and drag the nodes around, and zoom with the " \ "mouse wheel or the '+' and '-' keys" font = painter.font() font.setBold(True) font.setPointSize(14) painter.setFont(font) painter.setPen(Qt.lightGray) painter.drawText(textRect.translated(2, 2), message) painter.setPen(Qt.black) painter.drawText(textRect, message)
def wait(self): array_data = self._arrayreq.wait() rectf = self.rectf if array_data.handedness_switched: # array_data should be of type slicingtools.ProjectedArray rectf = QRectF(rectf.height(), rectf.width()) from PyQt5.QtWidgets import QPainter img = QImage(QSize(self.rectf.width(), self.rectf.height()), QImage.Format_ARGB32_Premultiplied) img.fill(0xFFFFFFFF) p = QPainter(img) p.drawImage(0, 0, img) DummyItem(self.rectf).paint(p, None) return img
def syncWithTileLayer(self): self.prepareGeometryChange() renderer = self.mMapDocument.renderer() boundingRect = QRectF(renderer.boundingRect(self.mLayer.bounds())) margins = self.mLayer.drawMargins() map = self.mLayer.map() if map: margins.setTop(margins.top() - map.tileHeight()) margins.setRight(margins.right() - map.tileWidth()) self.mBoundingRect = boundingRect.adjusted(-margins.left(), -margins.top(), margins.right(), margins.bottom())
class RoundRectItem(QGraphicsObject): def __init__(self, bounds, color, parent=None): super(RoundRectItem, self).__init__(parent) self.fillRect = False self.bounds = QRectF(bounds) self.pix = QPixmap() self.gradient = QLinearGradient() self.gradient.setStart(self.bounds.topLeft()) self.gradient.setFinalStop(self.bounds.bottomRight()) self.gradient.setColorAt(0, color) self.gradient.setColorAt(1, color.darker(200)) self.setCacheMode(QGraphicsItem.ItemCoordinateCache) def setFill(self, fill): self.fillRect = fill self.update() def fill(self): return self.fillRect fill = pyqtProperty(bool, fill, setFill) def paint(self, painter, option, widget): painter.setPen(Qt.NoPen) painter.setBrush(QColor(0, 0, 0, 64)) painter.drawRoundedRect(self.bounds.translated(2, 2), 25.0, 25.0) if self.fillRect: painter.setBrush(QApplication.palette().brush(QPalette.Window)) else: painter.setBrush(self.gradient) painter.setPen(QPen(Qt.black, 1)) painter.drawRoundedRect(self.bounds, 25.0, 25.0) if not self.pix.isNull(): painter.scale(1.95, 1.95) painter.drawPixmap(-self.pix.width() / 2, -self.pix.height() / 2, self.pix) def boundingRect(self): return self.bounds.adjusted(0, 0, 2, 2) def pixmap(self): return QPixmap(self.pix) def setPixmap(self, pixmap): self.pix = QPixmap(pixmap) self.update()
def activate_tracker(self, bounds: QtCore.QRectF): """ The main map tells us how large its view is (in terms of the game map) and where it is currently. :param bounds: """ # scale to scene width and height w = self.scene.width() h = self.scene.height() bounds = QtCore.QRectF(bounds.x() * w, bounds.y() * h, bounds.width() * w, bounds.height() * h) # set bounds of tracker and show self.tracker.setRect(bounds) self.tracker.show()
class PolygonBase(QGraphicsWidget): def __init__(self): super().__init__() self.MAR = 50 self.points = [] self.top_left = QPointF(float('Inf'), float('Inf')) self.bottom_right = QPointF(-float('Inf'), -float('Inf')) self.rect = QRectF() def boundingRect(self): return self.rect def update_bounding_rect(self, pt): """插入新顶点时,更新 bounding rect Args: pt (QPointF): 新插入的顶点 """ self.top_left = QPointF(min(self.top_left.x(), pt.x()), min(self.top_left.y(), pt.y())) self.bottom_right = QPointF(max(self.bottom_right.x(), pt.x()), max(self.bottom_right.y(), pt.y())) self.rect = QRectF(self.top_left, self.bottom_right).adjusted(-self.MAR, -self.MAR, self.MAR, self.MAR) self.prepareGeometryChange() def move_bounding_rect(self, offset): """移动多边形时,更新 bounding rect Args: offset (QPointF): 平移向量 """ self.top_left += offset self.bottom_right += offset self.rect.adjust(offset.x(), offset.y(), offset.x(), offset.y()) self.prepareGeometryChange() def get_points(self): """获取多边形中的顶点列表 Returns: points (list[QPointF]): 顶点列表 """ return self.points def get_vertices(self): """获取多边形中的顶点列表 Returns: vertices (list[list[float]]): 顶点列表 """ vertices = [[vertex.x(), vertex.y()] for vertex in self.points] return vertices
class Spinner(QSvgWidget): icon_file = QtDynamicProperty('icon_file', type=unicode) icon_size = QtDynamicProperty('icon_size', type=QSize) icon_crop = QtDynamicProperty('icon_crop', type=int) def __init__(self, parent=None, icon='icons/spinner.svg'): super(Spinner, self).__init__(parent) self._original_viewbox = QRectF() self.icon_crop = 0 self.icon_size = None self.icon_file = Resources.get(icon) def load(self, svg): super(Spinner, self).load(svg) self._original_viewbox = self.renderer().viewBoxF() self._update_viewbox(self.size()) def event(self, event): if event.type() == QEvent.DynamicPropertyChange: if event.propertyName() == 'icon_crop': self._update_viewbox(self.size()) elif event.propertyName() == 'icon_file': self.load(self.icon_file) elif event.propertyName() == 'icon_size': self.updateGeometry() return super(Spinner, self).event(event) def resizeEvent(self, event): super(Spinner, self).resizeEvent(event) self._update_viewbox(event.size()) def sizeHint(self): return self.icon_size or super(Spinner, self).sizeHint() def _update_viewbox(self, size): if self._original_viewbox.isEmpty() or size.isEmpty(): return if self.icon_crop >= 0: adjustment = self.icon_crop else: adjustment = self._original_viewbox.width() * self.icon_crop / (self._original_viewbox.width() + 2*self.icon_crop) # (w - w * w/(w+2b))/2 = wb/(w+2b) viewbox = self._original_viewbox.adjusted(adjustment, adjustment, -adjustment, -adjustment) width = size.width() height = size.height() if height >= width: new_viewbox = QRectF(viewbox.x(), viewbox.y() + viewbox.height()/2 * (1 - height/width), viewbox.width(), viewbox.height() * height/width) else: new_viewbox = QRectF(viewbox.x() + viewbox.width()/2 * (1 - width/height), viewbox.y(), viewbox.width() * width/height, viewbox.height()) self.renderer().setViewBox(new_viewbox)
def initUI(self): # load main ui window self.uic = uic.loadUi('main.ui', self) gr_rect = QRectF(0, 0, self.rect().width(), 20) self.scene = QGraphicsScene(gr_rect) self.scene.setBackgroundBrush(Qt.black) self.anim = NS_Animate(self.scene, gr_rect.width(), gr_rect.height(), QtGui.QColor.fromRgb(0, 32, 49)) self.horizontalLayout_anim.addWidget(self.anim.window) # self.anim.start() self.anim.window.resize(gr_rect.width(), gr_rect.height())
def mouseMoveEvent(self, event): canvasPos = event.localPos() widget = self.parent() if self._itemTuple is not None: if self._shouldPrepareUndo: self._glyph.prepareUndo() self._shouldPrepareUndo = False dx = canvasPos.x() - self._origin.x() dy = canvasPos.y() - self._origin.y() for anchor in self._glyph.anchors: if anchor.selected: anchor.move((dx, dy)) for contour in self._glyph: moveUISelection(contour, (dx, dy)) for component in self._glyph.components: if component.selected: component.move((dx, dy)) self._origin = canvasPos else: self._rubberBandRect = QRectF(self._origin, canvasPos).normalized() items = widget.items(self._rubberBandRect) points = set(items["points"]) if event.modifiers() & Qt.ShiftModifier: points ^= self._oldSelection # TODO: fine-tune this more, maybe add optional args to items... if event.modifiers() & Qt.AltModifier: points = set(pt for pt in points if pt.segmentType) if points != self._glyph.selection: # TODO: doing this takes more time than by-contour # discrimination for large point count self._glyph.selection = points widget.update()
def __init__(self): super().__init__() self.MAR = 50 self.points = [] self.top_left = QPointF(float('Inf'), float('Inf')) self.bottom_right = QPointF(-float('Inf'), -float('Inf')) self.rect = QRectF()
def __init__(self): super().__init__() self.mMapDocument = None self.mBoundingRect = QRectF() self.mRegion = QRegion() self.setFlag(QGraphicsItem.ItemUsesExtendedStyleOption)
class BoxOutline(QGraphicsItem): def __init__(self, bg_color): super(BoxOutline, self).__init__() self.rect = QRectF() self.bg_color = bg_color def shape(self): path = QPainterPath() path.addRect(self.rect) return path def boundingRect(self): return self.rect def paint(self, painter, option, widget=None): p = QPen(Qt.black) if self.isSelected(): p.setWidth(5) painter.setPen(p) else: p.setWidth(1) painter.setPen(p) painter.setBrush(self.bg_color) r = self.rect.height() / 8.0 painter.drawRoundedRect(self.rect, r, r)
def __init__(self, object, parent = None): super().__init__(parent) self.mBoundingRect = QRectF() self.mObject = object self.setFlags(QGraphicsItem.ItemIgnoresTransformations | QGraphicsItem.ItemIgnoresParentOpacity)
def mousePressEvent(self, event): QGraphicsScene.mousePressEvent(self, event) if not (any(key.pressed for key in self.piano_keys) or any(note.pressed for note in self.notes)): for note in self.selected_notes: note.setSelected(False) self.selected_notes = [] if event.button() == Qt.LeftButton: if self.insert_mode: self.place_ghost = True else: self.marquee_select = True self.marquee_rect = QRectF(event.scenePos().x(), event.scenePos().y(), 1, 1) self.marquee = QGraphicsRectItem(self.marquee_rect) self.marquee.setBrush(QColor(255, 255, 255, 100)) self.addItem(self.marquee) else: for s_note in self.notes: if s_note.pressed and s_note in self.selected_notes: break elif s_note.pressed and s_note not in self.selected_notes: for note in self.selected_notes: note.setSelected(False) self.selected_notes = [s_note] break for note in self.selected_notes: if not self.velocity_mode: note.mousePressEvent(event)
class ContainerItem: def __init__(self, entity, pos, scene): self.entity_width = 180 self.entity_height = 80 self.entity_pen = QPen(Qt.black, 5, Qt.SolidLine) self.entity_brush = QBrush(Qt.green, Qt.SolidPattern) self.attribute_width = 90 self.attribute_height = 50 self.attribute_pen = QPen(Qt.black, 3, Qt.SolidLine) self.attribute_brush = QBrush(Qt.blue, Qt.Dense6Pattern) self.at_connection_pen = QPen(Qt.black, 3, Qt.SolidLine) self.entity = entity self.no_atr = len(self.entity.attr_list) self.inter_atr_margin = 15 self.min_height = -50 self.container_width = self.entity_width + self.attribute_width self.container_height = -1 * self.min_height * self.no_atr + self.attribute_height self.en_shape = scene.addRect( QRectF(0, 0, self.entity_width, self.entity_height), self.entity_pen, self.entity_brush) self.txt_style = ''' QWidget{border:3px dashed black;padding-bottom:5px;} ''' self.txt_en_geometry = QRectF(0.0, 0.0, self.entity_width / 2, self.entity_height / 2) self.txt_atr_geometry = QRectF(0.0, 0.0, self.attribute_width / 2, self.attribute_height / 2) self.txt_atr_child_geometry = QRectF(0.0, 0.0, self.attribute_width / 2, self.attribute_height / 2) self.txt_atr_pos = QPointF(self.attribute_width / 4, self.attribute_height / 4) self.txt_en_pos = QPointF(self.entity_width / 4, self.entity_height / 4) self.en_txt = scene.addWidget(QLineEdit()) self.en_txt.setParentItem(self.en_shape) self.en_txt.setGeometry(self.txt_en_geometry) self.en_txt.widget().setStyleSheet(self.txt_style) self.en_txt.widget().setText(self.entity.name) self.en_txt.setPos(self.txt_en_pos) self.en_txt.widget().editingFinished.connect( lambda: ContainerItem.trial(self, -1, self.en_txt.widget(), 0)) self.scene = scene self.en_shape.setPos(pos) self.con_list = [] self.atr_shape_list = [] self.atr_txt_list = [] self.rel_orgn = QPointF(0, self.entity_height) self.orgn_step = 15 self.id = 0 if (self.no_atr > 1): self.atr_step = self.entity_width / (self.no_atr - 1) if (2 * self.atr_step < self.attribute_width): self.attribute_width = 2 * self.atr_step - self.inter_atr_margin self.txt_atr_geometry = QRectF(0.0, 0.0, self.attribute_width / 2, self.attribute_height / 2) for i in range(0, self.no_atr): self.attach_attribute( QLineF(self.atr_step * i, 0, self.atr_step * i, self.min_height - i * self.attribute_height), self.entity.attr_list[i].name, i, self.entity.attr_list[i].type, self.en_shape, self.attribute_width, self.attribute_height, self.txt_atr_geometry, -1) if (self.entity.attr_list[i].isComposite): no_child = len(self.entity.attr_list[i].attrib_childs) if (no_child > 1): ch_step = self.attribute_width / ( len(self.entity.attr_list[0].attrib_childs) - 1) else: ch_step = self.attribute_width par_x = self.atr_step * i - self.attribute_width / 2 par_y = self.min_height - i * self.attribute_height - self.attribute_height for j in range(0, no_child): self.attach_attribute( QLineF( par_x + (ch_step) * j, self.get_y_elipse( par_x + (ch_step) * j, par_x + self.attribute_width / 2, par_y + self.attribute_height / 2), par_x + ch_step * j, par_y + self.min_height / 2 - j * self.attribute_height * 0.75), self.entity.attr_list[i].attrib_childs[j].name, i, self.entity.attr_list[i].attrib_childs[j].type, self.en_shape, self.attribute_width * 0.75, self.attribute_height * 0.75, self.txt_atr_child_geometry, j) child_height = -1 * par_y - 1 * self.min_height + no_child * 0.75 * self.attribute_height if (child_height > self.container_height): self.container_height = child_height elif (self.no_atr == 1): self.attach_attribute(QLineF(0, 0, 0, self.min_height), self.entity.attr_list[0].name, 0, 'prime', self.en_shape, self.attribute_width, self.attribute_height, self.txt_atr_geometry, -1) if (self.entity.attr_list[0].isComposite): no_child = len(self.entity.attr_list[0].attrib_childs) if (no_child > 1): ch_step = self.attribute_width / ( len(self.entity.attr_list[0].attrib_childs) - 1) else: ch_step = self.attribute_width par_x = 0 - self.attribute_width / 2 par_y = 0 + self.min_height - self.attribute_height for j in range(0, no_child): self.attach_attribute( QLineF( par_x + (ch_step) * j, self.get_y_elipse( par_x + (ch_step) * j, 0, self.min_height - self.attribute_height / 2), par_x + ch_step * j, par_y + self.min_height / 2 - j * self.attribute_height * 0.75), self.entity.attr_list[0].attrib_childs[j].name, 0, self.entity.attr_list[0].attrib_childs[j].type, self.en_shape, self.attribute_width * 0.75, self.attribute_height * 0.75, self.txt_atr_child_geometry, j) self.id += 1 self.container_height += self.attribute_height / 2 + -1 * self.min_height / 2 - j * self.attribute_height / 2 + 10 child_height = -1 * par_y - 1 * self.min_height + no_child * 0.75 * self.attribute_height if (child_height > self.container_height): self.container_height = child_height 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 trial(self, id, widget, child): if id == -1: self.entity.name = widget.text() elif (child == -1): self.entity.attr_list[id].name = widget.text() else: self.entity.attr_list[id].attrib_childs[child].name = widget.text() def connect_relation(self, x, y, type): ver_line = QGraphicsLineItem(self.en_shape) horz_line = QGraphicsLineItem(self.en_shape) ver_line.setLine( QLineF(self.rel_orgn.x(), self.rel_orgn.y(), self.rel_orgn.x(), y - self.en_shape.y())) horz_line.setLine( QLineF(ver_line.line().x2(), ver_line.line().y2(), x - self.en_shape.x(), y - self.en_shape.y())) self.rel_orgn.setX(self.rel_orgn.x() + self.orgn_step) if (type == 'p'): ver_line.setPen(QPen(Qt.black, 3, Qt.DashLine)) horz_line.setPen(QPen(Qt.black, 3, Qt.DashLine)) def get_y_elipse(self, x, h, k): a = (self.attribute_width / 2) b = self.attribute_height / 2 m = ((x - h)**2) / a**2 return (((1 - m) * b**2)**0.5 * -1) + k
def getRectFromPoints(self, pts): pt1, pt2 = pts[0], pts[1] x1, y1 = pt1.x(), pt1.y() x2, y2 = pt2.x(), pt2.y() return QRectF(x1, y1, x2 - x1, y2 - y1)
"""Summary """ from PyQt5.QtCore import QRectF, QPointF from PyQt5.QtGui import QPainterPath, QPolygonF from cadnano.views.pathview import pathstyles as styles from cadnano.gui.palette import getPenObj from .abstractpathtool import AbstractPathTool _BW = styles.PATH_BASE_WIDTH _PEN = getPenObj(styles.RED_STROKE, 1) _RECT = QRectF(0, 0, _BW, _BW) _PATH_ARROW_LEFT = QPainterPath() _L3_POLY = QPolygonF() _L3_POLY.append(QPointF(_BW, 0)) _L3_POLY.append(QPointF(0.25 * _BW, 0.5 * _BW)) _L3_POLY.append(QPointF(_BW, _BW)) _PATH_ARROW_LEFT.addPolygon(_L3_POLY) _PATH_ARROW_RIGHT = QPainterPath() _R3_POLY = QPolygonF() # right-hand 3' arr _R3_POLY.append(QPointF(0, 0)) _R3_POLY.append(QPointF(0.75 * _BW, 0.5 * _BW)) _R3_POLY.append(QPointF(0, _BW)) _PATH_ARROW_RIGHT.addPolygon(_R3_POLY) class BreakTool(AbstractPathTool): """ docstring for BreakTool """ def __init__(self, manager): """Summary
def __init__(self, parent=None): super(GraphWidget, self).__init__(parent) self.editFlag = False # 未在编辑转态 self.controllerKey = ControllerManager().addController() self.sceneWidth = 10000 self.sceneHeight = 10000 self.bindingFile = None # 创建图形场景对象,传递控制键参数 self.scene = DiagramScene(self.controllerKey) self.scene.setSceneRect( QRectF(-self.sceneWidth / 2.0, -self.sceneHeight / 2.0, self.sceneWidth, self.sceneHeight)) # 将信号itemSelected连接到指定槽函数 self.scene.itemSelected.connect(self.itemSelected) self.scene.resetModeSignal.connect(self.modeReseted) self.scene.editSignal.connect(self.sceneEdited) # 创建图形视口对象,传入图形场景作为对象参数 self.view = DiagramView(self.scene) # self.view.setBackgroundBrush(QColor(230, 200, 167)) # self.view.setBackgroundBrush(QColor(41, 41, 41)) self.view.setMouseTracking(True) # 视图鼠标跟踪 # 创建水平布局管理器对象 layout = QHBoxLayout() # 视图控件对象添加到布局管理器中 layout.addWidget(self.view) # 把布局管理器设置给需要布局的父控件 self.setLayout(layout) # 参数面板控件 self.args_panel = ArgsDockWidget(self) self.args_panel.setWindowFlags(Qt.CustomizeWindowHint | Qt.FramelessWindowHint | Qt.SubWindow) # self.args_panel.args_tab.setColumnWidth(0, 100) # self.args_panel.args_tab.setColumnWidth(1, 150) self.args_panel.setGeometry(0, 0, 250, 200) self.args_panel.hide() # 空白控件,新建节点快捷栏 self.blankWidget = QuickDockWidget() self.blankWidget.setParent(self) self.blankWidget.resize(900, 80) self.blankWidget.show() self.blankWidget.raise_() self.blankWidget.hide() # 默认掩藏节点快捷栏 self.findResult = set() self.findResultItems = [] self.targetNode = None self.prevNodeList = [] self.nextNodeList = [] self.prevEdgeList = [] self.nextEdgeList = [] self.controller = ControllerManager().getController(self.controllerKey) self.controller.setScene(self.scene) self.nameIndex = {} self.valueIndex = {} self.commentIndex = {} self.allNodes = set() self.logger = logger.getLogger('GraphWidget') self.spinBoxValue = 0.00 self.process = None self.run_mode = None self.parent_conn, self.child_conn = multiprocessing.Pipe() # 线程 读取管道数据 # self.thread_ = threading.Thread(target=self.receive_data) # self.thread_.setDaemon(True) # self.thread_.start() self.read_data_thread = ReadDataThread(self.parent_conn, self) self.read_data_thread.start() self.read_data_thread.dataSignal[dict].connect(self.receive_data) self.read_data_thread.dataSignal[str].connect(self.finishedSlot)
def rect(self): return QRectF(self.position.x() - self.radius, self.position.y() - self.radius, 2 * self.radius, 2 * self.radius)
def drawBackground(self, painter: QPainter, rect: QRectF): if self.draw_grid and len(self.frequencies) > 0: painter.setPen(QPen(painter.pen().color(), 0)) parent_width = self.parent().width() if hasattr( self.parent(), "width") else 750 view_rect = self.parent().view_rect() if hasattr( self.parent(), "view_rect") else rect font_width = self.font_metrics.width( Formatter.big_value_with_suffix(self.center_freq) + " ") x_grid_size = int(view_rect.width() / parent_width * font_width) # x_grid_size = int(0.1 * view_rect.width()) if 0.1 * view_rect.width() > 1 else 1 y_grid_size = 1 x_mid = np.where(self.frequencies == 0)[0] x_mid = int(x_mid[0]) if len(x_mid) > 0 else 0 left = int(rect.left()) - (int(rect.left()) % x_grid_size) left = left if left > 0 else 0 top = rect.top() - (rect.top() % y_grid_size) bottom = rect.bottom() - (rect.bottom() % y_grid_size) right_border = int( rect.right()) if rect.right() < len(self.frequencies) else len( self.frequencies) scale_x, scale_y = util.calc_x_y_scale(rect, self.parent()) fh = self.font_metrics.height() x_range = list(range(x_mid, left, -x_grid_size)) + list( range(x_mid, right_border, x_grid_size)) lines = [QLineF(x, rect.top(), x, bottom-fh*scale_y) for x in x_range] \ + [QLineF(rect.left(), y, rect.right(), y) for y in np.arange(top, bottom, y_grid_size)] pen = painter.pen() pen.setStyle(Qt.DotLine) painter.setPen(pen) painter.drawLines(lines) painter.scale(scale_x, scale_y) counter = -1 # Counter for Label for every second line for x in x_range: freq = self.frequencies[x] counter += 1 if freq == 0: counter = 0 if freq != 0 and (counter % 2 != 0): # Label for every second line continue value = Formatter.big_value_with_suffix( self.center_freq + freq, 2) font_width = self.font_metrics.width(value) painter.drawText( QPointF(x / scale_x - font_width / 2, bottom / scale_y), value)
def show(self, title, points, pos): self.setGeometry(QRectF(pos, self.size())) self.tipWidget.updateUi(title, points) super(GraphicsProxyWidget, self).show()
def paint(self, painter: QtGui.QPainter, option: 'QStyleOptionViewItem', index: QtCore.QModelIndex) -> None: if not index.isValid(): return if option.state & QStyle.State_Selected: pass if option.state & QStyle.State_MouseOver: pass item = index.model().data(index, Qt.UserRole) if isinstance(item, QVariant): return painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHints(QPainter.SmoothPixmapTransform) value = item['value'] type = item['type'] x = option.rect.x() y = option.rect.y() w = option.rect.width() h = option.rect.height() if type == 'device_activity': painter.save() # 图标 icon = QImage(ResourceLoader().icon_path(value['icon'])) rect_icon = QRectF(x + 20, y + 13, 44, 44) painter.drawImage(rect_icon, icon) # 设备标签 painter.setFont(ResourceLoader().qt_font_text_xs) rect = calculate_text_rect('设备', painter=painter, x=x + 70, y=y + 15) painter.drawText(rect, Qt.TextSingleLine, '设备') # 设备编号 painter.setPen(ResourceLoader().qt_color_label_link) painter.setFont(ResourceLoader().qt_font_text_xs) rect = calculate_text_rect(value['device'], painter=painter, x=x + 110, y=y + 15) painter.drawText(rect, Qt.TextSingleLine, value['device']) # 活动内容 painter.setPen(ResourceLoader().qt_color_sub_text) painter.setFont(ResourceLoader().qt_font_text_xss) content = value['content'] + ',' + toDateStr() rect = calculate_text_rect(content, painter=painter, x=x + 70, y=y + 40) painter.drawText(rect, Qt.TextSingleLine, content) # 绘制边框 path = QPainterPath() path.addRoundedRect(QRectF(x + 4, y + 4, w - 8, h - 8), 4, 4) painter.strokePath(path, QPen(ResourceLoader().qt_color_background, 1)) painter.restore() elif type == 'load_more': # 绘制加载图标 # painter.save() # painter.translate(x+16, y+16) # self.loading_rotate += 5 # painter.rotate(self.loading_rotate%360) # icon = qtawesome.icon('mdi.loading', color=ResourceLoader().qt_color_sub_text) # icon_pixmap = icon.pixmap(QSize(32, 32)) # painter.drawPixmap(QRect(-16, -16, 32, 32), icon_pixmap) # painter.restore() # 绘制加载信息 painter.save() painter.setFont(ResourceLoader().qt_font_text_xs) painter.setPen(ResourceLoader().qt_color_sub_text) _rect = calculate_text_rect('~~~ 正在努力加载 ~~~', painter=painter) rect = calculate_middle_rect(option.rect, width=_rect.width(), height=_rect.height()) painter.drawText(rect, Qt.TextSingleLine, '~~~ 正在努力加载 ~~~') painter.restore() elif type == 'no_more': painter.save() painter.setFont(ResourceLoader().qt_font_text_xs) painter.setPen(ResourceLoader().qt_color_sub_text) _rect = calculate_text_rect('--- 我是有底线的 ---', painter=painter) rect = calculate_middle_rect(option.rect, width=_rect.width(), height=_rect.height()) painter.drawText(rect, Qt.TextSingleLine, '--- 我是有底线的 ---') painter.restore() else: self.initStyleOption(option, index) QStyledItemDelegate.paint(self, painter, option, index)
def boundingRect(self): return QRectF(0, 0, self.p_width, self.p_height)
class BCWImagePreview(QGraphicsView): """Display image with pan/zoom hability""" BG_BLACK = 0 BG_WHITE = 1 BG_NEUTRAL_GRAY = 2 BG_TRANSPARENT = 3 BG_CHECKER_BOARD = 4 # Mouse button emit coordinates on image leftButtonPressed = Signal(float, float) rightButtonPressed = Signal(float, float) leftButtonReleased = Signal(float, float) rightButtonReleased = Signal(float, float) leftButtonDoubleClicked = Signal(float, float) rightButtonDoubleClicked = Signal(float, float) zoomChanged = Signal(float) def __init__(self, parent=None): """Initialise viewer""" def zoomToFit(dummy): self.setZoom(0.0) def zoom1x1(dummy): self.setZoom(1.0) def bgColorBlack(dummy): self.setBackgroundType(BCWImagePreview.BG_BLACK) def bgColorWhite(dummy): self.setBackgroundType(BCWImagePreview.BG_WHITE) def bgColorNGray(dummy): self.setBackgroundType(BCWImagePreview.BG_NEUTRAL_GRAY) def bgColorNone(dummy): self.setBackgroundType(BCWImagePreview.BG_TRANSPARENT) def bgColorCheckerBoard(dummy): self.setBackgroundType(BCWImagePreview.BG_CHECKER_BOARD) super(BCWImagePreview, self).__init__(parent) # Image is a QPixmap in a QGraphicsScene self.__gScene = QGraphicsScene() self.setScene(self.__gScene) # Handle for current image self.__bgImg = QPixmap() self.__imgBgHandle = self.__imgHandle = self.__gScene.addPixmap( self.__bgImg) self.__imgBgHandle.setFlag(QGraphicsItem.ItemIgnoresTransformations, True) self.__imgHandle = None self.__imgRectF = None self.__currentZoomFactor = 1.0 # default properties self.__allowPan = True self.__allowZoom = True self.__allowMenu = True self.__backgroundType = None self.__mousePos = None self.__actionZoom1x1 = QAction(QIcon(":/images/zoom_1x1"), i18n('Zoom 1:1'), self) self.__actionZoom1x1.triggered.connect(zoom1x1) self.__actionZoomToFit = QAction(QIcon(":/images/zoom_fit"), i18n('Zoom to fit'), self) self.__actionZoomToFit.triggered.connect(zoomToFit) self.__actionBgBlack = QAction(QIcon(":/images/color_black"), i18n('Black'), self) self.__actionBgBlack.triggered.connect(bgColorBlack) self.__actionBgBlack.setCheckable(True) self.__actionBgWhite = QAction(QIcon(":/images/color_white"), i18n('White'), self) self.__actionBgWhite.triggered.connect(bgColorWhite) self.__actionBgWhite.setCheckable(True) self.__actionBgNGray = QAction(QIcon(":/images/color_ngray"), i18n('Gray'), self) self.__actionBgNGray.triggered.connect(bgColorNGray) self.__actionBgNGray.setCheckable(True) self.__actionBgNone = QAction(QIcon(":/images/color_none"), i18n('Default'), self) self.__actionBgNone.triggered.connect(bgColorNone) self.__actionBgNone.setCheckable(True) self.__actionBgCheckerBoard = QAction( QIcon(":/images/color_checkerboard"), i18n('Checker board'), self) self.__actionBgCheckerBoard.triggered.connect(bgColorCheckerBoard) self.__actionBgCheckerBoard.setCheckable(True) self.__contextMenu = QMenu(i18n("Background")) self.__bgMenu = self.__contextMenu.addMenu(QIcon(":/images/color"), 'Background') self.__contextMenu.addSeparator() self.__contextMenu.addAction(self.__actionZoom1x1) self.__contextMenu.addAction(self.__actionZoomToFit) self.__bgMenu.addAction(self.__actionBgCheckerBoard) self.__bgMenu.addSeparator() self.__bgMenu.addAction(self.__actionBgBlack) self.__bgMenu.addAction(self.__actionBgWhite) self.__bgMenu.addAction(self.__actionBgNGray) self.__bgMenu.addAction(self.__actionBgNone) menuGroup = QActionGroup(self) menuGroup.addAction(self.__actionBgCheckerBoard) menuGroup.addAction(self.__actionBgBlack) menuGroup.addAction(self.__actionBgWhite) menuGroup.addAction(self.__actionBgNGray) menuGroup.addAction(self.__actionBgNone) self.setContextMenuPolicy(Qt.DefaultContextMenu) # Set a default scrollbar configuration self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) self.setResizeAnchor(QGraphicsView.AnchorUnderMouse) self.setBackgroundType(BCWImagePreview.BG_CHECKER_BOARD) def contextMenuEvent(self, event): self.__contextMenu.exec_(event.globalPos()) @staticmethod def backgroundList(): """return list of possible values""" return [ BCWImagePreview.BG_BLACK, BCWImagePreview.BG_WHITE, BCWImagePreview.BG_NEUTRAL_GRAY, BCWImagePreview.BG_TRANSPARENT, BCWImagePreview.BG_CHECKER_BOARD ] def allowZoom(self): """Return True if user is allowed to zoom with mouse""" return self.__allowZoom def setAllowZoom(self, value=True): """define if user is allowed to zoom with mouse""" if not isinstance(value, bool): raise EInvalidType("Given `value` must be a <bool>") self.__allowZoom = value def allowPan(self): """Return True if user is allowed to pan with mouse""" return self.__allowPan def setAllowPan(self, value=True): """define if user is allowed to pan with mouse""" if not isinstance(value, bool): raise EInvalidType("Given `value` must be a <bool>") self.__allowPan = value def allowMenu(self): """Return True if user is allowed to display default context menu""" return self.__allowMenu def setAllowMenu(self, value=True): """define if user is allowed to display context menu""" if not isinstance(value, bool): raise EInvalidType("Given `value` must be a <bool>") self.__allowMenu = value def backgroundType(self): """Return current background definition""" return self.__backgroundType def setBackgroundType(self, value): """Set current background definition Can be: BCWImagePreview.BG_BLACK = 0 BCWImagePreview.BG_WHITE = 1 BCWImagePreview.BG_NEUTRAL_GRAY = 2 BCWImagePreview.BG_TRANSPARENT = 3 BCWImagePreview.BG_CHECKER_BOARD = 4 """ if not isinstance(value, int): raise EInvalidType("Given `value` must be a valid <int>") if not value in [ BCWImagePreview.BG_BLACK, BCWImagePreview.BG_WHITE, BCWImagePreview.BG_NEUTRAL_GRAY, BCWImagePreview.BG_TRANSPARENT, BCWImagePreview.BG_CHECKER_BOARD ]: raise EInvalidValue("Given `value` is not valid") if self.__backgroundType != value: self.__backgroundType = value if self.__backgroundType == BCWImagePreview.BG_BLACK: self.__gScene.setBackgroundBrush(QBrush(Qt.black)) self.__actionBgBlack.setChecked(True) elif self.__backgroundType == BCWImagePreview.BG_WHITE: self.__gScene.setBackgroundBrush(QBrush(Qt.white)) self.__actionBgWhite.setChecked(True) elif self.__backgroundType == BCWImagePreview.BG_NEUTRAL_GRAY: self.__gScene.setBackgroundBrush(QBrush(QColor(128, 128, 128))) self.__actionBgNGray.setChecked(True) elif self.__backgroundType == BCWImagePreview.BG_TRANSPARENT: self.__gScene.setBackgroundBrush( QBrush(Krita.activeWindow().qwindow().palette().color( QPalette.Mid))) self.__actionBgNone.setChecked(True) elif self.__backgroundType == BCWImagePreview.BG_CHECKER_BOARD: self.__gScene.setBackgroundBrush(checkerBoardBrush(32)) self.__actionBgCheckerBoard.setChecked(True) def zoom(self): """Return current zoom property returned value is a tuple (ratio, QRectF) or None if there's no image """ return self.__currentZoomFactor if self.hasImage(): if len(self.__zoomList) > 0: rect = self.__zoomList[-1] else: rect = self.sceneRect() imgRect = QRectF(self.__imgHandle.pixmap().rect()) if rect.width() > 0: ratio = imgRect.width() / rect.width() else: ratio = 1.0 return (ratio, rect) else: return None def setZoom(self, value=0.0): """Set current zoom value If value is a QRect() or QRectF(), set zoom to given bounds If value is a float, bounds are calculated automatically: 0 = fit to view """ if not self.hasImage(): return viewportRect = self.viewport().rect() if isinstance(value, QRect): value = QRectF(value) if isinstance(value, QRectF): sceneRect = self.transform().mapRect(value) self.__currentZoomFactor = min( viewportRect.width() / sceneRect.width(), viewportRect.height() / sceneRect.height()) self.scale(self.__currentZoomFactor, self.__currentZoomFactor) self.centerOn( value.left() + value.width() / 2, value.top() + value.height() / 2, ) elif isinstance(value, float) or isinstance(value, int): if value == 0: # fit self.resetTransform() self.setSceneRect(self.__imgRectF) sceneRect = self.transform().mapRect(self.__imgRectF) self.__currentZoomFactor = min( viewportRect.width() / sceneRect.width(), viewportRect.height() / sceneRect.height()) self.scale(self.__currentZoomFactor, self.__currentZoomFactor) elif value > 0: self.__currentZoomFactor = value self.resetTransform() self.scale(self.__currentZoomFactor, self.__currentZoomFactor) else: # ignore invalid given zoom return else: raise EInvalidType("Given `value` must be a <float> or <QRectF>") self.zoomChanged.emit(round(self.__currentZoomFactor * 100, 2)) def hasImage(self): """Return if an image is set or not""" if self.__imgHandle is None: return False return True def clearImage(self): """Clear current image""" if self.hasImage(): self.__gScene.removeItem(self.__imgHandle) self.__imgHandle = None self.__imgRectF = None self.__currentZoomFactor = 1.0 def image(self, asPixmap=False): """Return current image as QImage or None if not image is defined """ if self.hasImage(): if asPixmap: return self.__imgHandle.pixmap() else: return self.__imgHandle.pixmap().toImage() return None def setImage(self, image, resetZoom=True): """Set current image Given image is a QImage or a QPixmap """ if not (isinstance(image, QImage) or isinstance(image, QPixmap)): raise EInvalidType( "Given `image` must be a <QImage> or a <QPixmap>") if isinstance(image, QImage): img = QPixmap.fromImage(image) else: img = image if self.hasImage(): self.__imgHandle.setPixmap(img) else: self.__imgHandle = self.__gScene.addPixmap(img) self.__imgRectF = QRectF(img.rect()) if self.__imgRectF.isNull(): self.clearImage() elif resetZoom: # view image to fit self.setZoom(0.0) def resizeEvent(self, event): """When viewer is resized, keep current view rect""" self.resetTransform() self.scale(self.__currentZoomFactor, self.__currentZoomFactor) def mousePressEvent(self, event): """Start Pan or Zoom""" # memorize current mouse position on image self.__mousePos = self.mapToScene(event.pos()) if self.hasImage(): if event.button() == Qt.LeftButton: if self.__allowZoom and event.modifiers( ) == Qt.ControlModifier: self.setDragMode(QGraphicsView.RubberBandDrag) elif self.__allowPan: self.setDragMode(QGraphicsView.ScrollHandDrag) self.leftButtonPressed.emit(self.__mousePos.x(), self.__mousePos.y()) QGraphicsView.mousePressEvent(self, event) def mouseReleaseEvent(self, event): """Stop Pan or Zoom""" QGraphicsView.mouseReleaseEvent(self, event) # memorize current mouse position on image self.__mousePos = self.mapToScene(event.pos()) if self.hasImage(): if event.button() == Qt.LeftButton: if self.__allowZoom and event.modifiers( ) == Qt.ControlModifier: if self.__gScene.selectionArea().boundingRect().width( ) > 0.0: selectionRect = self.__gScene.selectionArea( ).boundingRect().intersected(self.__imgRectF) self.__gScene.setSelectionArea( QPainterPath()) # Clear current selection area. if selectionRect.isValid() and ( selectionRect != self.viewport().rect()): self.setZoom(selectionRect) self.setDragMode(QGraphicsView.NoDrag) elif self.__allowPan: self.setDragMode(QGraphicsView.NoDrag) self.leftButtonReleased.emit(self.__mousePos.x(), self.__mousePos.y()) def mouseDoubleClickEvent(self, event): """Reset zoom - left: default image size - right: fit image """ # memorize current mouse position on image self.__mousePos = self.mapToScene(event.pos()) if event.button() == Qt.LeftButton: if self.zoom() == 1: # scale 1:1 => zoom to fit self.setZoom(0.0) else: # scale is not 1:1 => scale to 1 self.setZoom(1.0) self.leftButtonDoubleClicked.emit(self.__mousePos.x(), self.__mousePos.y()) QGraphicsView.mouseDoubleClickEvent(self, event) def wheelEvent(self, event): """Zoom in/out""" # memorize current mouse position on image self.__mousePos = self.mapToScene(event.pos()) if self.hasImage(): if event.angleDelta().y() > 0: self.setZoom(self.__currentZoomFactor * 1.25) else: self.setZoom(self.__currentZoomFactor * 0.8)
def boundingRect(self): close = self.data['close'].reset_index()['close'] close_max = close.max() close_min = close.min() return QRectF(0, 0, close.size, close_max - close_min)
def boundingRect(self): return QRectF(-35, -81, 70, 115)
class DataModel(QGraphicsScene): WIDTH = 800 HEIGHT = 800 WALL_THICKNESS = 5 ALLOWED_AREA = QRectF(QPointF(-WIDTH / 2, -HEIGHT / 2), QPointF(WIDTH / 2, HEIGHT / 2)) START_POINT = QPointF(0, HEIGHT / 2 - 20) GOAL_POINT = QPointF(0, -HEIGHT / 2 + 20) GOAL_TOLERANCE = 50 # walls around the allowed area WALLS_SURROUNDING = [] # left WALLS_SURROUNDING.append( QRectF( QPointF(ALLOWED_AREA.left() - WALL_THICKNESS, ALLOWED_AREA.top() - WALL_THICKNESS), QPointF(ALLOWED_AREA.left(), ALLOWED_AREA.bottom() + WALL_THICKNESS))) # right WALLS_SURROUNDING.append( QRectF( QPointF(ALLOWED_AREA.right(), ALLOWED_AREA.top() - WALL_THICKNESS), QPointF(ALLOWED_AREA.right() + WALL_THICKNESS, ALLOWED_AREA.bottom() + WALL_THICKNESS))) # top WALLS_SURROUNDING.append( QRectF( QPointF(ALLOWED_AREA.left() - WALL_THICKNESS, ALLOWED_AREA.top() - WALL_THICKNESS), QPointF(ALLOWED_AREA.right() + WALL_THICKNESS, ALLOWED_AREA.top()))) # bottom WALLS_SURROUNDING.append( QRectF( QPointF(ALLOWED_AREA.left() - WALL_THICKNESS, ALLOWED_AREA.bottom()), QPointF(ALLOWED_AREA.right() + WALL_THICKNESS, ALLOWED_AREA.bottom() + WALL_THICKNESS))) # custom walls WALLS_CUSTOM = [] WALLS_CUSTOM.append( QRectF( QPointF(ALLOWED_AREA.left() - WALL_THICKNESS, HEIGHT / 4), QPointF(ALLOWED_AREA.left() + WIDTH - 100, HEIGHT / 4 + WALL_THICKNESS))) WALLS_CUSTOM.append( QRectF(QPointF(ALLOWED_AREA.left() + 100, 0), QPointF(ALLOWED_AREA.right() + WALL_THICKNESS, WALL_THICKNESS))) VISIBILITY_GRAPH = VisibilityGraph(START_POINT, GOAL_POINT, WALLS_CUSTOM + WALLS_SURROUNDING, ALLOWED_AREA) ################################################################################ def __init__(self): """ """ super().__init__() self.setSceneRect(self.ALLOWED_AREA) self._population = Population(self) self._generationCountItem = self.addSimpleText( 'gen: ' + str(self._population.generationCount)) self._generationCountItem.setPos( QPointF(-self.WIDTH / 2 + 20, -self.HEIGHT / 2 + 20)) self._wonCountItem = self.addSimpleText('won: ' + str(self._population.wonCount)) self._wonCountItem.setPos( QPointF(-self.WIDTH / 2 + 20, -self.HEIGHT / 2 + 40)) self._exhaustedCountItem = self.addSimpleText( 'exh: ' + str(self._population.exhaustedCount)) self._exhaustedCountItem.setPos( QPointF(-self.WIDTH / 2 + 20, -self.HEIGHT / 2 + 60)) self._deadCountItem = self.addSimpleText( 'ded: ' + str(self._population.deadCount)) self._deadCountItem.setPos( QPointF(-self.WIDTH / 2 + 20, -self.HEIGHT / 2 + 80)) self._population.updateCounters.connect(self._updateCounters) self._ctrlFlag = False ################################################################################ def _updateCounters(self): """ """ self._generationCountItem.setText( 'gen: ' + str(self._population.generationCount)) self._wonCountItem.setText('won: ' + str(self._population.wonCount)) self._exhaustedCountItem.setText('exh: ' + str(self._population.exhaustedCount)) self._deadCountItem.setText('ded: ' + str(self._population.deadCount)) ################################################################################ def mousePressEvent(self, event): """ """ self._population.start() super().mousePressEvent(event) ################################################################################ def keyPressEvent(self, event): """ """ key = event.key() if key == Qt.Key_Control: self._ctrlFlag = True self.update() super().keyPressEvent(event) ################################################################################ def keyReleaseEvent(self, event): """ """ key = event.key() if key == Qt.Key_Control: self._ctrlFlag = False self.update() super().keyReleaseEvent(event) ################################################################################ def drawBackground(self, painter, rect): """ """ painter.setPen(Qt.gray) painter.setBrush(Qt.gray) painter.drawRect(rect) painter.setBrush(Qt.white) painter.drawRect(self.ALLOWED_AREA) painter.setPen(Qt.blue) painter.setBrush(Qt.blue) painter.drawEllipse(self.START_POINT, 5, 5) painter.setPen(Qt.green) painter.setBrush(Qt.green) painter.drawEllipse(self.GOAL_POINT, self.GOAL_TOLERANCE, self.GOAL_TOLERANCE) painter.setPen(Qt.black) super().drawBackground(painter, rect) ################################################################################ def drawForeground(self, painter, rect): """ """ painter.setPen(QPen(Qt.red, 1, join=Qt.MiterJoin)) painter.setBrush(Qt.red) for rect in self.WALLS_SURROUNDING: painter.drawRect(rect) for rect in self.WALLS_CUSTOM: painter.drawRect(rect) if self._ctrlFlag: painter.setPen(Qt.green) for edge in self.VISIBILITY_GRAPH.shortestRouteEdges: painter.drawLine(edge) else: painter.setPen(Qt.black) for edge in self.VISIBILITY_GRAPH.edges: painter.drawLine(edge) super().drawForeground(painter, rect)
def point_is_outside(self, point: QPointF, bounds: QRectF): return point.x() < bounds.left() or point.x() > bounds.right() or point.y() < bounds.top() or point.y() > bounds.bottom()
def paint(self, painter, option, widget): painter.save() painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing == ANTIALIASING_FULL)) rect = QRectF(0, 0, self.p_width, self.p_height) # Draw rectangle pen = QPen(canvas.theme.box_pen_sel if self.isSelected() else canvas. theme.box_pen) pen.setWidthF(pen.widthF() + 0.00001) painter.setPen(pen) lineHinting = pen.widthF() / 2 if canvas.theme.box_bg_type == Theme.THEME_BG_GRADIENT: box_gradient = QLinearGradient(0, 0, 0, self.p_height) box_gradient.setColorAt(0, canvas.theme.box_bg_1) box_gradient.setColorAt(1, canvas.theme.box_bg_2) painter.setBrush(box_gradient) else: painter.setBrush(canvas.theme.box_bg_1) rect.adjust(lineHinting, lineHinting, -lineHinting, -lineHinting) painter.drawRect(rect) # Draw plugin inline display if supported self.paintInlineDisplay(painter) # Draw pixmap header rect.setHeight(canvas.theme.box_header_height) if canvas.theme.box_header_pixmap: painter.setPen(Qt.NoPen) painter.setBrush(canvas.theme.box_bg_2) # outline rect.adjust(lineHinting, lineHinting, -lineHinting, -lineHinting) painter.drawRect(rect) rect.adjust(1, 1, -1, 0) painter.drawTiledPixmap(rect, canvas.theme.box_header_pixmap, rect.topLeft()) # Draw text painter.setFont(self.m_font_name) if self.isSelected(): painter.setPen(canvas.theme.box_text_sel) else: painter.setPen(canvas.theme.box_text) if canvas.theme.box_use_icon: textPos = QPointF(25, canvas.theme.box_text_ypos) else: appNameSize = fontHorizontalAdvance(self.m_font_name, self.m_group_name) rem = self.p_width - appNameSize textPos = QPointF(rem / 2, canvas.theme.box_text_ypos) painter.drawText(textPos, self.m_group_name) self.repaintLines() painter.restore()
QStyleOptionGraphicsItem, QWidget) from cadnano import getBatch from cadnano.controllers import StrandItemController from cadnano.gui.palette import (getColorObj, getPenObj, getBrushObj, getNoPen) from cadnano.views.pathview import pathstyles as styles from .decorators.insertionitem import InsertionItem from .endpointitem import EndpointItem from .xoveritem import XoverItem from cadnano.views.pathview import (PathNucleicAcidPartItemT, PathVirtualHelixItemT, PathRootItemT) from cadnano.cntypes import (OligoT, StrandT, InsertionT, SegmentT, DocT, WindowT, ValueT) _BASE_WIDTH = styles.PATH_BASE_WIDTH _DEFAULT_RECT = QRectF(0, 0, _BASE_WIDTH, _BASE_WIDTH) _NO_PEN = getNoPen() SELECT_COLOR = "#ff3333" class StrandItem(QGraphicsLineItem): FILTER_NAME = "strand" def __init__(self, model_strand: StrandT, virtual_helix_item: PathVirtualHelixItemT): """The parent should be a VirtualHelixItem. Args: model_strand: virtual_helix_item: """
class MaskItem(pg.GraphicsObject): """Mask item used for drawing mask on an ImageItem.""" _mask = None # QImage _mask_rect = QRectF(0, 0, 0, 0) _TRANSPARENT = QColor(0, 0, 0, 0) _OPAQUE = QColor(0, 0, 0, 255) def __init__(self, item): """Initialization. :param ImageItem item: a reference to the masked image item. """ super().__init__() if not isinstance(item, ImageItem): raise TypeError("Input item must be an ImageItem instance.") self._image_item = item item.draw_started_sgn.connect(self.onDrawStarted) item.draw_region_changed_sgn.connect(self.onDrawRegionChanged) item.draw_finished_sgn.connect(self.onDrawFinished) # pen for drawing the bounding box self._pen = FColor.mkPen(config['GUI_MASK_BOUNDING_BOX_COLOR']) self.state = MaskState.UNMASK self._mask_pub = ImageMaskPub() self._p1 = None self._p2 = None @classmethod def resetMask(cls): cls._mask = None cls._mask_rect = QRectF(0, 0, 0, 0) def boundingRect(self): """Override.""" return self._mask_rect @pyqtSlot(int, int) def onDrawStarted(self, x, y): self._p1 = (x, y) @pyqtSlot(int, int) def onDrawRegionChanged(self, x, y): self.prepareGeometryChange() self._p2 = (x, y) def _selectedRect(self): if self._p1 is None or self._p2 is None: return QRectF(0, 0, 0, 0) rect = QRectF(QPoint(*self._p1), QPoint(*self._p2)) return rect.intersected(self._mask_rect) @pyqtSlot() def onDrawFinished(self): rect = self._selectedRect() x = int(rect.x()) y = int(rect.y()) w = int(rect.width()) h = int(rect.height()) if self.state == MaskState.MASK: self._mask_pub.add((x, y, w, h)) elif self.state == MaskState.UNMASK: self._mask_pub.erase((x, y, w, h)) self._p1 = None self._p2 = None for i in range(x, x + w): for j in range(y, y + h): if self.state == MaskState.MASK: self._mask.setPixelColor(i, j, self._OPAQUE) elif self.state == MaskState.UNMASK: self._mask.setPixelColor(i, j, self._TRANSPARENT) self._image_item.update() def removeMask(self): """Completely remove the current mask.""" # The following sequence ensures that it can be used to rescue if # there is discrepancy between ImageTool and the ImageProcessor. self._mask_pub.remove() if self._mask is None: return self._mask.fill(self._TRANSPARENT) self._image_item.update() def onSetImage(self): h, w = self._image_item.image.shape if self._mask is None: self.__class__._mask = QImage(w, h, QImage.Format_Alpha8) self._mask.fill(self._TRANSPARENT) self.__class__._mask_rect = QRectF(0, 0, w, h) def paint(self, p, *args): if self._mask is None: return p.setRenderHint(QPainter.Antialiasing) p.setPen(self._pen) p.drawImage(self.boundingRect(), self._mask) p.drawRect(self._selectedRect()) def toNDArray(self): w = self._mask.width() h = self._mask.height() mask_array = np.zeros((h, w), dtype=bool) for i in range(w): for j in range(h): mask_array[j, i] = self._mask.pixelColor(i, j) == self._OPAQUE return mask_array def loadMask(self, mask): """Load a given image mask. :param np.ndarray mask: mask in ndarray. shape = (h, w) """ self._mask_pub.set(mask) h, w = mask.shape self.__class__._mask = QImage(w, h, QImage.Format_Alpha8) for i in range(w): for j in range(h): if mask[j, i]: self._mask.setPixelColor(i, j, self._OPAQUE) else: self._mask.setPixelColor(i, j, self._TRANSPARENT) self.__class__._mask_rect = QRectF(0, 0, w, h) self._image_item.update()
def onSetImage(self): h, w = self._image_item.image.shape if self._mask is None: self.__class__._mask = QImage(w, h, QImage.Format_Alpha8) self._mask.fill(self._TRANSPARENT) self.__class__._mask_rect = QRectF(0, 0, w, h)
class TestPathFinding(TestCase): ################################################################################ def setUp(self): """ """ # --left --right # ' ' # I | II | III # ------+==========+------ --top # VIII | IX (in) | IV # ------+==========+------ --bottom # VII | VI | V self._offset = 10 self._rect = QRectF(QPointF(-20, -10), QPointF(20, 10)) self._pointI = QPointF(self._rect.left()-self._offset, self._rect.top()-self._offset) self._pointII = QPointF(self._rect.center().x(), self._rect.top()-self._offset) self._pointIII = QPointF(self._rect.right()+ self._offset, self._rect.top()- self._offset) self._pointIV = QPointF(self._rect.right()+self._offset, self._rect.center().y()) self._pointV = QPointF(self._rect.right()+self._offset, self._rect.bottom()+self._offset) self._pointVI = QPointF(self._rect.center().x(), self._rect.bottom()+self._offset) self._pointVII = QPointF(self._rect.left()-self._offset, self._rect.bottom()+self._offset) self._pointVIII = QPointF(self._rect.left()-self._offset, self._rect.center().y()) self._pointIX = self._rect.center() self._lineI_VII = QLineF(self._pointI, self._pointVII) self._lineI_V = QLineF(self._pointI, self._pointV) self._lineII = QLineF(self._pointII, QPointF(self._rect.center().x(), self._rect.top())) self._lineII_IV = QLineF(QPointF(self._rect.right()-self._offset, self._rect.top()-self._offset), QPointF(self._rect.right()+self._offset, self._rect.top()+self._offset)) ################################################################################ def testPointRectDist(self): """ """ lineI = PathFinding.pointRectDist(self._pointI, self._rect) self.assertEqual(lineI.p2(), self._rect.topLeft()) self.assertEqual(lineI.length(), pow(pow(self._offset, 2)+pow(self._offset, 2), 0.5)) lineII = PathFinding.pointRectDist(self._pointII, self._rect) self.assertEqual(lineII.p2(), QPointF(self._rect.center().x(), self._rect.top())) self.assertEqual(lineII.length(), self._offset) lineIII = PathFinding.pointRectDist(self._pointIII, self._rect) self.assertEqual(lineIII.p2(), self._rect.topRight()) self.assertEqual(lineIII.length(), pow(pow(self._offset, 2)+pow(self._offset, 2), 0.5)) lineIV = PathFinding.pointRectDist(self._pointIV, self._rect) self.assertEqual(lineIV.p2(), QPointF(self._rect.right(), self._rect.center().y())) self.assertEqual(lineIV.length(), self._offset) lineV = PathFinding.pointRectDist(self._pointV, self._rect) self.assertEqual(lineV.p2(), self._rect.bottomRight()) self.assertEqual(lineV.length(), pow(pow(self._offset, 2)+pow(self._offset, 2), 0.5)) lineVI = PathFinding.pointRectDist(self._pointVI, self._rect) self.assertEqual(lineVI.p2(), QPointF(self._rect.center().x(), self._rect.bottom())) self.assertEqual(lineVI.length(), self._offset) lineVII = PathFinding.pointRectDist(self._pointVII, self._rect) self.assertEqual(lineVII.p2(), self._rect.bottomLeft()) self.assertEqual(lineVII.length(), pow(pow(self._offset, 2)+pow(self._offset, 2), 0.5)) lineVIII = PathFinding.pointRectDist(self._pointVIII, self._rect) self.assertEqual(lineVIII.p2(), QPointF(self._rect.left(), self._rect.center().y())) self.assertEqual(lineVIII.length(), self._offset) lineIX = PathFinding.pointRectDist(self._pointIX, self._rect) self.assertEqual(lineIX.p2(), self._pointIX) self.assertEqual(lineIX.length(), 0) ################################################################################ def testIntersects(self): """ """ rect = QRectF(QPointF(-50, -10), QPointF(50, 10)) # line completely outside of the rectangle self.assertFalse(PathFinding.intersects(rect, QLineF(QPointF(-100, -50), QPointF(-100, 50)))) # the line is a top side of the rectangle self.assertFalse(PathFinding.intersects(rect, QLineF(rect.topLeft(), rect.topRight()))) # the line starts at the left corner of the rectangle and is not perpendicular to any of the rectangle sides; # the line ends outside of the rectangle, not going through it self.assertFalse(PathFinding.intersects(rect, QLineF(rect.topLeft(), QPointF(-100, -100)))) # the line starts at the left corner of the rectangle and is perpendicular to the top side of the rectangle; # the line ends outside of the rectangle, not going through it self.assertFalse(PathFinding.intersects(rect, QLineF(rect.topLeft(), QPointF(rect.left(), rect.top() - 100)))) # the line is horizontal and goes straight through the center of the rectangle self.assertTrue(PathFinding.intersects(rect, QLineF(QPointF(-100, 0), QPointF(100, 0)))) # the line is vertical and goes straight through the center of the rectangle self.assertTrue(PathFinding.intersects(rect, QLineF(QPointF(0, -100), QPointF(0, 100)))) # the line is vertical and goes up from the bottom right corner of the rectangle self.assertFalse(PathFinding.intersects(rect, QLineF(rect.bottomRight(), QPointF(rect.right(), rect.top()-100)))) # the line is diagonal of the rectangle self.assertTrue(PathFinding.intersects(rect, QLineF(rect.topLeft(), rect.bottomRight())))
def getCircleFromPoints(self, pts): center = pts[0] r = pts[1] - pts[0] d = math.sqrt(math.pow(r.x(), 2) + math.pow(r.y(), 2)) rectangle = QRectF(center.x() - d, center.y() - d, 2 * d, 2 * d) return rectangle
def boundingRect(self): """Override.""" if self._picture is None: self.drawPicture() return QRectF(self._picture.boundingRect())
def paintEvent(self, _event: QPaintEvent): if not self.crop or not self.resolution: return painter = QPainter(self) # Keep a backup of the transform and create a new one transform = painter.worldTransform() # Set scaling transform transform = transform.scale(self.width() / self.resolution.width(), self.height() / self.resolution.height()) # Compute the transform to flip the coordinate system on the x axis transform_flip = QTransform() if self.flip_x: transform_flip = transform_flip.translate(self.resolution.width(), 0.0) transform_flip = transform_flip.scale(-1.0, 1.0) # Small helper for tuple to QPoint def toqp(point): return QPoint(point[0], point[1]) # Starting from here we care about AA painter.setRenderHint(QPainter.Antialiasing) # Draw the QR code finder overlay painter.setWorldTransform(transform_flip * transform, False) painter.setOpacity(self.QR_FINDER_OPACITY) qr_finder_size = self.crop.size() * self.QR_FINDER_SIZE tmp = (self.crop.size() - qr_finder_size) / 2 qr_finder_pos = QPoint(tmp.width(), tmp.height()) + self.crop.topLeft() qr_finder_rect = QRect(qr_finder_pos, qr_finder_size) self.qr_finder.render(painter, QRectF(qr_finder_rect)) painter.setOpacity(1.0) # Draw all the QR code results for res in self.results: painter.setWorldTransform(transform_flip * transform, False) # Draw lines between all of the QR code points pen = QPen(self.qr_outline_pen) if res in self.validator_results.result_colors: pen.setColor(self.validator_results.result_colors[res]) painter.setPen(pen) num_points = len(res.points) for i in range(0, num_points): i_n = i + 1 line_from = toqp(res.points[i]) line_from += self.crop.topLeft() line_to = toqp( res.points[i_n] if i_n < num_points else res.points[0]) line_to += self.crop.topLeft() painter.drawLine(line_from, line_to) # Draw the QR code data # Note that we reset the world transform to only the scaled transform # because otherwise the text could be flipped. We only use transform_flip # to map the center point of the result. painter.setWorldTransform(transform, False) font_metrics = painter.fontMetrics() data_metrics = QSize(font_metrics.horizontalAdvance(res.data), font_metrics.capHeight()) center_pos = toqp(res.center) center_pos += self.crop.topLeft() center_pos = transform_flip.map(center_pos) text_offset = QPoint(data_metrics.width(), data_metrics.height()) text_offset = text_offset / 2 text_offset.setX(-text_offset.x()) center_pos += text_offset padding = self.BG_RECT_PADDING bg_rect_pos = center_pos - QPoint(padding, data_metrics.height() + padding) bg_rect_size = data_metrics + (QSize(padding, padding) * 2) bg_rect = QRect(bg_rect_pos, bg_rect_size) bg_rect_path = QPainterPath() radius = self.BG_RECT_CORNER_RADIUS bg_rect_path.addRoundedRect(QRectF(bg_rect), radius, radius, Qt.AbsoluteSize) painter.setPen(self.bg_rect_pen) painter.fillPath(bg_rect_path, self.bg_rect_fill) painter.drawPath(bg_rect_path) painter.setPen(self.text_pen) painter.drawText(center_pos, res.data)
def _selectedRect(self): if self._p1 is None or self._p2 is None: return QRectF(0, 0, 0, 0) rect = QRectF(QPoint(*self._p1), QPoint(*self._p2)) return rect.intersected(self._mask_rect)
def _itemsAt(self, func, obj, justOne=True): """ Go through all anchors, points and components (in this order) in the glyph, construct their canvas path and list items for which *func(path, obj)* returns True, or only return the first item if *justOne* is set to True. An item is a (point, contour) or (anchor, None) or (component, None) tuple. The second argument permits accessing parent contour to post notifications. Here is a sample *func* function that tests whether item with path *path* contains *pos*: def myFunction(path, pos): return path.contains(pos) This is useful to find out whether an item was clicked on canvas. """ scale = self._inverseScale # TODO: export this from drawing or use QSettings. # XXX: outdated # anchor anchorSize = 7 * scale anchorHalfSize = anchorSize / 2 # offCurve offSize = 5 * scale offHalf = offSize / 2 offStrokeWidth = 2.5 * scale # onCurve onSize = 6.5 * scale onHalf = onSize / 2 onStrokeWidth = 1.5 * scale # onCurve smooth smoothSize = 8 * scale smoothHalf = smoothSize / 2 # guideline pt guidelineStrokeWidth = 1 * scale if not justOne: ret = dict( anchors=[], points=[], components=[], guidelines=[], image=None, ) if self._glyph is None: if justOne: return None return ret flags = GlyphFlags(True) # anchors if self.drawingAttribute("showGlyphAnchors", flags): for anchor in reversed(self._glyph.anchors): path = QPainterPath() path.addEllipse(anchor.x - anchorHalfSize, anchor.y - anchorHalfSize, anchorSize, anchorSize) if func(path, obj): if justOne: return anchor ret["anchors"].append(anchor) # points if self.drawingAttribute("showGlyphOnCurvePoints", flags): for contour in reversed(self._glyph): for index, point in enumerate(contour): path = QPainterPath() if point.segmentType is None: x = point.x - offHalf y = point.y - offHalf path.addEllipse(x, y, offSize, offSize) strokeWidth = offStrokeWidth else: if point.smooth: x = point.x - smoothHalf y = point.y - smoothHalf path.addEllipse(x, y, smoothSize, smoothSize) else: x = point.x - onHalf y = point.y - onHalf path.addRect(x, y, onSize, onSize) strokeWidth = onStrokeWidth path = _shapeFromPath(path, strokeWidth) if func(path, obj): if justOne: return (contour, index) ret["points"].append((contour, index)) # components for component in reversed(self._glyph.components): path = component.getRepresentation("TruFont.QPainterPath") if func(path, obj): if justOne: return component ret["components"].append(component) # guideline # TODO: we should further dispatch with showFontGuidelines, # although both are bind in the UI if self.drawingAttribute("showGlyphGuidelines", flags): for guideline in UIGlyphGuidelines(self._glyph): if None not in (guideline.x, guideline.y): # point x = guideline.x - smoothHalf y = guideline.y - smoothHalf path = QPainterPath() path.addEllipse(x, y, smoothSize, smoothSize) path = _shapeFromPath(path, guidelineStrokeWidth) if func(path, obj): if justOne: return guideline ret["guidelines"].append(guideline) # TODO: catch line if selected # image if self.drawingAttribute("showGlyphImage", flags): image = self._glyph.image pixmap = image.getRepresentation("defconQt.QPixmap") if pixmap is not None: path = QPainterPath() transform = QTransform(*image.transformation) rect = transform.mapRect(QRectF(pixmap.rect())) path.addRect(*rect.getCoords()) if func(path, obj): if justOne: return image ret["image"] = image if not justOne: return ret return None
def resetMask(cls): cls._mask = None cls._mask_rect = QRectF(0, 0, 0, 0)
def add_relation(self, x, r): if (len(r.attrib_list) != 0): self.level += self.rel_height / 2 + self.r_atr_h * ( len(r.attrib_list) - 1) + self.r_atr_line Qpoints = [ QPointF(x, self.level), QPointF(x + self.rel_width / 2, self.level + self.rel_height / 2), QPointF(x + self.rel_width, self.level), QPointF(x + self.rel_width / 2, self.level - self.rel_height / 2) ] rel_shape = self.scene.addPolygon(QPolygonF(Qpoints), self.rel_pen, self.rel_Brush) rel_name = self.scene.addWidget(QLineEdit()) left_p = self.scene.addWidget(QLineEdit()) right_p = self.scene.addWidget(QLineEdit()) #rel_name.setParentItem(rel_shape) rel_name.setGeometry(QRectF(0, 0, self.rel_width / 2, 3)) left_p.setGeometry(QRectF(0, 0, 0, 0)) right_p.setGeometry(QRectF(0, 0, 0, 0)) left_p.widget().setFixedWidth(43) right_p.widget().setFixedWidth(43) rel_name.setPos(x + self.rel_width / 4, self.level - rel_name.widget().height() / 2) left_p.setPos(x - left_p.widget().width(), self.level - left_p.widget().height()) right_p.setPos(x + self.rel_width, self.level - right_p.widget().height()) rel_name.widget().setText(r.name) left_p.widget().setText(r.p_ratio1) right_p.widget().setText(r.p_ratio2) rel_name.widget().editingFinished.connect( partial(self.mod, "n", r, rel_name.widget())) left_p.widget().editingFinished.connect( partial(self.mod, "l", r, left_p.widget())) right_p.widget().editingFinished.connect( partial(self.mod, "r", r, right_p.widget())) atr_step = ((self.rel_width - 2 * right_p.widget().width() - 10) / (len(r.attrib_list) - 1)) if len(r.attrib_list) > 1 else 0 ten = (Qpoints[0].y() - Qpoints[3].y()) / (Qpoints[0].x() - Qpoints[3].x()) for i in range(len(r.attrib_list)): first_pt = QPointF( Qpoints[0].x() + i * atr_step + right_p.widget().width() + 10, self.get_y_line( Qpoints[0].x() + i * atr_step + right_p.widget().width() + 10, Qpoints[0], ten)) if (first_pt.x() > Qpoints[3].x()): first_pt.setY( self.get_y_line(first_pt.x(), Qpoints[3], -1 * ten)) atr_line = self.scene.addLine( first_pt.x(), first_pt.y(), first_pt.x(), Qpoints[3].y() - self.r_atr_line - i * self.r_atr_h) elip_pt = QPointF(first_pt.x() - self.r_atr_w / 2, atr_line.line().y2() - self.r_atr_h) atr_elipse = self.scene.addEllipse( QRectF(0, 0, self.r_atr_w, self.r_atr_h), self.rel_pen, self.rel_Brush) txt = [] txt.append(self.scene.addWidget(QLineEdit(r.attrib_list[i].name))) atr_elipse.setPos(elip_pt) txt[-1].setPos(elip_pt.x() + self.rel_width * 0.25, elip_pt.y() + self.r_atr_h * 0.125) txt[-1].widget().setFixedWidth(self.r_atr_w * 0.5) txt[-1].widget().setFixedHeight(self.r_atr_h * 0.75) txt[-1].widget().editingFinished.connect( partial(self.mod, "c", r, txt[-1].widget(), i))
def __init__(self): super().__init__(QRectF(0, 0, 500, 180), QColor(179, 179, 255, 235)) self.setPos(-250, -90) self.setZValue(10) self.setOpacity(0)
def __init__(self, entity, pos, scene): self.entity_width = 180 self.entity_height = 80 self.entity_pen = QPen(Qt.black, 5, Qt.SolidLine) self.entity_brush = QBrush(Qt.green, Qt.SolidPattern) self.attribute_width = 90 self.attribute_height = 50 self.attribute_pen = QPen(Qt.black, 3, Qt.SolidLine) self.attribute_brush = QBrush(Qt.blue, Qt.Dense6Pattern) self.at_connection_pen = QPen(Qt.black, 3, Qt.SolidLine) self.entity = entity self.no_atr = len(self.entity.attr_list) self.inter_atr_margin = 15 self.min_height = -50 self.container_width = self.entity_width + self.attribute_width self.container_height = -1 * self.min_height * self.no_atr + self.attribute_height self.en_shape = scene.addRect( QRectF(0, 0, self.entity_width, self.entity_height), self.entity_pen, self.entity_brush) self.txt_style = ''' QWidget{border:3px dashed black;padding-bottom:5px;} ''' self.txt_en_geometry = QRectF(0.0, 0.0, self.entity_width / 2, self.entity_height / 2) self.txt_atr_geometry = QRectF(0.0, 0.0, self.attribute_width / 2, self.attribute_height / 2) self.txt_atr_child_geometry = QRectF(0.0, 0.0, self.attribute_width / 2, self.attribute_height / 2) self.txt_atr_pos = QPointF(self.attribute_width / 4, self.attribute_height / 4) self.txt_en_pos = QPointF(self.entity_width / 4, self.entity_height / 4) self.en_txt = scene.addWidget(QLineEdit()) self.en_txt.setParentItem(self.en_shape) self.en_txt.setGeometry(self.txt_en_geometry) self.en_txt.widget().setStyleSheet(self.txt_style) self.en_txt.widget().setText(self.entity.name) self.en_txt.setPos(self.txt_en_pos) self.en_txt.widget().editingFinished.connect( lambda: ContainerItem.trial(self, -1, self.en_txt.widget(), 0)) self.scene = scene self.en_shape.setPos(pos) self.con_list = [] self.atr_shape_list = [] self.atr_txt_list = [] self.rel_orgn = QPointF(0, self.entity_height) self.orgn_step = 15 self.id = 0 if (self.no_atr > 1): self.atr_step = self.entity_width / (self.no_atr - 1) if (2 * self.atr_step < self.attribute_width): self.attribute_width = 2 * self.atr_step - self.inter_atr_margin self.txt_atr_geometry = QRectF(0.0, 0.0, self.attribute_width / 2, self.attribute_height / 2) for i in range(0, self.no_atr): self.attach_attribute( QLineF(self.atr_step * i, 0, self.atr_step * i, self.min_height - i * self.attribute_height), self.entity.attr_list[i].name, i, self.entity.attr_list[i].type, self.en_shape, self.attribute_width, self.attribute_height, self.txt_atr_geometry, -1) if (self.entity.attr_list[i].isComposite): no_child = len(self.entity.attr_list[i].attrib_childs) if (no_child > 1): ch_step = self.attribute_width / ( len(self.entity.attr_list[0].attrib_childs) - 1) else: ch_step = self.attribute_width par_x = self.atr_step * i - self.attribute_width / 2 par_y = self.min_height - i * self.attribute_height - self.attribute_height for j in range(0, no_child): self.attach_attribute( QLineF( par_x + (ch_step) * j, self.get_y_elipse( par_x + (ch_step) * j, par_x + self.attribute_width / 2, par_y + self.attribute_height / 2), par_x + ch_step * j, par_y + self.min_height / 2 - j * self.attribute_height * 0.75), self.entity.attr_list[i].attrib_childs[j].name, i, self.entity.attr_list[i].attrib_childs[j].type, self.en_shape, self.attribute_width * 0.75, self.attribute_height * 0.75, self.txt_atr_child_geometry, j) child_height = -1 * par_y - 1 * self.min_height + no_child * 0.75 * self.attribute_height if (child_height > self.container_height): self.container_height = child_height elif (self.no_atr == 1): self.attach_attribute(QLineF(0, 0, 0, self.min_height), self.entity.attr_list[0].name, 0, 'prime', self.en_shape, self.attribute_width, self.attribute_height, self.txt_atr_geometry, -1) if (self.entity.attr_list[0].isComposite): no_child = len(self.entity.attr_list[0].attrib_childs) if (no_child > 1): ch_step = self.attribute_width / ( len(self.entity.attr_list[0].attrib_childs) - 1) else: ch_step = self.attribute_width par_x = 0 - self.attribute_width / 2 par_y = 0 + self.min_height - self.attribute_height for j in range(0, no_child): self.attach_attribute( QLineF( par_x + (ch_step) * j, self.get_y_elipse( par_x + (ch_step) * j, 0, self.min_height - self.attribute_height / 2), par_x + ch_step * j, par_y + self.min_height / 2 - j * self.attribute_height * 0.75), self.entity.attr_list[0].attrib_childs[j].name, 0, self.entity.attr_list[0].attrib_childs[j].type, self.en_shape, self.attribute_width * 0.75, self.attribute_height * 0.75, self.txt_atr_child_geometry, j) self.id += 1 self.container_height += self.attribute_height / 2 + -1 * self.min_height / 2 - j * self.attribute_height / 2 + 10 child_height = -1 * par_y - 1 * self.min_height + no_child * 0.75 * self.attribute_height if (child_height > self.container_height): self.container_height = child_height
def _updateAppearance(self, strand: StrandT): """Prepare Strand for drawing, positions are relative to the :class:`PathVirtualHelixItem`: 1. Show or hide caps depending on L and R connectivity. 2. Determine line coordinates. 3. Apply paint styles. """ # 0. Setup vhi = self._virtual_helix_item bw = _BASE_WIDTH half_base_width = bw / 2.0 low_idx, high_idx = strand.lowIdx(), strand.highIdx() l_upper_left_x, l_upper_left_y = vhi.upperLeftCornerOfBase( low_idx, strand) h_upper_left_x, h_upper_left_y = vhi.upperLeftCornerOfBase( high_idx, strand) low_cap = self._low_cap high_cap = self._high_cap dual_cap = self._dual_cap # 1. Cap visibilty lx = l_upper_left_x + bw # draw from right edge of base low_cap.safeSetPos(l_upper_left_x, l_upper_left_y) if strand.connectionLow() is not None: # has low xover # if we are hiding it, we might as well make sure it is reparented to the StrandItem low_cap.restoreParent() low_cap.hide() else: # has low cap if not low_cap.isVisible(): low_cap.show() hx = h_upper_left_x # draw to edge of base high_cap.safeSetPos(h_upper_left_x, h_upper_left_y) if strand.connectionHigh() is not None: # has high xover # if we are hiding it, we might as well make sure it is reparented to the StrandItem high_cap.restoreParent() high_cap.hide() else: # has high cap if not high_cap.isVisible(): high_cap.show() # special case: single-base strand with no L or H connections, # (unconnected caps were made visible in previous block of code) if strand.length() == 1 and (low_cap.isVisible() and high_cap.isVisible()): low_cap.hide() high_cap.hide() dual_cap.safeSetPos(l_upper_left_x, l_upper_left_y) dual_cap.show() else: dual_cap.hide() # 2. Xover drawing xo = self.xover_3p_end if strand.connection3p(): xo.update(strand) xo.showIt() else: xo.restoreParent() xo.hideIt() # 3. Refresh insertionItems if necessary drawing self.refreshInsertionItems(strand) # 4. Line drawing hy = ly = l_upper_left_y + half_base_width self.setLine(lx, ly, hx, hy) rectf = QRectF(l_upper_left_x + bw, l_upper_left_y, bw * (high_idx - low_idx - 1), bw) self._click_area.setRect(rectf) self._updateColor(strand)
if not args: logger.error("no coordinate set...") return if len(args) == 1: self.moveTo(args[0].x(), args[0].y()) else: self.moveTo(QPointF(args[0], args[1])) def get_P1(self): return QPointF(self.x(), self.y()) if __name__ == '__main__': # ça marche --> voici deux examples de shapes test = Rect2D(0, 0, 100, 100) rect = QRectF(0,0, 125,256) print(rect.x()) print(rect.y()) print(rect.width()) print(rect.height()) rect.translate(10,20) # ça marche print(rect) (test.x(), test.y(), test.width(), test.height()) print(test.contains(QPointF(50, 50))) print(test.contains(QPointF(-1, -1))) print(test.contains(QPointF(0, 0)))