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 scene_bbox(item, view=None): """ Returns the bounding box of an item in scene space. If view is given and the object has the QGraphicsItem::ItemIgnoresTransformations flag set, additional steps are taken to compute the exact bounding box of the item. """ bbox = item.boundingRect() if not (item.flags() & QGraphicsItem.ItemIgnoresTransformations): # Normal item, simply map its bounding box to scene space bbox = item.mapRectToScene(bbox) else: # Item with the ItemIgnoresTransformations flag, need to compute its # bounding box with deviceTransform() if view is not None: vp_trans = view.viewportTransform() else: vp_trans = QTransform() item_to_vp_trans = item.deviceTransform(vp_trans) # Map bbox to viewport space bbox = item_to_vp_trans.mapRect(bbox) # Map bbox back to scene space bbox = vp_trans.inverted()[0].mapRect(bbox) return bbox
class Curve1(Curve): def __init__(self): Curve.__init__(self) self.setPen( QColor( 150, 150, 200 ), 2 ) self.setStyle( Qwt.QwtPlotCurve.Lines ) curveFitter = Qwt.QwtSplineCurveFitter() curveFitter.setSplineSize( 150 ) self.setCurveFitter( curveFitter ) self.setCurveAttribute( Qwt.QwtPlotCurve.Fitted, True ) symbol = Qwt.QwtSymbol( Qwt.QwtSymbol.XCross ) symbol.setPen( Qt.yellow ) symbol.setSize( 7 ) self.setSymbol( symbol ) # somewhere to the left self.transform = QTransform() self.transform.scale( 1.5, 1.0 ); self.transform.translate( 1.5, 3.0 ); self.setTransformation( self.transform ) def points(self, phase ): pnts = QPolygonF() numSamples = 15; for i in range(numSamples): v = 6.28 * i / ( numSamples - 1 ) pnts += QPointF( math.sin( v - phase ), v ) return pnts def updateSamples( self, phase ): self.setSamples( self.d_transform.map( self.points( phase )))
def get_nametag(char_id, x, y, color, vertical = False): w = IMG_W h = IMG_H nametag = get_char_name(char_id, common.editor_config.data01_dir) if nametag == None: nametag = "NAMETAG MISSING" if vertical: nametag_img = QImage(h, w, QImage.Format_ARGB32_Premultiplied) new_x = h - y new_y = x x = new_x y = new_y else: nametag_img = QImage(w, h, QImage.Format_ARGB32_Premultiplied) format = TextFormat(x = x, y = y, w = 25, h = 25, align = TEXT_ALIGN.left, orient = TEXT_ORIENT.hor, clt = 0) nametag_img = print_text(nametag_img, nametag, None, format = format, mangle = False) if vertical: matrix = QTransform() matrix.rotate(-90) nametag_img = nametag_img.transformed(matrix) nametag_img = replace_all_colors(nametag_img, color) return nametag_img
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 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 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 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 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 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 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 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 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 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 __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 __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 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
def trigger(self, ui): """ Trigger this animation """ glyph = [ glyph for glyph in ui.scene.items() if hasattr(glyph, 'entity') and glyph.entity == self.mover ][0] if self.direction in (2, 3, 4): self.flipped = True self.offset = 32 if self.direction in (6, 7, 8): self.flipped = False self.offset = 0 if self.flipped: glyph.flipped = True glyph.setTransform(QTransform.fromScale(-1, 1)) else: glyph.flipped = False glyph.setTransform(QTransform.fromScale(1, 1)) if glyph.entity.artificial_intelligence: adapter = MapGlyphAdapter(ui, glyph) else: adapter = MapGlyphAdapter(ui, glyph, True) animation = QParallelAnimationGroup() move_y = QPropertyAnimation(adapter, 'y_location') move_y.setDuration(100) move_y.setStartValue(self.start[1] * 32) move_y.setEndValue(self.destination[1] * 32) move_x = QPropertyAnimation(adapter, 'x_location') move_x.setDuration(100) move_x.setStartValue(self.start[0] * 32 + self.offset) move_x.setEndValue(self.destination[0] * 32 + self.offset) animation.addAnimation(move_y) animation.addAnimation(move_x) ui.animations.append(animation) animation.finished.connect(ui.remove_finished_animation) animation.start()
def __init__(self, *args, **kwargs): QDockWidget.__init__(self, *args, **kwargs) self.__expandedWidget = None self.__collapsedWidget = None self.__expanded = True self.__trueMinimumWidth = -1 self.setFeatures(QDockWidget.DockWidgetClosable | \ QDockWidget.DockWidgetMovable) self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.featuresChanged.connect(self.__onFeaturesChanged) self.dockLocationChanged.connect(self.__onDockLocationChanged) # Use the toolbar horizontal extension button icon as the default # for the expand/collapse button pm = self.style().standardPixmap( QStyle.SP_ToolBarHorizontalExtensionButton ) # Rotate the icon transform = QTransform() transform.rotate(180) pm_rev = pm.transformed(transform) self.__iconRight = QIcon(pm) self.__iconLeft = QIcon(pm_rev) close = self.findChild(QAbstractButton, name="qt_dockwidget_closebutton") close.installEventFilter(self) self.__closeButton = close self.__stack = AnimatedStackedWidget() self.__stack.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self.__stack.transitionStarted.connect(self.__onTransitionStarted) self.__stack.transitionFinished.connect(self.__onTransitionFinished) QDockWidget.setWidget(self, self.__stack) self.__closeButton.setIcon(self.__iconLeft)
def setImageMove(self, scale, pos, angle): log_debug("New scale = %s" % (scale,)) self.scale = scale self.min_scale = self.data_manager.minScale() self.img_scale = (scale[0]/self.min_scale, scale[1]/self.min_scale) back_matrix = QTransform() back_matrix.scale(*self.img_scale) back_matrix.translate(pos.x(), pos.y()) back_matrix.rotate(angle) self.back_matrix = back_matrix rect = back_matrix.mapRect(QRectF(self.background_image.rect())) inv, ok = back_matrix.inverted() if not ok: raise ValueError("The movement is not invertible !?!") self.invert_back_matrix = inv self.real_scene_rect = rect
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 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 data(self, index, role): if not index.isValid(): return QVariant() if index.row() >= len(self.list): return QVariant() if role == Qt.DecorationRole: card = self.list[index.row()] pixmap = card.pixmap() pixmap = pixmap.scaledToHeight(self.preferredCardHeight) if card.tapped: transform = QTransform() transform.rotate(90) pixmap = pixmap.transformed(transform) return pixmap return QVariant()
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 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 __init__(self,parent, font_name, font_size, font_height, w,h, colorscheme): super().__init__(parent) self.setFocusPolicy(Qt.WheelFocus) self.setAutoFillBackground(False) self.setAttribute(Qt.WA_OpaquePaintEvent, True) self.setCursor(Qt.IBeamCursor) font = QFont(font_name) font.setPixelSize(font_size) self.setFont(font) self._screen = [] self._text = [] self._transform= QTransform() self._cursor_col = 0 self._cursor_row = 0 self._dirty = False self._kbdfunc= None self._w=w self._h=h self._alt_sequence= False self._alt_seq_length=0 self._alt_seq_value=0 self._cursortype= CURSOR_OFF self._color_scheme=self.color_schemes[self.color_scheme_names[colorscheme]] self._cursor_color=self._color_scheme[2] self._cursor_char= 0x20 self._cursor_attr=-1 self._cursor_update=True self._blink= True self._blink_counter=0 self._cursor_rect = QRect(0, 0, self._char_width, self._char_height) self._cursor_polygon=QPolygon([QPoint(0,0+(self._char_height/2)), QPoint(0+(self._char_width*0.8),0+self._char_height), QPoint(0+(self._char_width*0.8),0+(self._char_height*0.67)), QPoint(0+self._char_width,0+(self._char_height*0.67)), QPoint(0+self._char_width,0+(self._char_height*0.33)), QPoint(0+(self._char_width*0.8),0+(self._char_height*0.33)), QPoint(0+(self._char_width*0.8),0), QPoint(0,0+(self._char_height/2))])
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 updateStandardIcons(self): size = QSize(16, 16) rect = QRect(QPoint(), self.iconSize()) transform = QTransform() transform.rotate(90) pixmap = self.style().standardIcon(QStyle.SP_TitleBarNormalButton, None, self.widgetForAction(self.aFloat)).pixmap(size) rect.moveCenter(pixmap.rect().center()) pixmap = pixmap.copy(rect) self.aFloat.setIcon(QIcon(pixmap)) pixmap = self.style().standardIcon(QStyle.SP_TitleBarCloseButton, None, self.widgetForAction(self.aClose)).pixmap(size) rect.moveCenter(pixmap.rect().center()) pixmap = pixmap.copy(rect) self.aClose.setIcon(QIcon(pixmap))
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 trigger(self, ui): """ Trigger this animation """ glyph = [glyph for glyph in ui.scene.items() if hasattr(glyph, 'entity') and glyph.entity == self.mover][0] if self.direction in (2, 3, 4): self.flipped = True self.offset = 32 if self.direction in (6, 7, 8): self.flipped = False self.offset = 0 if self.flipped: glyph.flipped = True glyph.setTransform(QTransform.fromScale(-1, 1)) else: glyph.flipped = False glyph.setTransform(QTransform.fromScale(1, 1)) if glyph.entity.artificial_intelligence: adapter = MapGlyphAdapter(ui, glyph) else: adapter = MapGlyphAdapter(ui, glyph, True) animation = QParallelAnimationGroup() move_y = QPropertyAnimation(adapter, 'y_location') move_y.setDuration(100) move_y.setStartValue(self.start[1] * 32) move_y.setEndValue(self.destination[1] * 32) move_x = QPropertyAnimation(adapter, 'x_location') move_x.setDuration(100) move_x.setStartValue(self.start[0] * 32 + self.offset) move_x.setEndValue(self.destination[0] * 32 + self.offset) animation.addAnimation(move_y) animation.addAnimation(move_x) ui.animations.append(animation) animation.finished.connect(ui.remove_finished_animation) animation.start()
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 resizeEvent(self, event): w = self.view.width() - 10 h = self.view.height() - 10 transform = QTransform.fromScale(w, h) self.view.setTransform(transform) QWidget.resizeEvent(self, event)
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 _define_symbols(): """ Add symbol ? to ScatterPlotItemSymbols, reflect the triangle to point upwards """ symbols = pyqtgraph.graphicsItems.ScatterPlotItem.Symbols path = QPainterPath() path.addEllipse(QRectF(-0.35, -0.35, 0.7, 0.7)) path.moveTo(-0.5, 0.5) path.lineTo(0.5, -0.5) path.moveTo(-0.5, -0.5) path.lineTo(0.5, 0.5) symbols["?"] = path tr = QTransform() tr.rotate(180) symbols['t'] = tr.map(symbols['t'])
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 _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 _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 mappedPolygon( self, polygon, path = None, percent = 0.5 ): """ Maps the inputed polygon to the inputed path \ used when drawing items along the path. If no \ specific path is supplied, then this object's own \ path will be used. It will rotate and move the \ polygon according to the inputed percentage. :param polygon <QPolygonF> :param path <QPainterPath> :param percent <float> :return <QPolygonF> mapped_poly """ translatePerc = percent anglePerc = percent # we don't want to allow the angle percentage greater than 0.85 # or less than 0.05 or we won't get a good rotation angle if ( 0.95 <= anglePerc ): anglePerc = 0.98 elif ( anglePerc <= 0.05 ): anglePerc = 0.05 if ( not path ): path = self.path() if ( not (path and path.length()) ): return QPolygonF() # transform the polygon to the path point = path.pointAtPercent(translatePerc) angle = path.angleAtPercent(anglePerc) # rotate about the 0 axis transform = QTransform().rotate(-angle) polygon = transform.map(polygon) # move to the translation point transform = QTransform().translate(point.x(), point.y()) # create the rotated polygon mapped_poly = transform.map(polygon) self._polygons.append(mapped_poly) return mapped_poly
def saveSlice(self, filename): """Legacy code.""" #print "Saving in ", filename, "slice #", self.sliceNumber, "axis", self._axis result_image = QImage(self.scene().image.size(), self.scene().image.format()) p = QPainter(result_image) for patchNr in range(self.patchAccessor.patchCount): bounds = self.patchAccessor.getPatchBounds(patchNr) if self.openglWidget is None: p.drawImage(0, 0, self.scene().image) else: p.drawImage(bounds[0], bounds[2], self.imagePatches[patchNr]) p.end() #horrible way to transpose an image. but it works. transform = QTransform() transform.rotate(90) result_image = result_image.mirrored() result_image = result_image.transformed(transform) result_image.save(QString(filename))
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 inicializarUI(self): self.setWindowTitle("BlueKing::Reversa") self.setGeometry(0,0,320,240) self.setAutoFillBackground(True) #QGraphicsView/Scene self.view = QGraphicsView() self.view.setStyleSheet("border: 0px;margin: 0px;background-color: #000000;") self.scene = QGraphicsScene(0,0,320,240) self.view.setScene(self.scene) self.baseLayout = QVBoxLayout() self.baseLayout.setContentsMargins(0,0,0,0) self.baseLayout.addWidget(self.view) #Decoracion car_logo = QPixmap("imagenes/car_logo.png") car_logo_item = QGraphicsPixmapItem(car_logo) car_logo_item.setPos(5,5) self.scene.addItem(car_logo_item) self.distlabel = QLabel("-") self.distlabel.setGeometry(20, 20, 280, 200) self.distlabel.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) self.distlabel.setStyleSheet("color: #00FFFF;font-size: 150px;background-color: transparent;") self.scene.addWidget(self.distlabel) self.measureLabel=QLabel("metros") self.measureLabel.setGeometry(10,190,300,30) self.measureLabel.setAlignment(QtCore.Qt.AlignRight |QtCore.Qt.AlignVCenter) self.measureLabel.setStyleSheet("color: #FFFF00;font-size: 30px; font-weight: bold; font-style: italic;background-color: transparent;") self.scene.addWidget(self.measureLabel) self.setLayout(self.baseLayout) transformacion = QTransform() transformacion.scale(1.0,-1.0) #self.view.setTransform(transformacion) self.show()
def updateStandardIcons(self): size = QSize(16, 16) rect = QRect(QPoint(), self.iconSize()) transform = QTransform() transform.rotate(90) pixmap = self.style().standardIcon( QStyle.SP_TitleBarNormalButton, None, self.widgetForAction(self.aFloat)).pixmap(size) rect.moveCenter(pixmap.rect().center()) pixmap = pixmap.copy(rect) self.aFloat.setIcon(QIcon(pixmap)) pixmap = self.style().standardIcon(QStyle.SP_TitleBarCloseButton, None, self.widgetForAction( self.aClose)).pixmap(size) rect.moveCenter(pixmap.rect().center()) pixmap = pixmap.copy(rect) self.aClose.setIcon(QIcon(pixmap))
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 wheelEvent( self, event ): """ Mouse wheel event """ if QApplication.keyboardModifiers() == Qt.ControlModifier: factor = 1.41 ** ( -event.delta() / 240.0 ) self.__currentFactor *= factor self.setTransform( QTransform.fromScale( self.__currentFactor, self.__currentFactor ) ) Settings().flowScale = self.__currentFactor else: QGraphicsView.wheelEvent( self, event ) return
def run(self): """Main method of a thread to receive the MJEPG-stream. For every frame received, the SIGNAL newFrame() is thrown. Never call this directly. Always use start(). """ self.updateControls = self.hasUpdateControls() self.inputAvt = self.isInputAvt() self.running = True while (self.running): frame = self.httpGet("?action=snapshot") if (frame): self.raw = frame frame = QImage.fromData(frame) oldWidth = frame.size().width() oldHeight = frame.size().height() if self.rotation is not None: #print "rot" #print "before", frame.size().width(),frame.size().height() transf = QTransform() transf.rotate(self.rotation) frame = frame.transformed(transf) #print "after", frame.size().width(),frame.size().height() newWidth = frame.size().width() newHeight = frame.size().height() addedHeight = oldWidth * math.sin( math.radians(self.rotation)) addedWidth = oldHeight * math.sin( math.radians(self.rotation)) h = oldHeight / math.sin(math.radians(self.rotation)) #l1 = #print "addedwidth,Height",addedWidth,addedHeight if (self.transformMode is not None and not (self.width == frame.width() and self.height == frame.height())): frame = frame.scaled(self.width, self.height, self.aspectRatio, self.transformMode) self.frame = frame self.emit(SIGNAL("newFrame()"))
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 transformation. 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 overlay_for(pt1, pt2, frequency): # Construct the line-geometry, we'll use this to construct the ellipsoid line = QLineF(pt1, pt2) # Determine the radius for the ellipsoid radius = fresnel_radius(line.length(), frequency) # Draw the ellipsoid zone = QPainterPath() zone.addEllipse(QPointF(0., 0.), line.length() / 2, radius) # Rotate the ellipsoid - same angle as the line transform = QTransform() transform.rotate(-line.angle()) zone = transform.map(zone) # Center the zone over the line lc = QRectF(pt1, pt2).center() zc = zone.boundingRect().center() zone.translate(lc.x() - zc.x(), lc.y() - zc.y()) return line, zone
def __init__( self, parent=None ): QGraphicsScene.__init__( self, parent=parent ) # tiled rendering of patches self._tiling = None self._brushingLayer = None # indicates the dirtyness of each tile self._dirtyIndicator = None self._tileProvider = None self._stackedImageSources = None self._showTileOutlines = False self.data2scene = QTransform(0,1,1,0,0,0) self.scene2data = self.data2scene.transposed() self._slicingPositionSettled = True self._redrawIndicator = False
def _setup_scene(self): self._clear_plot() self.matrix_item = DistanceMapItem(self._sorted_matrix) # Scale the y axis to compensate for pg.ViewBox's y axis invert self.matrix_item.setTransform(QTransform.fromScale(1, -1), ) self.viewbox.addItem(self.matrix_item) # Set fixed view box range. h, w = self._sorted_matrix.shape self.viewbox.setRange(QRectF(0, -h, w, h), padding=0) self.matrix_item.selectionChanged.connect(self._invalidate_selection) if self.sorting == OWDistanceMap.NoOrdering: tree = None elif self.sorting == OWDistanceMap.Clustering: tree = self._cluster_tree() elif self.sorting == OWDistanceMap.OrderedClustering: tree = self._ordered_cluster_tree() self._set_displayed_dendrogram(tree) self._update_color()
class ImageScene2D(QGraphicsScene): """ The 2D scene description of a tiled image generated by evaluating an overlay stack, together with a 2D cursor. """ @property def stackedImageSources(self): return self._stackedImageSources @stackedImageSources.setter def stackedImageSources(self, s): self._stackedImageSources = s s.sizeChanged.connect(self._onSizeChanged) @property def showTileOutlines(self): return self._showTileOutlines @showTileOutlines.setter def showTileOutlines(self, show): self._showTileOutlines = show self.invalidate() @property def sceneShape(self): """ The shape of the scene in QGraphicsView's coordinate system. """ return (self.sceneRect().width(), self.sceneRect().height()) @sceneShape.setter def sceneShape(self, sceneShape): """ Set the size of the scene in QGraphicsView's coordinate system. sceneShape -- (widthX, widthY), where the origin of the coordinate system is in the upper left corner of the screen and 'x' points right and 'y' points down """ assert len(sceneShape) == 2 self.setSceneRect(0,0, *sceneShape) #The scene shape is in Qt's QGraphicsScene coordinate system, #that is the origin is in the top left of the screen, and the #'x' axis points to the right and the 'y' axis down. #The coordinate system of the data handles things differently. #The x axis points down and the y axis points to the right. r = self.scene2data.mapRect(QRect(0,0,sceneShape[0], sceneShape[1])) sliceShape = (r.width(), r.height()) if self._dirtyIndicator: self.removeItem(self._dirtyIndicator) del self._dirtyIndicator self._dirtyIndicator = None self._tiling = Tiling(sliceShape, self.data2scene) self._dirtyIndicator = DirtyIndicator(self._tiling) self.addItem(self._dirtyIndicator) self._onSizeChanged() if self._tileProvider: self._tileProvider.notifyThreadsToStop() # prevent ref cycle self._tileProvider = TileProvider(self._tiling, self._stackedImageSources) self._tileProvider.changed.connect(self.invalidateViewports) def invalidateViewports( self, rectF ): '''Call invalidate on the intersection of all observing viewport-rects and rectF.''' rectF = rectF if rectF.isValid() else self.sceneRect() for view in self.views(): QGraphicsScene.invalidate( self, rectF.intersected(view.viewportRect()) ) def __init__( self, parent=None ): QGraphicsScene.__init__( self, parent=parent ) # tiled rendering of patches self._tiling = None self._brushingLayer = None # indicates the dirtyness of each tile self._dirtyIndicator = None self._tileProvider = None self._stackedImageSources = None self._showTileOutlines = False self.data2scene = QTransform(0,1,1,0,0,0) self.scene2data = self.data2scene.transposed() self._slicingPositionSettled = True self._redrawIndicator = False def drawLine(self, fromPoint, toPoint, pen): tileId = self._tiling.containsF(toPoint) if tileId is None: return p = self._brushingLayer[tileId] p.lock() painter = QPainter(p.image) painter.setPen(pen) tL = self._tiling.imageRectFs[tileId].topLeft() painter.drawLine(fromPoint-tL, toPoint-tL) painter.end() p.dataVer += 1 p.unlock() self.scheduleRedraw(self._tiling.imageRectFs[tileId]) def _onSizeChanged(self): self._brushingLayer = TiledImageLayer(self._tiling) def drawForeground(self, painter, rect): if self._tiling is None: return tile_nos = self._tiling.intersectedF(rect) for tileId in tile_nos: p = self._brushingLayer[tileId] if p.dataVer == p.imgVer: continue p.paint(painter) #access to the underlying image patch is serialized ## draw tile outlines if self._showTileOutlines: painter.drawRect(self._tiling.imageRects[tileId]) def indicateSlicingPositionSettled(self, settled): self._dirtyIndicator.setVisible(settled) self._slicingPositionSettled = settled def drawBackground(self, painter, rectF): if self._tileProvider is None: return tiles = self._tileProvider.getTiles(rectF) for tile in tiles: # prevent flickering if not tile.progress < 1.0: painter.drawImage(tile.rectF, tile.qimg) self._dirtyIndicator.setTileProgress(tile.id, tile.progress) def joinRendering( self ): return self._tileProvider.join()
def setZoom(self, scale): """Scale to selected factor """ transform = QTransform() transform.scale(scale, scale) self.graphicsView.setTransform(transform)