def _newAxes(self): """Given self._rotation and self._swapped, calculates and sets the appropriate data2scene transformation. """ # TODO: this function works, but it is not elegant. There must # be a simpler way to calculate the appropriate tranformation. w, h = self.dataShape assert self._rotation in range(0, 4) # unlike self._rotation, the local variable 'rotation' # indicates how many times to rotate clockwise after swapping # axes. # t1 : do axis swap t1 = QTransform() if self._swapped: t1 = QTransform(0, 1, 0, 1, 0, 0, 0, 0, 1) h, w = w, h # t2 : do rotation t2 = QTransform() t2.rotate(self._rotation * 90) # t3: shift to re-center rot2trans = {0: (0, 0), 1: (h, 0), 2: (w, h), 3: (0, w)} trans = rot2trans[self._rotation] t3 = QTransform.fromTranslate(*trans) self.data2scene = t1 * t2 * t3 if self._tileProvider: self._tileProvider.axesSwapped = self._swapped self.axesChanged.emit(self._rotation, self._swapped)
def testData2Scene(self): t = Tiling((0, 0)) trans = QTransform() t.data2scene = trans self.assertEquals(trans, t.data2scene) # try using transformation that is not invertible trans = QTransform(1, 1, 1, 1, 1, 1) with self.assertRaises(AssertionError): t.data2scene = trans
def setLeftHanded(self, bValue): """Configure the neck as left or right-handed. bValue -- bool, if True, mirror the neck Return None. """ if bValue: self.setTransform(QTransform().scale(-1, 1)) else: self.setTransform(QTransform().scale(1, 1))
def _refreshTile( self, stack_id, tile_no, prefetch=False ): if not self.axesSwapped: transform = QTransform(0,1,0,1,0,0,1,1,1) else: transform = QTransform().rotate(90).scale(1,-1) transform *= self.tiling.data2scene try: if self._cache.tileDirty( stack_id, tile_no ): if not prefetch: self._cache.setTileDirty(stack_id, tile_no, False) img = self._renderTile( stack_id, tile_no ) self._cache.setTile(stack_id, tile_no, img, self._sims.viewVisible(), self._sims.viewOccluded()) # refresh dirty layer tiles for ims in self._sims.viewImageSources(): if self._cache.layerDirty(stack_id, ims, tile_no) \ and not self._sims.isOccluded(ims) \ and self._sims.isVisible(ims): rect = self.tiling.imageRects[tile_no] dataRect = self.tiling.scene2data.mapRect(rect) ims_req = ims.request(dataRect, stack_id[1]) if ims.direct and not prefetch: # The ImageSource 'ims' is fast (it has the # direct flag set to true) so we process # the request synchronously here. This # improves the responsiveness for layers # that have the data readily available. start = time.time() img = ims_req.wait() img = img.transformed(transform) stop = time.time() ims._layer.timePerTile(stop-start, self.tiling.imageRects[tile_no]) self._cache.updateTileIfNecessary( stack_id, ims, tile_no, time.time(), img ) img = self._renderTile( stack_id, tile_no ) self._cache.setTile(stack_id, tile_no, img, self._sims.viewVisible(), self._sims.viewOccluded() ) else: pool = get_render_pool() pool.submit(prefetch, time.time(), self, ims, transform, tile_no, stack_id, ims_req, self._cache) except KeyError: pass
def __init__(self, undo_stack, delete_act, sel_actions, *args): """ Constructor """ params = parameters.instance QGraphicsScene.__init__(self, *args) self.delete_act = delete_act self.undo_stack = undo_stack self.data_manager = None self._mode = None self.link = None self.image_path = None self.image_name = None self.background_image = None self.template = TemplateItem() self.template.setPos(QPointF(0, 0)) self.template.setVisible(params.show_template) self.show_template = False self.points = {} self.cells = {} self._real_scene_rect = QRectF() params.pointParameterChange.connect(self.updatePoints) params.cellParameterChange.connect(self.updateCells) params.searchParameterChange.connect(self.updateTemplate) self.had_selection = None self.selectionChanged.connect(self.updateSelectionActions) self.current_data = None self.back_matrix = QTransform() self.invert_back_matrix = QTransform() self.clear() popup = QMenu("Scene menu") validate_cell_act = popup.addAction("Validate cell", self.validateCell) validate_cell_act.setVisible(False) self._validate_cell_act = validate_cell_act lifespan_act = popup.addAction("Change cell lifespan", self.changeLifespan) lifespan_act.setVisible(False) self.lifespan_act = lifespan_act make_starshape_act = popup.addAction("Make cell star shaped", self.makeCellStarshaped) make_starshape_act.setVisible(False) self.make_starshape_act = make_starshape_act sel = popup.addMenu("Selection") for act in sel_actions: if act == "-": sel.addSeparator() else: sel.addAction(act) popup.addAction(delete_act) self._popup = popup self._sel_rect = None self._sel_first_pt = None self._current_cell = None self._first_point = None self.mode = TrackingScene.Pan
def transform(self): try: return self.__dict__['transform'] if self.scale else QTransform() except KeyError: transform = QTransform() image = self.client.image if image is not None and not image.isNull(): scale = min(self.width() / image.width(), self.height() / image.height()) transform.translate( (self.width() - image.width() * scale) / 2, (self.height() - image.height() * scale) / 2) transform.scale(scale, scale) transform = self.__dict__.setdefault('transform', transform) return transform
def _plat_get_blocks(self, block_count_per_side, orientation): image = QImage(str(self.path)) image = image.convertToFormat(QImage.Format_RGB888) # MYSTERY TO SOLVE: For reasons I cannot explain, orientations 5 and 7 don't work for # duplicate scanning. The transforms seems to work fine (if I try to save the image after # the transform, we see that the image has been correctly flipped and rotated), but the # analysis part yields wrong blocks. I spent enought time with this feature, so I'll leave # like that for now. (by the way, orientations 5 and 7 work fine under Cocoa) if 2 <= orientation <= 8: t = QTransform() if orientation == 2: t.scale(-1, 1) elif orientation == 3: t.rotate(180) elif orientation == 4: t.scale(1, -1) elif orientation == 5: t.scale(-1, 1) t.rotate(90) elif orientation == 6: t.rotate(90) elif orientation == 7: t.scale(-1, 1) t.rotate(270) elif orientation == 8: t.rotate(270) image = image.transformed(t) return getblocks(image, block_count_per_side)
def paint(self, painter, option, widget): params = parameters.instance tr = painter.worldMatrix() saved = False scale = self.scale ms = min(scale) if tr.m11() < 1 / scale[0] or tr.m12() < 1 / scale[1]: painter.save() saved = True dx = tr.dx() dy = tr.dy() painter.setWorldTransform( QTransform(1 / scale[0], 0, 0, 1 / scale[1], dx, dy)) if self.hover: pen_color = params.old_point_matching_color else: pen_color = params.old_point_color half_size = params.old_point_size / 2. pen = QPen(pen_color) pen.setWidth(params.old_point_thickness * ms) painter.setPen(pen) painter.drawLine(0, -half_size * scale[1], 0, half_size * scale[1]) painter.drawLine(-half_size * scale[0], 0, half_size * scale[0], 0) if saved: painter.restore()
def add_line(self, cord_1, cord_2, color): key = tuple(sorted([tuple(cord_1), tuple(cord_2)])) x = min(cord_1[0], cord_2[0]) y = min(cord_1[1], cord_2[1]) if key in self.lines: print("ERROR: Line between {} and {} already added.".format( cord_1, cord_2)) else: line = QLabel(self) if color == "white": pixmap = QPixmap(get_asset_path("hor_line_white")) else: pixmap = QPixmap(get_asset_path("hor_line_black")) c1 = (30 + cord_1[0] * 30, 30 + cord_1[1] * 30) c2 = (30 + cord_2[0] * 30, 30 + cord_2[1] * 30) length = ((c1[0] - c2[0])**2 + (c1[1] - c2[1])**2)**(1 / 2) angle = math.degrees( math.atan2(key[1][1] - key[0][1], key[1][0] - key[0][0])) pixmap = pixmap.scaled(length, 5) pixmap = pixmap.transformed(QTransform().rotate(angle)) line.setPixmap(pixmap) line.move(30 + x * 30, 30 + y * 30) line.show() line.lower() self.lines[key] = line
def rotateCenter(item, angle): """rotates a QGraphicsItem around its center""" center = item.boundingRect().center() centerX, centerY = center.x() * item.scale(), center.y() * item.scale() item.setTransform(QTransform().translate( centerX, centerY).rotate(angle).translate(-centerX, -centerY)) return item
def __updateText(self): self.prepareGeometryChange() if self.__sourceName or self.__sinkName: if self.__sourceName != self.__sinkName: text = u"{0} \u2192 {1}".format(self.__sourceName, self.__sinkName) else: # If the names are the same show only one. # Is this right? If the sink has two input channels of the # same type having the name on the link help elucidate # the scheme. text = self.__sourceName else: text = "" self.linkTextItem.setPlainText(text) path = self.curveItem.path() if not path.isEmpty(): center = path.pointAtPercent(0.5) angle = path.angleAtPercent(0.5) brect = self.linkTextItem.boundingRect() transform = QTransform() transform.translate(center.x(), center.y()) transform.rotate(-angle) # Center and move above the curve path. transform.translate(-brect.width() / 2, -brect.height()) self.linkTextItem.setTransform(transform)
def __init__(self, sliceShape, data2scene=QTransform(), blockSize=256, overlap=0, overlap_draw=1e-3, name="Unnamed Tiling"): self.blockSize = blockSize self.overlap = overlap self._patchAccessor = PatchAccessor(sliceShape[0], sliceShape[1], blockSize=self.blockSize) self._overlap_draw = overlap_draw self._overlap = overlap numPatches = self._patchAccessor.patchCount self.imageRectFs = [None] * numPatches self.dataRectFs = [None] * numPatches self.tileRectFs = [None] * numPatches self.imageRects = [None] * numPatches self.dataRects = [None] * numPatches self.tileRects = [None] * numPatches self.sliceShape = sliceShape self.name = name self.data2scene = data2scene
def __init__(self, sliceShape, data2scene=QTransform(), blockSize=512, overlap=0, overlap_draw=1e-3, name="Unnamed Tiling"): """ Args: sliceShape -- (width, height) data2scene -- QTransform from data to image coordinates (default: identity transform) blockSize -- base tile size: blockSize x blockSize (default 256) overlap -- overlap between tiles positive number prevents rendering artifacts between tiles for certain zoom levels (default 1) """ self.blockSize = blockSize self.overlap = overlap self._patchAccessor = PatchAccessor(sliceShape[0], sliceShape[1], blockSize=self.blockSize) self._overlap_draw = overlap_draw self._overlap = overlap numPatches = self._patchAccessor.patchCount self.imageRectFs = [None]*numPatches self.dataRectFs = [None]*numPatches self.tileRectFs = [None]*numPatches self.imageRects = [None]*numPatches self.dataRects = [None]*numPatches self.tileRects = [None]*numPatches self.sliceShape = sliceShape self.name = name self.data2scene = data2scene
def _resetIcon(self): if self._swapped: pixmap = self._pixmap_swapped else: pixmap = self._orig_pixmap transform = QTransform().rotate(self._rotation * 90) self.setPixmap(pixmap.transformed(transform))
def paintEvent(self, event): """QToolBar.paintEvent reimplementation Draws buttons, dock icon and text """ rect = self._spacer.rect() painter = QPainter(self) transform = QTransform() transform.translate(self._spacer.pos().x(), self._spacer.pos().y()) painter.setTransform(transform) """ Not supported currently if self._dock.features() & QDockWidget.DockWidgetVerticalTitleBar : transform = QTransform() rect.setSize(QSize(rect.height(), rect.width())) transform.rotate(-90) transform.translate(-rect.width(), 0) painter.setTransform(transform) """ # icon / title optionB = QStyleOptionButton() optionB.initFrom(self._dock) optionB.rect = rect optionB.text = self._dock.windowTitle() optionB.iconSize = self.iconSize() optionB.icon = self._dock.windowIcon() self.style().drawControl(QStyle.CE_PushButtonLabel, optionB, painter, self._dock)
def paintEvent(self, event): painter = QPainter(self) painter.fillRect(self.rect(), QColor('#101010')) image = self._image if image is not None: if self.height() < 240: fast_scaler = QTransform() scale = 297 / image.height() if self.mirror: fast_scaler.scale(-scale, scale) else: fast_scaler.scale(scale, scale) rect = event.rect() painter.drawPixmap( rect, QPixmap.fromImage( image.transformed(fast_scaler)).scaledToHeight( self.height(), Qt.SmoothTransformation), rect) else: transform = QTransform() scale = min(self.width() / image.width(), self.height() / image.height()) if self.mirror: transform.translate( (self.width() + image.width() * scale) / 2, (self.height() - image.height() * scale) / 2) transform.scale(-scale, scale) else: transform.translate( (self.width() - image.width() * scale) / 2, (self.height() - image.height() * scale) / 2) transform.scale(scale, scale) inverse_transform, invertible = transform.inverted() rect = inverse_transform.mapRect(event.rect()).adjusted( -1, -1, 1, 1).intersected(image.rect()) painter.setTransform(transform) if self.height() > 400: painter.drawPixmap(rect, QPixmap.fromImage(image), rect) else: painter.drawImage(rect, image, rect) painter.end()
def updatePixmap(self): path = _PATH + os.sep + "assets" + os.sep + self._base_image self.__pixmap = QPixmap(path) self.__pixmap = self.__pixmap.scaled(self.__pixmap.width() * _SCALE, self.__pixmap.height() * _SCALE) self.__pixmap = self.__pixmap.transformed(QTransform().rotate( self.angle)) self._base_label.setPixmap(self.__pixmap)
def setZoom(self, x, y): self.zx = x self.zy = y trans = QTransform() trans.scale(self.zx, self.zy) self.setTransform(trans) for vert in self.vertItems: vert.updateZoom(self.zx, self.zy)
def updatePixmap(self): path = get_asset_path(self._base_image) self.__pixmap = QPixmap(path) self.__pixmap = self.__pixmap.scaled(self._size[0], self._size[1]) self.__pixmap = self.__pixmap.transformed(QTransform().rotate( self.angle)) self._base_label.setPixmap(self.__pixmap) self._base_label.show()
def flip_vt(self): for obj in self.childItems(): rect = obj.boundingRect() x = rect.width() / 2 y = rect.height() / 2 obj.setTransform(QTransform().translate(x, y).scale(1, -1).translate( -x, -y))
def updateZoom(self, zx, zy): trans = QTransform() trans.scale(1.0 / zx, 1.0 / zy) # self.setTransform( trans ) self.VP.setTransform(trans) self.preBP.setTransform(trans) self.postBP.setTransform(trans) self.updateTPPos()
def rotate(self, rotation): "rotates item over its own center" for obj in self.childItems(): if hasattr(obj, "rotable") and obj.rotable: rect = obj.boundingRect() x = rect.width() / 2 y = rect.height() / 2 obj.setTransform(QTransform().translate( x, y).rotate(rotation).translate(-x, -y))
def _updateLayout(self): rect = self.geometry() n = len(self._items) if not n: return regions = venn_diagram(n, shape=self.shapeType) # The y axis in Qt points downward transform = QTransform().scale(1, -1) regions = list(map(transform.map, regions)) union_brect = reduce(QRectF.united, (path.boundingRect() for path in regions)) scalex = rect.width() / union_brect.width() scaley = rect.height() / union_brect.height() scale = min(scalex, scaley) transform = QTransform().scale(scale, scale) regions = [transform.map(path) for path in regions] center = rect.width() / 2, rect.height() / 2 for item, path in zip(self.items(), regions): item.setPath(path) item.setPos(*center) intersections = venn_intersections(regions) assert len(intersections) == 2**n assert len(self.vennareas()) == 2**n anchors = [(0, 0)] + subset_anchors(self._items) anchor_transform = QTransform().scale(rect.width(), -rect.height()) for i, area in enumerate(self.vennareas()): area.setPath(intersections[setkey(i, n)]) area.setPos(*center) x, y = anchors[i] anchor = anchor_transform.map(QPointF(x, y)) area.setTextAnchor(anchor) area.setZValue(30) self._updateTextAnchors()
def updateTransfrom(self): if self.updating: return self.updating = True trans = QTransform() trans.translate( self.valueToX(-self.scrollX) + self.offsetX, self.valueToY(-self.scrollY)) self.setTransform(trans) self.update() self.updating = False
def paint(self, painter, option, widget=None): t = painter.transform() rect = t.mapRect(self.rect()) painter.save() painter.setTransform(QTransform()) pwidth = self.pen().widthF() painter.setPen(self.pen()) painter.drawRect(rect.adjusted(pwidth, -pwidth, -pwidth, pwidth)) painter.restore()
def __init__(self): Curve.__init__(self) self.d_points = QPolygonF() self.setStyle( Qwt.QwtPlotCurve.Lines ) self.setPen( Qt.red, 2 ) self.initSamples() # somewhere in the center transform = QTransform() transform.translate( 7.0, 3.0 ) transform.scale( 1.5, 1.5 ) self.setTransformation( transform )
def add_decoration(self, path): if path is None: self._decor_label.hide() else: self._decor_label = QLabel(self) self._decor_pixmap = QPixmap(path) self._decor_pixmap = self._decor_pixmap.scaled( self._decor_pixmap.width() * _SCALE, self._decor_pixmap.height() * _SCALE) self._decor_pixmap = self._decor_pixmap.transformed( QTransform().rotate(self.angle)) self._decor_label.setPixmap(self._decor_pixmap)
def __init__(self, id, title='', title_above=False, title_location=AxisMiddle, line=None, arrows=0, plot=None, bounds=None): QGraphicsItem.__init__(self) self.setFlag(QGraphicsItem.ItemHasNoContents) self.setZValue(AxisZValue) self.id = id self.title = title self.title_location = title_location self.data_line = line self.plot = plot self.graph_line = None self.size = None self.scale = None self.tick_length = (10, 5, 0) self.arrows = arrows self.title_above = title_above self.line_item = QGraphicsLineItem(self) self.title_item = QGraphicsTextItem(self) self.end_arrow_item = None self.start_arrow_item = None self.show_title = False self.scale = None path = QPainterPath() path.setFillRule(Qt.WindingFill) path.moveTo(0, 3.09) path.lineTo(0, -3.09) path.lineTo(9.51, 0) path.closeSubpath() self.arrow_path = path self.label_items = [] self.label_bg_items = [] self.tick_items = [] self._ticks = [] self.zoom_transform = QTransform() self.labels = None self.values = None self._bounds = bounds self.auto_range = None self.auto_scale = True self.zoomable = False self.update_callback = None self.max_text_width = 50 self.text_margin = 5 self.always_horizontal_text = False
def add_decoration(self, path): if path is None: self._decor_label.deleteLater() self._decor_label = None else: self._decor_label = QLabel(self) self._decor_pixmap = QPixmap(path) # self._decor_pixmap = self._decor_pixmap.scaled(self._size[0], self._size[1]) self._decor_pixmap = self._decor_pixmap.transformed( QTransform().rotate(self.angle)) self._decor_label.setPixmap(self._decor_pixmap) self._decor_label.setAlignment(Qt.AlignCenter) self._decor_label.show()
def ellipse_path(center, a, b, rotation=0): if not isinstance(center, QPointF): center = QPointF(*center) brect = QRectF(-a, -b, 2 * a, 2 * b) path = QPainterPath() path.addEllipse(brect) if rotation != 0: transform = QTransform().rotate(rotation) path = transform.map(path) path.translate(center) return path