def move(self, vb, xv=None): if vb is not None: if xv is None: xv = self.pos().x() ys = vb.geometry().top() yv = vb.mapSceneToView(pg.Point(0.0, ys)).y() self.setPos(pg.Point(xv, yv))
def paint_flag(self, painter, p1): axis = self._axis() if axis is None: return h = axis.geometry().height() he = h // 3 w2 = h // 2 if self._shape in [None, 'none']: return if self._shape in ['right']: wl, wr = -w2, 0 elif self._shape in ['left']: wl, wr = 0, w2 else: wl, wr = -w2, w2 brush = pg.mkBrush(self.color) painter.setBrush(brush) painter.setPen(None) painter.resetTransform() painter.translate(p1) painter.drawConvexPolygon([ pg.Point(0, 0), pg.Point(wl, -he), pg.Point(wl, -h), pg.Point(wr, -h), pg.Point(wr, -he) ])
def __init__(self, delegate): self.delegate = delegate self.source = self.delegate.source source = self.source pg.ROI.__init__( self, pos=pg.Point(source.outline()[1]), size=pg.Point(source.width, source.length), angle=-source.strike, invertible=False, pen=self.pen_outline) self.handlePen = self.pen_handle self.addScaleRotateHandle([0, 0], [0, 1]) self.addScaleRotateHandle([0, 1], [0, 0]) self.addScaleHandle([1, .5], [0, .5], lockAspect=False) for h in self.handles: h['item'].sigClicked.connect(self.sigRegionChangeStarted.emit) self.delegate.sourceParametersChanged.connect( self.updateROIPosition) self.sigRegionChangeFinished.connect( self.setSourceParametersFromROI) self.setAcceptedMouseButtons(QtCore.Qt.RightButton) self.sigClicked.connect(self.showEditingDialog)
def mouseDragEvent(self, event, axis=None): vb = self.linkedView() if vb is None: return pos = event.scenePos() if self.geometry().contains(pos): self.log.info('mouseDragEvent(%s)', event) event.accept() if self.config['range'] == 'manual': [x_min, x_max], [y_min, y_max] = vb.viewRange() pmin = vb.mapViewToScene(pg.Point(x_min, y_min)) pmax = vb.mapViewToScene(pg.Point(x_max, y_max)) yview_range = y_max - y_min yscene_range = pmax.y() - pmin.y() pnow_y = event.scenePos().y() if self._pan is not None: dx = (pnow_y - self._pan[1]) * yview_range / yscene_range self._pan[0] += dx self._pan[1] = pnow_y if event.button() & QtCore.Qt.LeftButton: if event.isFinish(): if self._pan is not None: pan_x, self._pan = self._pan[0], None self.sigPanYEvent.emit('finish', pan_x) elif self._pan is None: self._pan = [0.0, pnow_y] self.sigPanYEvent.emit('start', 0.0) else: self.sigPanYEvent.emit('drag', self._pan[0])
def paint(self, p, opt, widget): vb = self._view() color = self._cmdp[self._instance_prefix + 'color'] p.resetTransform() vb_rect = vb.geometry() y = self.scene_pos_y() p1 = pg.Point(vb_rect.left(), y) p2 = pg.Point(vb_rect.right(), y) pen = pg.mkPen(color) pen.setWidth(1) p.setPen(pen) p.drawLine(p1, p2) show_stats = self.statistics_show if show_stats != 'off': pen = pg.mkPen([255, 255, 255, 255]) p.setPen(pen) if self.pair is None: txt = three_sig_figs(self.y, self._units) else: dy = abs(self.y - self.pair.y) t1 = three_sig_figs(self.y, self._units) t2 = three_sig_figs(dy, self._units) txt = f'{t1}, Δ={t2}' if show_stats == 'bottom': font = QtGui.QFont() h = QtGui.QFontMetrics(font).height() p1 += pg.Point(0, h) else: p1 += pg.Point(0, -2) p.drawText(p1, txt)
def test_mouse_drag_event(self): self.mock_graph.state = ZOOMING mock_event = Mock() mock_event.button.return_value = Qt.LeftButton mock_event.pos.return_value = pg.Point(0.6, 0.6) mock_event.isFinish.return_value = True mock_event.buttonDownPos.return_value = pg.Point(0.4, 0.4) self.mvb.mapToView = lambda x: x self.mvb.state['mouseMode'] = pg.ViewBox.RectMode self.mvb.match_zoom(pg.Point(0.5, 0.5)) qrect1 = self.sr.call_args[0][0] zoom1 = self.mvb.get_zoom() self.mvb.mouseDragEvent(mock_event) mock_event.accept.assert_called() zoom2 = self.mvb.get_zoom() qrect2 = self.sr.call_args[0][0] # when selecting a smaller region zoom level should increase and # shown area should decrees self.assertTrue(zoom2 > zoom1) self.assertTrue(qrect2.width() < qrect1.width()) mock_event.button.return_value = Qt.RightButton self.mvb.mouseDragEvent(mock_event) mock_event.ignore.assert_called()
def myMouseDragEvent(self, ev, axis=None): # most of this code is copied behavior mouse drag from the original code ev.accept() pos = ev.pos() lastPos = ev.lastPos() dif = pos - lastPos dif *= -1 if ev.button() == QtCore.Qt.RightButton or \ (ev.button() == QtCore.Qt.LeftButton and ev.modifiers() & QtCore.Qt.ControlModifier): # determine the amount of translation tr = dif tr = self.view_box.mapToView(tr) - self.view_box.mapToView(pg.Point(0, 0)) x = tr.x() y = tr.y() self.view_box.translateBy(x=x, y=y) if ev.start: self.range_changed_timer.start() if ev.isFinish(): self.range_changed_timer.stop() self.emit_sig_range_changed() else: if ev.isFinish(): # This is the final move in the drag; change the view scale now self.auto_range = False self.view_box.rbScaleBox.hide() ax = QtCore.QRectF(pg.Point(ev.buttonDownPos(ev.button())), pg.Point(pos)) ax = self.view_box.childGroup.mapRectFromParent(ax) self.view_box.showAxRect(ax) self.view_box.axHistoryPointer += 1 self.view_box.axHistory = self.view_box.axHistory[:self.view_box.axHistoryPointer] + [ax] self.emit_sig_range_changed() else: # update shape of scale box self.view_box.updateScaleBox(ev.buttonDownPos(), ev.pos())
def updateROIPosition(self): source = self.source width = source.width self.setPos(pg.Point(source.outline()[1]), finish=False) self.setSize(pg.Point(width, source.length), finish=False) self.setAngle(-source.strike, finish=False)
def get_ab_angle(self, with_ab_vector=None): """ Gets ROI.ab_angle. If with_ab_vector is given, then the angle returned is with respect to the given vector """ if with_ab_vector is not None: corner = pg.Point(with_ab_vector[0], with_ab_vector[1]) return corner.angle(pg.Point(1, 0)) else: return self.ab_angle
def __init__(self, window, x, y, kind): pg.GraphicsObject.__init__(self) window.imageview.addItem(self) self.window = window self.pts = [pg.Point(round(x), round(y))] self.kind = kind self.state = {'pos': pg.Point(x, y), 'size': pg.Point(0, 0)} self.color = QtGui.QColor( g.settings['roi_color'] ) if g.settings['roi_color'] != 'random' else random_color()
def wheelEvent(self, ev, axis=None): scale_fact = 1.02 ** (ev.delta() * self.state['wheelScaleFactor']) vr = self.targetRect() center = pg.Point(pg.functions.invertQTransform(self.childGroup.transform()).map(ev.pos())) if (center.x()-vr.left())/vr.width() < 0.05: # zoom to far left => all the way left center = pg.Point(vr.left(), center.y()) elif (center.x()-vr.left())/vr.width() > 0.95: # zoom to far right => all the way right center = pg.Point(vr.right(), center.y()) self.zoom_rect(vr, scale_fact, center) ev.accept()
def set_range(self, x0, y0, x1, y1, pad=False): if np.isnan(y0) or np.isnan(y1): return if pad: x0 -= self.datasrc.period*0.5 x1 += self.datasrc.period*0.5 if self.yscale == 'log': y0 = np.log10(y0) if y0 > 0 else 0 y1 = np.log10(y1) if y1 > 0 else 0 self.setRange(QtCore.QRectF(pg.Point(x0, y0), pg.Point(x1, y1)), padding=0)
def coordinateSubmitted(self): if self.displayCtrl.params['Orientation'] != "right": displayError('Set Coordinate function is only supported with Right orientation') return coord_args = str(self.coordinateCtrl.line.text()).split(';') vxsize = self.atlas._info[-1]['vxsize'] * 1e6 x = float(coord_args[0]) y = float(coord_args[1]) z = float(coord_args[2]) if len(coord_args) < 3: return if len(coord_args) <= 4: # When only 4 points are given, assume point needs to be set using orientation == 'right' translated_x = (self.atlas_view.atlas.shape[1] - (float(coord_args[0])/vxsize)) * self.atlas_view.scale[0] translated_y = (self.atlas_view.atlas.shape[2] - (float(coord_args[1])/vxsize)) * self.atlas_view.scale[0] translated_z = (self.atlas_view.atlas.shape[0] - (float(coord_args[2])/vxsize)) * self.atlas_view.scale[0] roi_origin = (translated_x, 0.0) to_size = (self.atlas_view.atlas.shape[2] * self.atlas_view.scale[1], 0.0) to_ab_angle = 90 to_ac_angle = 0 target_p1 = translated_z target_p2 = translated_y else: transform = literal_eval(coord_args[4]) # Use LIMS matrices to get the origin and vectors of the plane M1, M1i = points_to_aff.lims_obj_to_aff(transform) origin, ab_vector, ac_vector = points_to_aff.aff_to_origin_and_vectors(M1i) target_p1, target_p2 = self.get_target_position([x, y, z, 1], M1, ab_vector, ac_vector, vxsize) # Put the origin and vectors back to view coordinates roi_origin = np.array(self.ccf_point_to_view(origin)) ab_vector = -np.array(self.vector_to_view(ab_vector)) ac_vector = -np.array(self.vector_to_view(ac_vector)) to_ac_angle = self.atlas_view.line_roi.get_ac_angle(ac_vector) # Where the origin of the ROI should be if to_ac_angle > 0: roi_origin = ac_vector + roi_origin to_size = self.atlas_view.line_roi.get_roi_size(ab_vector, ac_vector) to_ab_angle = self.atlas_view.line_roi.get_ab_angle(ab_vector) self.target.setPos(target_p1, target_p2) self.atlas_view.line_roi.setPos(pg.Point(roi_origin[0], roi_origin[1])) self.atlas_view.line_roi.setSize(pg.Point(to_size)) self.atlas_view.line_roi.setAngle(to_ab_angle) self.atlas_view.slider.setValue(int(to_ac_angle)) self.target.setVisible(True) # TODO: keep target visible when coming back to the same slice... how?
def get_roi_size(self, ab_vector, ac_vector): """ Returns the size of the ROI expected from the given vectors. """ # Find the width w = pg.Point(ab_vector[0], ab_vector[1]) # Find the length l = pg.Point(ac_vector[0], ac_vector[1]) return w.length(), l.length()
def test_match_zoom(self): point1 = pg.Point(0.5, 0.5) self.mvb.match_zoom(point1) qrect1 = self.sr.call_args[0][0] point2 = pg.Point(0.75, 0.75) self.mvb.match_zoom(point2, offset=True) qrect2 = self.sr.call_args[0][0] # when center is offset the new rect should also be offset self.assertTrue(qrect1.x() < qrect2.x()) self.assertAlmostEqual(qrect1.width(), qrect2.width())
def paint(self, p, *args): p.setRenderHint(p.Antialiasing) px, py = self._px w = 4 * px h = 4 * py r = QtCore.QRectF(-w, -h, w * 2, h * 2) p.setPen(pg.mkPen(self.color)) p.setBrush(pg.mkBrush(0, 0, 255, 100)) p.drawEllipse(r) p.drawLine(pg.Point(-w * 2, 0), pg.Point(w * 2, 0)) p.drawLine(pg.Point(0, -h * 2), pg.Point(0, h * 2))
def simulate_mouse_drag(self, start: tuple, end: tuple): start = self.widget.graph.view_box.mapViewToScene( pg.Point(start[0], start[1])).toPoint() end = self.widget.graph.view_box.mapViewToScene( pg.Point(end[0], end[1])).toPoint() mouseMove(self.widget.graph, start) QtTest.QTest.qWait(100) mousePress(self.widget.graph, start, Qt.LeftButton) mouseMove(self.widget.graph, end, Qt.LeftButton) mouseRelease(self.widget.graph, end, Qt.LeftButton) QtTest.QTest.qWait(100)
def myMouseDragEvent(self, ev, axis=None): # most of this code is copied behavior of left click mouse drag from the original code ev.accept() pos = ev.pos() lastPos = ev.lastPos() dif = pos - lastPos dif *= -1 ## Ignore axes if mouse is disabled mouseEnabled = np.array(self.img_view_box.state['mouseEnabled'], dtype=np.float) mask = mouseEnabled.copy() if axis is not None: mask[1 - axis] = 0.0 if ev.button() == QtCore.Qt.RightButton or \ (ev.button() == QtCore.Qt.LeftButton and \ ev.modifiers() & QtCore.Qt.ControlModifier): # determine the amount of translation tr = dif * mask tr = self.img_view_box.mapToView(tr) - self.img_view_box.mapToView( pg.Point(0, 0)) x = tr.x() y = tr.y() self.img_view_box.translateBy(x=x, y=y) self.img_view_box.sigRangeChangedManually.emit( self.img_view_box.state['mouseEnabled']) else: if ev.isFinish( ): ## This is the final move in the drag; change the view scale now # print "finish" self.img_view_box.rbScaleBox.hide() # ax = QtCore.QRectF(Point(self.pressPos), Point(self.mousePos)) ax = QtCore.QRectF(pg.Point(ev.buttonDownPos(ev.button())), pg.Point(pos)) ax = self.img_view_box.childGroup.mapRectFromParent(ax) self.img_view_box.showAxRect(ax) self.img_view_box.axHistoryPointer += 1 self.img_view_box.axHistory = self.img_view_box.axHistory[:self . img_view_box . axHistoryPointer] + [ ax ] self._max_range = False else: ## update shape of scale box self.img_view_box.updateScaleBox(ev.buttonDownPos(), ev.pos())
def boundingRect(self): if self._bounds is None: # too slow! w = self.pixelLength(pg.Point(1, 0)) if w is None: return QtCore.QRectF() h = self.pixelLength(pg.Point(0, 1)) # o = self.mapToScene(QtCore.QPointF(0, 0)) # w = abs(1.0 / (self.mapToScene(QtCore.QPointF(1, 0)) - o).x()) # h = abs(1.0 / (self.mapToScene(QtCore.QPointF(0, 1)) - o).y()) self._px = (w, h) w *= 21 h *= 21 self._bounds = QtCore.QRectF(-w, -h, w * 2, h * 2) return self._bounds
def get_ac_angle(self, with_ac_vector=None): """ Gets ROI.ac_angle. If with_ac_vector is given, then the angle returned is with respect to the given vector """ if with_ac_vector is not None: l = pg.Point(with_ac_vector[0], with_ac_vector[1]) # Explain this. corner = pg.Point(l.length(), with_ac_vector[2]) if with_ac_vector[ 0] < 0: # Make sure this points to the correct direction corner = pg.Point(-l.length(), with_ac_vector[2]) return pg.Point(0, 1).angle(corner) else: return self.ac_angle
def safe_update_scale_box(self, buttonDownPos, currentPos): x, y = currentPos if buttonDownPos[0] == x: x += 1 if buttonDownPos[1] == y: y += 1 self.updateScaleBox(buttonDownPos, pg.Point(x, y))
def myMouseDragEvent(self, ev, axis=None): #most of this code is copied behavior of left click mouse drag from the original code ev.accept() pos = ev.pos() lastPos = ev.lastPos() dif = pos - lastPos dif *= -1 ## Ignore axes if mouse is disabled mouseEnabled = np.array(self.img_view_box.state['mouseEnabled'], dtype=np.float) mask = mouseEnabled.copy() if axis is not None: mask[1 - axis] = 0.0 if ev.button() == QtCore.Qt.RightButton or \ (ev.button() == QtCore.Qt.LeftButton and \ ev.modifiers() & QtCore.Qt.ControlModifier): #determine the amount of translation tr = dif * mask tr = self.img_view_box.mapToView(tr) - self.img_view_box.mapToView(pg.Point(0, 0)) x = tr.x() y = tr.y() self.img_view_box.translateBy(x=x, y=y) self.img_view_box.sigRangeChangedManually.emit(self.img_view_box.state['mouseEnabled']) else: pg.ViewBox.mouseDragEvent(self.img_view_box, ev)
def _update_marker_text(self): x = self._x style = self._time_style() if self._x is None: html = '' else: html = f'<div><span style="{style}">t={x:.6f}</span></div>' self._marker_time_text.setHtml(html) axis = self._axis() if axis is None: return vb = axis.linkedView() if vb is None or self._x is None: return g = axis.geometry() axis_top = g.top() axis_height = axis.geometry().height() text_offset = axis_height // 2 x_scene = vb.mapViewToScene(pg.Point(x, 0.0)).x() if self._pair is None: self._marker_time_text.setPos(x_scene + text_offset, axis_top) elif self.is_left: self._marker_time_text.setPos(x_scene, axis_top) self._update_delta_time() else: self._marker_time_text.setPos(x_scene, axis_top) self._pair._update_delta_time()
def _update_offsets(self, vb=None): vb = self.parent.viewbox height = vb.height() n = len(self.plots) plot_items = sorted(self.plots.items(), reverse=True) for i, (key, plot) in enumerate(plot_items): offset = (i + 1) * height / (n + 1) point = self.parent.viewbox.mapToView(pg.Point(0, offset)) plot.setPos(0, point.y()) labels = sorted(self.labels.items(), reverse=True) for i, (key, label) in enumerate(labels): offset = (i + 1) * height / (n + 1) point = self.parent.viewbox_norm.mapToView(pg.Point(0, offset)) label.setPos(0.8, point.y())
def boundingRect(self): r = pg.ROI.boundingRect(self) pxl = self.pixelLength(pg.Point([1, 0])) if pxl is None: return r pxw = 50 * pxl return r.adjusted(-50, -50, 50, 50)
def __init__(self, text='', color=(200, 200, 200), html=None, anchor=(0, 0), border=None, fill=None): """ Arguments: *text* The text to display *color* The color of the text (any format accepted by pg.mkColor) *html* If specified, this overrides both *text* and *color* *anchor* A QPointF or (x,y) sequence indicating what region of the text box will be anchored to the item's position. A value of (0,0) sets the upper-left corner of the text box to be at the position specified by setPos(), while a value of (1,1) sets the lower-right corner. *border* A pen to use when drawing the border *fill* A brush to use when filling within the border """ UIGraphicsItem.__init__(self) self.textItem = QtGui.QGraphicsTextItem() self.lastTransform = None self._bounds = QtCore.QRectF() if html is None: self.setText(text, color) else: self.setHtml(html) self.anchor = pg.Point(anchor) self.fill = pg.mkBrush(fill) self.border = pg.mkPen(border)
def myMouseDragEvent(self, ev, axis=None): #most of this code is copied behavior of left click mouse drag from the original code ev.accept() pos = ev.pos() lastPos = ev.lastPos() dif = pos - lastPos dif *= -1 if ev.button() == QtCore.Qt.RightButton or \ (ev.button() == QtCore.Qt.LeftButton and \ ev.modifiers() & QtCore.Qt.ControlModifier): #determine the amount of translation tr = dif tr = self.view_box.mapToView(tr) - self.view_box.mapToView( pg.Point(0, 0)) x = tr.x() y = tr.y() self.view_box.translateBy(x=x, y=y) else: self._auto_range = False pg.ViewBox.mouseDragEvent(self.view_box, ev) self.view_box.sigRangeChangedManually.emit( self.view_box.state['mouseEnabled'])
def __updateLayout(self): T = self.sceneTransform() if T is None: T = QTransform() # map the axis spine to scene coord. system. viewbox_line = T.map(self._spine.line()) angle = viewbox_line.angle() assert not np.isnan(angle) # note in Qt the y axis is inverted (90 degree angle 'points' down) left_quad = 270 < angle <= 360 or -0.0 <= angle < 90 # position the text label along the viewbox_line label_pos = self._spine.line().pointAt(0.90) if left_quad: # Anchor the text under the axis spine anchor = (0.5, -0.1) else: # Anchor the text over the axis spine anchor = (0.5, 1.1) self._label.setPos(label_pos) self._label.setAnchor(pg.Point(*anchor)) self._label.setRotation(-angle if left_quad else 180 - angle) self._arrow.setPos(self._spine.line().p2()) self._arrow.setRotation(180 - angle)
def stepTo(self, t): data = self.clock.refData while self.i < len(data)-1 and data['t'][self.i] < t: self.i += 1 while self.i > 1 and data['t'][self.i-1] >= t: self.i -= 1 self.setPos(data['x'][self.i], self.clock.y0) t = data['pt'][self.i] self.hand.setRotation(-0.25 * t * 360.) self.resetTransform() v = data['v'][self.i] gam = (1.0 - v**2)**0.5 self.setScale(gam) f = data['f'][self.i] self.flare.resetTransform() if f < 0: self.flare.moveBy(self.size*0.4, 0) else: self.flare.moveBy(-self.size*0.4, 0) self.flare.setScale(-f * (0.5+np.random.random()*0.1)) if self._spaceline is not None: self._spaceline.setPos(pg.Point(data['x'][self.i], data['t'][self.i])) self._spaceline.setAngle(data['v'][self.i] * 45.)
def mouseDragEvent(self, ev, axis=None): ## if axis is specified, event will only affect that axis. ev.accept() ## we accept all buttons pos = ev.pos() lastPos = ev.lastPos() dif = pos - lastPos dif = dif * -1 ## Ignore axes if mouse is disabled mouseEnabled = np.array(self.state['mouseEnabled'], dtype=np.float) mask = mouseEnabled.copy() if axis is not None: mask[1 - axis] = 0.0 ## Scale or translate based on mouse button if (ev.button() & QtCore.Qt.LeftButton) and ( ev.modifiers() & QtCore.Qt.ShiftModifier): tr = dif * mask tr = self.mapToView(tr) - self.mapToView(pyqtgraph.Point(0, 0)) x = tr.x() if mask[0] == 1 else None y = tr.y() if mask[1] == 1 else None self.translateBy(x=x, y=y) self.sigRangeChangedManually.emit(self.state['mouseEnabled']) else: super(CustomViewBox, self).mouseDragEvent(ev, axis)