;ivdZddlZddlmZmZmZmZmZddlZ ddl m Z ddl m Z ddlmZmZmZddlmZd d lmZd d lmZejjZgd Zd ZGddeZGddeZGddeZGddeZGddeZGddeZGddej Z!Gdde!Z"GddeZ#Gd d!e#Z$Gd"d#eZ%Gd$d%eZ&Gd&d'e&Z'Gd(d)eZ(Gd*d+e&Z)Gd,d-eZ*dS).a ROI.py - Interactive graphics items for GraphicsView (ROI widgets) Copyright 2010 Luke Campagnola Distributed under MIT/X11 license. See license.txt for more information. Implements a series of graphics items which display movable/scalable/rotatable shapes for use as region-of-interest markers. ROI class automatically handles extraction of array data from ImageItems. The ROI class is meant to serve as the base for more specific types; see several examples of how to build an ROI at the bottom of the file. N)atan2cosdegreeshypotsin) functions)Point)QtCoreQtGui QtWidgets) SRTTransform)GraphicsObject)UIGraphicsItem) ROITestROIRectROI EllipseROI CircleROILineROI MultiLineROI MultiRectROILineSegmentROI PolyLineROI CrosshairROI TriangleROIcd||||fzS)Nz[%f, %f] + [%f, %f])xywidthheight)rs OC:\PYTHON\MyICR_Workspace\venv\Lib\site-packages\pyqtgraph/graphicsItems/ROI.pyrectStrr%&s6 ACCEE13355!''))QXXZZ#H HHceZdZdZejeZejeZejeZ ejeZ ejeeZ ejeZ e ddddddddddddddddddddfdZd Zd Zd ZdId Zd ZdZdZdZdZdZdJdZdKdZdKdZdKdZdZdLdZdZdMdZ dNdZ!dOdZ"dPdZ#dPdZ$dMdZ%dQd Z&d!Z'd"Z(d#Z)d$Z*dQd%Z+dQd&Z,d'Z-d(Z.d)Z/d*Z0d+Z1d,Z2d-Z3d.Z4d/Z5d0Z6d1Z7d2Z8d3Z9d4Z:d5Z;d6ZdRd:Z?dId;Z@d<ZAd=ZBdQd>ZCd?ZDd@ZEdSdBZFdTdCZGdTdDZHdTdEZIdFZJdQdGZKdHZLdS)UraJ Generic region-of-interest widget. Can be used for implementing many types of selection box with rotate/translate/scale handles. ROIs can be customized to have a variety of shapes (by subclassing or using any of the built-in subclasses) and any combination of draggable handles that allow the user to manipulate the ROI. Default mouse interaction: * Left drag moves the ROI * Left drag + Ctrl moves the ROI with position snapping * Left drag + Alt rotates the ROI * Left drag + Alt + Ctrl rotates the ROI with angle snapping * Left drag + Shift scales the ROI * Left drag + Shift + Ctrl scales the ROI with size snapping In addition to the above interaction modes, it is possible to attach any number of handles to the ROI that can be dragged to change the ROI in various ways (see the ROI.add____Handle methods). ================ =========================================================== **Arguments** pos (length-2 sequence) Indicates the position of the ROI's origin. For most ROIs, this is the lower-left corner of its bounding rectangle. size (length-2 sequence) Indicates the width and height of the ROI. angle (float) The rotation of the ROI in degrees. Default is 0. invertible (bool) If True, the user may resize the ROI to have negative width or height (assuming the ROI has scale handles). Default is False. maxBounds (QRect, QRectF, or None) Specifies boundaries that the ROI cannot be dragged outside of by the user. Default is None. snapSize (float) The spacing of snap positions used when *scaleSnap* or *translateSnap* are enabled. Default is 1.0. scaleSnap (bool) If True, the width and height of the ROI are forced to be integer multiples of *snapSize* when being resized by the user. Default is False. translateSnap (bool) If True, the x and y positions of the ROI are forced to be integer multiples of *snapSize* when being resized by the user. Default is False. rotateSnap (bool) If True, the ROI angle is forced to a multiple of the ROI's snap angle (default is 15 degrees) when rotated by the user. Default is False. parent (QGraphicsItem) The graphics item parent of this ROI. It is generally not necessary to specify the parent. pen (QPen or argument to pg.mkPen) The pen to use when drawing the shape of the ROI. hoverPen (QPen or argument to mkPen) The pen to use while the mouse is hovering over the ROI shape. handlePen (QPen or argument to mkPen) The pen to use when drawing the ROI handles. handleHoverPen (QPen or argument to mkPen) The pen to use while the mouse is hovering over an ROI handle. movable (bool) If True, the ROI can be moved by dragging anywhere inside the ROI. Default is True. rotatable (bool) If True, the ROI can be rotated by mouse drag + ALT resizable (bool) If True, the ROI can be resized by mouse drag + SHIFT removable (bool) If True, the ROI will be given a context menu with an option to remove the ROI. The ROI emits sigRemoveRequested when this menu action is selected. Default is False. antialias (bool) If True, the ROI will render using AntiAliasing, this is what is desired in almost all cases, the option is added for testing purposes. Default is True ================ =========================================================== ======================= ==================================================== **Signals** sigRegionChangeFinished Emitted when the user stops dragging the ROI (or one of its handles) or if the ROI is changed programatically. sigRegionChangeStarted Emitted when the user starts dragging the ROI (or one of its handles). sigRegionChanged Emitted any time the position of the ROI changes, including while it is being dragged by the user. sigHoverEvent Emitted when the mouse hovers over the ROI. sigClicked Emitted when the user clicks on the ROI. Note that clicking is disabled by default to prevent stealing clicks from objects behind the ROI. To enable clicking, call roi.setAcceptedMouseButtons(QtCore.Qt.MouseButton.LeftButton). See QtWidgets.QGraphicsItem documentation for more details. sigRemoveRequested Emitted when the user selects 'remove' from the ROI's context menu (if available). ======================= ==================================================== rgFN?Tctj|| |tjjjt|}t|}||_||_ ||_ ||_ ||_ d|_ ||_d|_d|_| d} || | d} t%j| |_| d} t%j| |_|d}||_g|_tddtdddd|_d|_|||||||dd|_d |_||_ ||_!||_"||_#| |_$d |_%||_&||_'tQ||_)dS) NF)r*r*r*r*r)r*r*rr)possizeangle g.@)*r__init__setAcceptedMouseButtonsr Qt MouseButtonNoButtonr aspectLocked translatable rotatable resizable removablemenu _antialiasfreeHandleMoved mouseHoveringsetPenfnmkPenhoverPen handlePenhandleHoverPenhandlesstate lastStatesetPossetAnglesetSize setZValueisMoving handleSize invertible maxBoundssnapSize translateSnap rotateSnaprotateSnapAngle scaleSnap scaleSnapSizeMouseDragHandlermouseDragHandler)selfr-r.r/rOrPrQrUrRrSparentpenrCrDrEmovabler9r:r;r7 antialiass r$r2z ROI.__init__s f--- $$VY%:%CDDDCjjT{{(#""" #$" ;!C C  $H**  'I),,  !*N, "1QZZqaHH  C e T r $"  *$#"%!1 6 6r&c*|SN) stateCopyrYs r$getStatez ROI.getStates~~r&ci}t|jd|d<t|jd|d<|jd|d<|S)Nr-r.r/)r rG)rYscs r$r`z ROI.stateCopysL $*U+,,5 4:f-..6 j)7  r&ci}t|jd|d<t|jd|d<|jd|d<|S)zReturn the state of the widget in a format suitable for storing to disk. (Points are converted to tuple) Combined with setState(), this allows ROIs to be easily saved and restored.r-r.r/)tuplerGrYrGs r$ saveStatez ROI.saveStatesN TZ.//e dj011f G,g r&c||dd||dd||d|dS)zk Set the state of the ROI from a structure generated by saveState() or getState(). r-Fupdater.r/N)rIrKrJ)rYrGrks r$setStatez ROI.setStatesX E%L /// U6]5 111 eGnV 44444r&ctj|||jD] }|d|dz!dS)Nitemr)r QGraphicsItemrLrF)rYzhs r$rLz ROI.setZValuesU))$222 % %A fI  ! $ $ $ $ % %r&ct||S)zs Return the bounding rectangle of this ROI in the coordinate system of its parent. ) mapToParent boundingRectras r$ parentBoundszROI.parentBoundss0  1 1 3 344AACCCr&crtj|i||_|j|_|dS)z| Set the pen to use when drawing the ROI shape. For arguments, see :func:`mkPen `. N)rArBr[ currentPenrk)rYargskwargss r$r@z ROI.setPens4 8T,V,,( r&c6|dS)z!Return the size (w,h) of the ROI.r.rbras r$r.zROI.sizes}}v&&r&c6|dS)zjReturn the position (x,y) of the ROI's origin. For most ROIs, this will be the lower-left corner.r-r{ras r$r-zROI.poss}}u%%r&c6|dS)z'Return the angle of the ROI in degrees.r/r{ras r$r/z ROI.angles}}w''r&c@|dvrtd|t|}n4t|trtdt||}||jd<t j|||r||dSdS)aSet the position of the ROI (in the parent's coordinate system). Accepts either separate (x, y) arguments or a single :class:`Point` or ``QPointF`` argument. By default, this method causes both ``sigRegionChanged`` and ``sigRegionChangeFinished`` to be emitted. If *finish* is False, then ``sigRegionChangeFinished`` will not be emitted. You can then use stateChangeFinished() to cause the signal to be emitted after a series of state changes. If *update* is False, the state change will be remembered but not processed and no signals will be emitted. You can then use stateChanged() to complete the state change. This allows multiple change functions to be called sequentially while minimizing processing overhead and repeated signals. Setting ``update=False`` also forces ``finish=False``. TFupdate argument must be boolNz3Positional arguments to setPos() must be numerical.r-finish) TypeErrorr isinstanceboolrGr rorI stateChanged)rYr-r rkrs r$rIz ROI.setPos s"  & &:;; ; 9**CC!T"" W UVVVQ--C 5&&tS111  -   V  , , , , , - -r&c@|dvrtdt|}|rPt|d|jz |jz|d<t|d|jz |jz|d<|^t|jd}|ddkrdn|d|d<|ddkrdn|d|d<t||z }|t|}|t||jdz}|t||z} |jd|z| z } || dd |||jd<|r|| dSdS) a| Set the ROI's size. =============== ========================================================================== **Arguments** size (Point | QPointF | sequence) The final size of the ROI center (None | Point) Optional center point around which the ROI is scaled, expressed as [0-1, 0-1] over the size of the ROI. centerLocal (None | Point) Same as *center*, but the position is expressed in the local coordinate system of the ROI snap (bool) If True, the final size is snapped to the nearest increment (see ROI.scaleSnapSize) update (bool) See setPos() finish (bool) See setPos() =============== ========================================================================== rrrrNr.r-Frkrr) rr roundrVrGrsrIprepareGeometryChanger) rYr.center centerLocalsnaprkroldSizecc1newPoss r$rKz ROI.setSize,s"  & &:;; ;T{{  ODGd&8899D>aBBB>>##"5/B.yy&& <%D u  "228E?2NNHUO > %x((Aa A~""$$qvvxx//~**,,qvvxx7!%%''!''))33~++-- 9!~!!##aeegg--~))++aeegg5!&&((188::55~,,..;! UOOOq OOO8T**8T** HUOF6 BBBBBr&cd|||z||||dS)a Rotate the ROI by *angle* degrees. =============== ========================================================================== **Arguments** angle (float) The angle in degrees to rotate center (None | Point) Optional center point around which the ROI is rotated, in the local coordinate system of the ROI snap (bool) If True, the final ROI angle is snapped to the nearest increment (default is 15 degrees; see ROI.rotateSnapAngle) update (bool) See setPos() finish (bool) See setPos() =============== ========================================================================== )rrrkrN)rJr/)rYr/rrrkrs r$rz ROI.rotates4 djjll5(d6Z` aaaaar&cl||_|j|dSr_)rb preMoveStatesigRegionChangeStartedemitras r$handleMoveStartedzROI.handleMoveStarteds/ MMOO #((.....r&cXt|}||d||d|S)a Add a new translation handle to the ROI. Dragging the handle will move the entire ROI without changing its angle or shape. Note that, by default, ROIs may be moved by dragging anywhere inside the ROI. However, for larger ROIs it may be desirable to disable this and instead provide one or more translation handles. =================== ==================================================== **Arguments** pos (length-2 sequence) The position of the handle relative to the shape of the ROI. A value of (0,0) indicates the origin, whereas (1, 1) indicates the upper-right corner, regardless of the ROI's size. item The Handle instance to add. If None, a new handle will be created. name The name of this handle (optional). Handles are identified by name when calling getLocalHandlePositions and getSceneHandlePositions. =================== ==================================================== tnametyper-rnindexr addHandlerYr-axesrnrrs r$addTranslateHandlezROI.addTranslateHandles2,Cjj~~tSdSS[`~aaar&c\|t|}||d||d|S)a Add a new free handle to the ROI. Dragging free handles has no effect on the position or shape of the ROI. =================== ==================================================== **Arguments** pos (length-2 sequence) The position of the handle relative to the shape of the ROI. A value of (0,0) indicates the origin, whereas (1, 1) indicates the upper-right corner, regardless of the ROI's size. item The Handle instance to add. If None, a new handle will be created. name The name of this handle (optional). Handles are identified by name when calling getLocalHandlePositions and getSceneHandlePositions. =================== ==================================================== Nfrrrrs r$ addFreeHandlezROI.addFreeHandles7$ ?**C~~tSdSS[`~aaar&c:t|}t|}|d||||d}||krd|d<||krd|d<|||S)a  Add a new scale handle to the ROI. Dragging a scale handle allows the user to change the height and/or width of the ROI. =================== ==================================================== **Arguments** pos (length-2 sequence) The position of the handle relative to the shape of the ROI. A value of (0,0) indicates the origin, whereas (1, 1) indicates the upper-right corner, regardless of the ROI's size. center (length-2 sequence) The center point around which scaling takes place. If the center point has the same x or y value as the handle position, then scaling will be disabled for that axis. item The Handle instance to add. If None, a new handle will be created. name The name of this handle (optional). Handles are identified by name when calling getLocalHandlePositions and getSceneHandlePositions. =================== ==================================================== r)rrrr-rn lockAspectTxoffyoffr)r rr r) rYr-rrrnrrrinfos r$addScaleHandlezROI.addScaleHandles,CjjvcVCQUeopp 5577fhhjj DL 5577fhhjj DL~~d%~000r&cxt|}t|}||d|||d|S)a[ Add a new rotation handle to the ROI. Dragging a rotation handle allows the user to change the angle of the ROI. =================== ==================================================== **Arguments** pos (length-2 sequence) The position of the handle relative to the shape of the ROI. A value of (0,0) indicates the origin, whereas (1, 1) indicates the upper-right corner, regardless of the ROI's size. center (length-2 sequence) The center point around which rotation takes place. item The Handle instance to add. If None, a new handle will be created. name The name of this handle (optional). Handles are identified by name when calling getLocalHandlePositions and getSceneHandlePositions. =================== ==================================================== r#rrrr-rnrrrYr-rrnrrs r$addRotateHandlezROI.addRotateHandlesA(Cjjv~~tSFSV`deemr~sssr&ct|}t|}|d|dkr!|d|dkrtd||d|||d|S)a Add a new scale+rotation handle to the ROI. When dragging a handle of this type, the user can simultaneously rotate the ROI around an arbitrary center point as well as scale the ROI by dragging the handle toward or away from the center point. =================== ==================================================== **Arguments** pos (length-2 sequence) The position of the handle relative to the shape of the ROI. A value of (0,0) indicates the origin, whereas (1, 1) indicates the upper-right corner, regardless of the ROI's size. center (length-2 sequence) The center point around which scaling and rotation take place. item The Handle instance to add. If None, a new handle will be created. name The name of this handle (optional). Handles are identified by name when calling getLocalHandlePositions and getSceneHandlePositions. =================== ==================================================== rrz5Scale/rotate handles cannot be at their center point.srrr)r Exceptionrrs r$addScaleRotateHandlezROI.addScaleRotateHandle1su,Cjjv q6VAY  3q6VAY#6#6STT T~~tTVTWaeffns~tttr&cxt|}t|}||d|||d|S)a Add a new rotation+free handle to the ROI. When dragging a handle of this type, the user can rotate the ROI around an arbitrary center point, while moving toward or away from the center point has no effect on the shape of the ROI. =================== ==================================================== **Arguments** pos (length-2 sequence) The position of the handle relative to the shape of the ROI. A value of (0,0) indicates the origin, whereas (1, 1) indicates the upper-right corner, regardless of the ROI's size. center (length-2 sequence) The center point around which rotation takes place. item The Handle instance to add. If None, a new handle will be created. name The name of this handle (optional). Handles are identified by name when calling getLocalHandlePositions and getSceneHandlePositions. =================== ==================================================== rfrrr)rYr-rrrnrrs r$addRotateFreeHandlezROI.addRotateFreeHandleMsA,Cjjv~~tTVTWaeffns~tttr&c>d|vs|d5t|j|d|j|j||j}||d<n'|d}|d||d<||d|jdz||||j |n|j ||| | dz||S)Nrnr)typr[rCrZr]r-r.r)HandlerNrDrEr=r-rIrG connectROIrFappendinsertrLzValuerrYrrrqs r$rz ROI.addHandlegs   f!5tDLdn $ 3DDO]]]ADLLV AE{"eeggU  etz&11222 T = L   % % % % L  t , , , DKKMM!O$$$ r&cttrJfdt|jD}t |dkrt d|dSS)zQ Return the index of *handle* in the list of this ROI's handles. c.g|]\}}|du|Srn).0irhandles r$ z%ROI.indexOfHandle..s,XXX71dfQWAWAWQAWAWAWr&rz4Cannot return handle index; not attached to this ROI)rr enumeraterFrrrYrrs ` r$ indexOfHandlezROI.indexOfHandlesf ff % % XXXXi &=&=XXXE5zzQ VWWW8OMr&c||}|j|d}|j|||t |jdkr;|'|||dS)ztRemove a handle from this ROI. Argument may be either a Handle instance or the integer index of the handle.rnrN) rrFpop disconnectROIrroisscene removeItemrrs r$ removeHandlezROI.removeHandles""6**e$V, T""" v{  q TZZ\\%= JJLL # #F + + + r&c||}|j|}||||d<||d<|||dS)zReplace one handle in the ROI for another. This is useful when connecting multiple ROIs together. *oldHandle* may be a Handle instance or the index of a handle to be replaced.rnr-rN)rrFrr-r)rY oldHandle newHandlerrs r$ replaceHandlezROI.replaceHandlesm ""9--|E" %    V mmooU  t5)))))r&cdSNTr)rYrs r$checkRemoveHandlezROI.checkRemoveHandles tr&c|1g}|jD]%}||d|df&|S|j|d|j|dfS)zReturns the position of handles in the ROI's coordinate system. The format returned is a list of (name, pos) tuples. Nrr-)rFrrYr positionsrqs r$getLocalHandlePositionszROI.getLocalHandlePositionssl =I\ 8 8  !F)QuX!67777 L'/e1DU1KL Lr&c|Cg}|jD]7}||d|df8|S|j|d|j|dfS)zReturns the position of handles in the scene coordinate system. The format returned is a list of (name, pos) tuples. Nrrn)rFrscenePosrs r$getSceneHandlePositionszROI.getSceneHandlePositionss =I\ D D  !F)QvY-?-?-A-A!BCCCC L'/e1DV1L1U1U1W1WX Xr&c$d|jDS)z6 Return a list of this ROI's Handles. cg|] }|d Srrrrqs r$rz"ROI.getHandles..000a& 000r&rFras r$ getHandleszROI.getHandless104<0000r&cR|||Sr_)rs mapFromScene)rYrs r$mapSceneToParentzROI.mapSceneToParents$ 1 1" 5 5666r&ctj|||r&|jD]}|ddS|jD]}|ddSNrn)r ro setSelectedrFshowhide)rYrrqs r$rzROI.setSelecteds++D!444  !\ ! !&      ! !\ ! !&      ! !r&czd}|s|jr+|tjjjrd}tjjjtjjjtjjjfD]0}| |zr| |rd}1| r)| tjjj|r| d| tjjj| tjjj| tjjj|j |dS| ddSNFT)isExitr8 acceptDragsr r4r5 LeftButton RightButton MiddleButtonacceptedMouseButtons acceptClickscontextMenuEnabled setMouseHover sigHoverEventrrYevhoverbtns r$ hoverEventzROI.hoverEventsxyy{{ C  R^^FI4I4T%U%U  -8&):O:[]c]f]r]A  --//#52??3;O;OE&&(( C 5 ABBB  &   t $ $ $ OOFI1< = = = OOFI1= > > > OOFI1> ? ? ?   # #D ) ) ) ) )   u % % % % %r&cV|j|krdS||_|dSr_)r?_updateHoverColorrYrs r$rzROI.setMouseHovers5   & & F"      r&c~|}|j|kr||_|dSdSr_)_makePenrwrk)rYr[s r$rzROI._updateHoverColors<mmoo ?c ! !!DO KKMMMMM " !r&c,|jr|jS|jSr_)r?rCr[ras r$rz ROI._makePens   = 8Or&cr|jp0|jo)t|jdkSNr)r;r<rchildrenras r$rzROI.contextMenuEnableds1~L!Ls493E3E3G3G/H/H1/LLr&c |sdS|}||||}|}|t jt| t| dSr_) rgetMenuraddParentContextMenus screenPospopupr QPointintrr )rYrr<r-s r$raiseContextMenuzROI.raiseContextMenus&&((  F||~~zz||11$bAAllnn 6=SUUWWs35577||<<=====r&c|jtj|_|jt dd|jrmt jt dd|j}|j |j |j |||j_ |jS)Nrz Remove ROI) r<r QMenusetTitlerr;r QAction triggeredconnect removeClicked addActionremAct)rYr1s r$r"z ROI.getMenu s 9 !))DI I  y66 7 7 7~ *y 'E'EtyQQ (();<<< ##F+++#)  yr&cPtjd|jdS)Nr)r QTimer singleShot_emitRemoveRequestras r$r/zROI.removeClickeds#   D$;<<<<| | }|d |||d<d |_n|ddkr|dd|ddkrd|d<|dd|ddkrd|d<|js|tjjj zrPt%|d|jz |jz|d<t%|d|jz |jz|d<|ds|tjjjzr|| }|d| z }|ddkrd|d<|ddkrd|d<||z }|ddkr|dd|d<|ddkr|dd|d<|js:|ddkr|dd|d<|ddkr|dd|d<|jr |d|d<| |jdz}| |z}|||z |tddz }||d<|d|z|d<|j1||}|j|sdS||dd ||dd n|ddvr|ddkrd |_|jsdS |dks| dkrdSn#t<$rYdSwxYw|d| |z }|dS|j s|tjjj zrt%||j!z |j!z}tEj#}|$||| |%| |jdzz }||d<|d|z|d<|j1||}|j|sdS||dd |&|d |ddkrF|d |'| | | |d<n|ddkr |dks| dkrdSn#t<$rYdSwxYw|d| |z }|dS|j s|tjjj zrt%||j!z |j!z}|js|dd|ddkr|jdd|z| z |dd<|jr4t%|dd|j(z |j(z|dd<|js|dd|ddkr|jdd|z| z |dd<|jr4t%|dd|j(z |j(z|dd<|dddkr d|dd<|dddkr d|dd<| |dz}tEj#}|$||| |%||jdzz }||d<|d|z|d<|j1||}|j|sdS|)|d |*|dS)Nr-r.rZrzKNew point location must be given in either 'parent' or 'scene' coordinates.rrrTF)rrkrrnrrrrrj)r#rrr/rr)+r r4KeyboardModifier NoModifierr`rrFrsrGr rr mapFromParentControlModifierrrIr>rUrrV AltModifierprojrOr7rPrcontainsrKr9length OverflowErrorr/rSrTr rrrrJrrQrlr)rYrr-rLrcoordsrrrqp0p1rcslp0lp1rrhsrs0s1rr#angrrs r$ movePointz ROI.movePointBs~    2=I>>##""6** L    ahF);; < < 3ZZ X    w  &&r**BBijj j q==( ATZ''B$$R((2-C$$R((2-C V9  % (B(RR]44Y]D NN2b5tEN : : : : vY#  ''++F fI  V $ $ $AeH#'D vY#  {1~5!,,A{1~5!,,A~ Q)fi.H.X"X Qs1v(::;;d>PPAs1v(::;;d>PPA $9vy/I/U#U $hhsmm5AB!uzz1!uzz1BhGqzQ%f-a0 qzQ%f-a0 ? 51:>>!)&!1!!4GAJ1:>>!)&!1!!4GAJ  ($QZ TZ''BWB!!"r'**T-=-=eAqkk-J-JJB 'HV &uo2HUO~)NN8,,~..q11F KKK 6 6 6 LL&)%L 8 8 8 8 vY+ % %yD  '+$>  ::<<1$$ (9(9F):     7#ciinn4C{ O9vy/I/Y#Y OC$"6677$:NN!##B IIcNNN!!"%%dj6G)GHB #HW &uo2HUO~)NN8,,~..q11F KKK 6 6 6 MM#eM , , ,yD  &   !2!22!6!6777--b11% vY$   ::<<1$$ (9(9F):     7#ciinn4C{ O9vy/I/Y#Y OC$"6677$:NN  eAhKNahqk$A$A&*j&8&;cjjll&JSZZ\\&Y #>e*/0@0Cdm0S*T*TW[Wd*dHV$Q'  eAhKNahqk$A$A&*j&8&;cjjll&JSZZ\\&Y #>e*/0@0Cdm0S*T*TW[Wd*dHV$Q'"a''&' #"a''&' #Xf%%B!##B IIcNNN!!"%%dj6G)GHB #HW &uo2HUO~)NN8,,~..q11F MM(5M 1 1 1 (((((s$ 0R R R40Y'' Y54Y5cd}|jd}nQ|}t|D]}|||j|krd}||r|jD]M}|d|vr/|d|d|jdzN| |j |n!|j r|j |d|_ ||_|r*| |dSdS)zProcess changes to the state of the ROI. If there are any changes, then the positions of handles are updated accordingly and sigRegionChanged is emitted. If finish is True, then sigRegionChangeFinished will also be emitted.FNTrnr-r.)rHrblistkeysrrF childItemsrIrGrksigRegionChangedrr>rHinformViewBoundsChanged)rYrchangedrGkrqs r$rzROI.stateChangedsk  > !GGMMOOE%**,,'' # #8t~a000"G ""$$$  -\ D DV9 1 111fI$$QuX 60B%BCCC KKMMM  ! & &t , , , ,  ! -  ! & &t , , ,$  +  $ $ & & &  ( ( * * * * * + +r&c:|j|dSr_sigRegionChangeFinishedrras r$rHzROI.stateChangeFinished $))$/////r&cxtjdd|dd|dd}tj}||d ||}||dd|dd|dd|ddS)Nrr.rr/r-)r QRectFr rrmapRectadjusted)rYrGr#rs r$rz ROI.stateRects M!Qf a 0%-2B C C     5>/""" JJqMMzz%,q/5<?E%LOUSX\Z[_]]]r&c||dur#|j|St|j|j}tt|d|dz |dzt|d|dz |dzS)NTrr)rQr r)rYr-rs r$rzROI.getSnapPositions <44<<}$  66D #a&47" # #d1g - #a&47" # #d1g -   r&ctjdd|jdd|jddSNrr.r)r rprG normalizedras r$rtzROI.boundingRect-s<}Q4:f#5a#8$*V:LQ:OPP[[]]]r&cFtjdd|jdd|jdd}|t jjj|j | |j | | |||||dddddSru)r rprGrv setRenderHintr QPainter RenderHint Antialiasingr=r@rwrrrrr!r"drawRectrYpoptwidgetr#s r$paintz ROI.paint0s M!Q 6 21 5tz&7I!7L M M X X Z Z  N % 2 O    !!! AFFHHaeegg&&&  188::&&& 1aAr&rrc |j|d|j|df} |tj|z}n #tjjj$rYdSwxYw|j}|dkrg|t|d| z t|d| z nf|t|d| z t|d| z | | }|dkr7|tjdd|d|d} n6|tjdd|d|d} t#t%| | t#dt+| | zft#t%| | t#dt+| | zff} |dkr | ddd} |rYt1dg|jz} t1| d| |d<t1| d| |d<t5| |fS| |fS)aXReturn a tuple of slice objects that can be used to slice the region from *data* that is covered by the bounding rectangle of this ROI. Also returns the transform that maps the ROI into data coordinates. If returnSlice is set to False, the function returns a pair of tuples with the values that would have been used to generate the slice objects. ((ax0Start, ax0Stop), (ax1Start, ax1Stop)) If the slice cannot be computed (usually because the scene/transforms are not properly constructed yet), then the method returns None. rrN row-major)shapesceneTransformrAinvertQTransformnplinalg LinAlgError axisOrderrfloatr!r"rqrt intersectedr rpr'minrrmaxrrslicendimrf) rYdataimgr returnSlicedShaperr dataBounds intBoundsboundssls r$ getArraySlicezROI.getArraySlice<s*T!W%tz$q'':; $$&&)`. =================== ==================================================== This method uses :func:`affineSlice ` to generate the slice from *data* and uses :func:`getAffineSliceParams ` to determine the parameters to pass to :func:`affineSlice `. If *returnMappedCoords* is True, then the method returns a tuple (result, coords) such that coords is the set of coordinates used to interpolate values from the original data, mapped into the parent coordinate system of the image. This is useful, when slicing data from images that have been transformed, for determining the location of each value in the sliced data. All extra keyword arguments are passed to :func:`affineSlice `. fromBoundingRectF)rrvectorsorigin)rrrrT returnCoords)rgetAffineSliceParamsrA affineSlicetransformCoordinates transform)rYrrrreturnMappedCoordskwdsfromBR_shape_vectors_originrrrrgnresultrXmappeds r$getArrayRegionzROI.getArrayRegionqsJ,e44%)$=$=dC`f$=$g$g!'&))((9h//(G,,! ".fUGFY]ffaeffCJ#'D ^DqwW]dhqqlpqqNFF,S]]__fEEF6> !r&c @|rtj|||||fddi|\}}ntj|||||fddi|}|jdkr9||j|d|j|d}n?||j|d|j|d}|j}dg|jz} |j|d| |d<|j|d| |d<|| }|r||z|fS||zS)z Return the result of :meth:`~pyqtgraph.ROI.getArrayRegion`, masked by the shape of the ROI. Values outside the ROI shape are set to 0. See :meth:`~pyqtgraph.ROI.getArrayRegion` for a description of the arguments. rTz col-majorrr)rrrrenderShapeMaskrTrreshape) rYrrrrrsliced mappedCoordsmaskrs r$ _getArrayRegionForArbitraryShapez$ROI._getArrayRegionForArbitraryShapesg  Z#dC'9$Z$ZLP$ZTX$Z$Z FLL'dC'9ZZLPZTXZZF =K ' ''' T!W(=v|DQRG?TUUDD'' T!W(=v|DQRG?TUUD6Ddid1g.d1gd1g.d1g||E""  !D=,. .D= r&c "||urtd|||t jdd}|||t jdd|z }|||t jdd|z }t ||}t ||} d|z } d| z } || z|| zf|| z|| zff} |dur| | f} |||| }||f}n5|j d} ||f}t| d| z t| d| z g} |jdkr| ddd } | ddd } | | |fS) a Returns the parameters needed to use :func:`affineSlice ` (shape, vectors, origin) to extract a subset of *data* using this ROI and *img* to specify the subset. If *fromBoundingRect* is True, then the ROI's bounding rectangle is used rather than the shape of the ROI. See :func:`getArrayRegion ` for more information. z6ROI and target item must be members of the same scene.rrr(Tr.rNr)rr mapToData mapToItemr QPointFrrr rtr!r"topLeftrGabsr)rYrrrrrvxvylvxlvysxsyrrs r$rzROI.getAffineSliceParamssq ::<!Q3G3GHHII]]4>>#v~a/C/CDD E E N ]]4>>#v~a/C/CDD E E NBDDFFBDDFF##BDDFFBDDFF##3Y 3YDDFF2Irttvvby)BDDFF2Irttvvby+AB t # #%%''--//1B1B1D1D1K1K1M1MME]]4>>#t7H7H7J7J7R7R7T7T#U#UVVFhhjj&((**-FFJv&Ehhjj&((**-FU1Xb[!!3uQx{#3#34 =K ' 'dddmG$$B$KEgv%%r&c|dks|dkrtj||ftStj||tjjj}|tj j j tj |}| tjd|tjd|}|}|||z ||z || |||t6jdkrdnd}tj|d|fj}|tdz S) zReturn an array of 0.0-1.0 into which the shape of the item has been drawn. This can be used to mask array selections. r)dtypeNwlittle.r*) remptyrr QImageFormat Format_ARGB32fillr r4 GlobalColor transparentryr@rArBsetBrushmkBrushrrtrr!r"rrdrawPathendsys byteorderndarray_from_qimagerastype) rYr!r"imr~rrcidxrs r$rzROI.renderShapeMasks A::18UFO5999 9 \%)<)J K K  %1222 N2   $    2:c??### ##%%  V\\^^+RYY[[6==??-JKKK V^^%%%&&& 5 MX--qq1%b))#d(35{{5!!C''r&c||j}|}|d|d<|d|d<t|}t|}||z S)zReturn global transformation (rotation angle+translation) required to move from relative state to current state. If relative state isn't specified, then we use the state of the ROI when mouse is pressed.Nr.r)rrbr)rY relativeTostt1t2s r$getGlobalTransformzROI.getGlobalTransforms`  *J ]]__)0 7j7 * % % "  "u r&c|}|d|d<t|}||z}|d|d<||dS)Nr.r)rbrrhrl)rYrrs r$applyGlobalTransformzROI.applyGlobalTransformsc ]]__j7 "  2g " "[6  br&T)NTT)NNFTT)NFTT)NNNN)NNNNN)NNNFN)NNNr_)NTrZ)rT)rF)M__name__ __module__ __qualname____doc__r SignalobjectrmrrgrrAr8r r2rbr`rhrlrLrur@r.r-r/rIrKrJrrrrrrrrrrrrrrrrrrrrrrrrrr(r"r/r5r;rCrErIr@rMrbrrHrrrtrrrrrrrrrr&r$rr)s0^^@,fmF33*V]622$v}V,,!FM&))Mvv..J&v..!&q!CE#$t$t#t 77777777r      5555%%% DDD'''&&& (((----B(-(-(-(-T$-$-$-$-Loooo0C0C0Cdbbbb"///bbbb2bbbb,1111>tttt0uuuu8uuuu40       * * * M M M M Y Y Y Y111 777!!!&&&*!!! MMM>>>   ===+++111   ///  ))) n)n)n)n)` + + + +D000^^^     ^^^   3333j8"8"8"8"t!!!!@+&+&+&+&Z(((. r&rceZdZdZdejdz fdejdz fdddddZeje e Z eje Z dd Z d Z d ZdZdZdZdZdZdZdZdZddZdZdZdZdZdZdZdS)ra Handle represents a single user-interactable point attached to an ROI. They are usually created by a call to one of the ROI.add___Handle() methods. Handles are represented as a square, diamond, or circle, and are drawn with fixed pixel size regardless of the scaling of the view they are displayed in. Handles may be dragged to change the position, size, orientation, or other properties of the ROI they are attached to. )rr) r)rrrr#rrNrr+FTcpg|_||_||_tj||_tj||_|j|_d|_|j |\|_ |_ | d|_ ||_||_t#j|||t(jjj||_|r)|t(jjj|ddS)NF)rZ )rradiusrrArBr[rCrwrMtypessidesstartAng buildPathrr= buildMenur<rr2r3r r4r5r6 deletabler rL)rYrrr[rCrZrr]s r$r2zHandle.__init__@s  8C==** ( $(JsO! DM  #NN$$ V4444 $$VY%:%CDDD"  L  ( ()>)J K K K rr&c:|j|dSr_)rrrYrois r$rzHandle.connectROIVs r&c:|j|dSr_)rremovers r$rzHandle.disconnectROIZs r&c||_|r@||tjjjzdS||tjjjzdSr_)rr3rr r4r5r )rYbs r$ setDeletablezHandle.setDeletable]s{  k  ( ()B)B)D)DvyG\Gh)h i i i i i  ( ()B)B)D)D H]HiGi)i j j j j jr&c:|j|dSr_r7ras r$r/zHandle.removeClickeddr9r&cd}|s|tjjjrd}tjjjtjjjtjjjfD]0}||zr| |rd}1|r |j |_ n |j |_ | dSr)r r r r4r5r r r rrrCrwr[rkrs r$rzHandle.hoverEventgsyy{{ ~~fi3>??  -8&):O:[]c]f]r]A  --//#52??3;O;OE  '"mDOO"hDO r&cJ|tjjjkr@|jr9d|_||jd|dS| |zry||tjjjkr|j r| ||j ||dS|dSNFTr)r>r r4r5r rMrbstartPosr?rrr(rArrBr<s r$rCzHandle.mouseClickEventvs 99;;&)/; ; ; ;!DM NN4=N 6 6 6 IIKKKKK  & & ( (299;; 6  IIKKKyy{{fi3???DN?%%b))) O r * * * * * IIKKKKKr&ctj}|tdd|tdd|j|_|S)Nrrz Remove handle)r r*r+rr0r/ removeAction)rYr<s r$rzHandle.buildMenusS   ix00111 NN9UO+L+LdN`aa r&c|jSr_)r<ras r$r"zHandle.getMenus yr&c |}tfdjD}j||}|tj t| t| dS)Nc3BK|]}|VdSr_)r)rr#rYs r$ z*Handle.raiseContextMenu..s1II!A//55IIIIIIr&)rr#r"allrr setEnabledr$r%r r&r'rr )rYrr< removeAllowedr-s` r$r(zHandle.raiseContextMenuszz||11$ KKIIIItyIIIII  $$]333llnn 6=SUUWWs35577||<<=====r&c|tjjjkrdS||rM|jr|jD]}| d|_|j |_ | n| rx|jD]}|d|_||_||z |_|j|_ |jrT||jz}|j|_ |||ddSdSr)r>r r4r5r r?isFinishrMrrHr[rwrkisStartrrrbuttonDownScenePos cursorOffsetrCrbrL)rYrr#r-s r$r;zHandle.mouseDragEvents^ 99;;&)/: : : F  ;;== ,} ,,,A))++++!DM"hDO KKMMMM ZZ\\ ,Y & &##%%%% DM MMOODM $ "2G2G2I2I ID "mDO = >++--$"33C"mDO NN3 uN = = = = = > >r&c|tjjj}|jD]}||||sdS|jD]}|||||ddS)Nr)rrX)r r4rOrPrrMrb)rYr-rLrr#s r$rbzHandle.movePoints   2=I  A##D#y99   M MA KKc9VGK L L L L M Mr&c|j}tj|_|j}dt jz|jz }td|jD]h}|t|z}|t|z}||z }|dkr|j ||M|j ||i|j dS)Nrr)rr QPainterPathpathrrpirrangerrmoveTolineTo closeSubpath)rYr.radtrrr s r$rzHandle.buildPaths{&(( m Y #q$*%% ' 'As3xxAs3xxA 2ICAvv   A&&&&   A&&&&      r&c||jj|j||j||dSr_)rxrzr{r=r@rwrr)rYr~rrs r$rz Handle.paints[  L % O    !!! 4::<<     r&c|j8|}||jS||_||jSr_)r generateShaperr)rYrs r$rz Handle.shapesK ; ""$$Ayy DK  & & ( ( ({r&cv|}|Sr_rrt)rYr`s r$rtzHandle.boundingRects) ZZ\\zz||((***r&c|}||j|_dS|t jdd|t jddz }t ||}tj |}|t jdd}tj }| |||||||jS)Nrr)deviceTransformrrrr rrr rrArr rr rotateRadians)rYrvvadtidevPosrs r$rzHandle.generateShapes  ! ! # # :)DK4 FF6>!Q'' ( (266&.A2F2F+G+G G 13355!##%% !"%%q++,,     VXXZZ,,, wwrvvdi(()))r&cdtj|d|_|dSr_)rviewTransformChangedrrkras r$r)zHandle.viewTransformChangeds++D111  r&)Nrr+NFTr)rrrrrrrr rrrAr8r2rrrr/rrCrr"r(r;rbrrrrtrr)rr&r$rr)s  q\q\     Evv..J&v..->>>>>> M M M M ! ! !!!!   +++***$r&rceZdZdZdZdZdS)rWzJImplements default mouse drag behavior for ROI (not for ROI handles). c$||_d|_d|_tjjj|_tjjj|_ tjjj |_ tjjj |_ d|_d|_dS)N?g)\(?)rdragMode startStater r4rOrR snapModifierrPtranslateModifierrSrotateModifier ShiftModifier scaleModifier rotateSpeed scaleSpeedrs r$r2zMouseDragHandler.__init__sj "I6F!'!;!F$i8D#Y7Er&c^|j}|r|tjjjkrZ|d|} ||j z}n$#t$r||j zr ||j z}YnwxYw|j r||j krd|_ n;|jr||jkrd|_ n!|jr||jkrd|_ nd|_ |j ||||_||_||jz |_|n0|nd|_ ||r|j |dS|jr|j dS||j zrdnd}||}|j dkr9||jz}|||z |ddS|j dkr|j |!|"z #z}|jd|z }|$|||ddS|j dkr|j%|!|"z & z}|'tQ|jd |z||ddSdS) NTrrrF)rrr/)rrrr.))rrr>r r4r5r rrLr/ ValueErrorr8r0r-r9r1r:r3rErs buttonDownPosrrhr.r-rr?rBrrIrMrr4rrrrJr5r rKr ) rYrrmodsrr-rdiffr/s r$r;zMouseDragHandler.mouseDragEvent skh ::<< yy{{fi3>>>%%%||~~2T...DD!222d//2 112#)0F(F(F$/DMM])tt/B'B'B$,DMM])tt/A'A'A$+DMM$(DM=,$$&&&$'OOB4D4D4F4F$G$GDM&)mmooDO(+ DM(AD%IIKKKKIIKKKK $   ;;== T]6       F| t}4 F )::Ettoobffhh'' =K ' '4,,F MM&37799,4M F F F F F ]h & &#r{{}}r7L7L7N7N'N&Q&Q&S&SSDOG,t3E LLB,<,<,>,>TRWL X X X X X ]g % %? 8M8M8O8O(O'R'R'T'T&TTD KKdof566=2K[K[K]K]dhqvK w w w w w& %s4 BB! B!N)rrrrr2r;rr&r$rWrWsA   6x6x6x6x6xr&rWceZdZdZdS)rc tj|||fi||ddg|ddgddg|ddgddg|ddgddg|ddgddg|ddgddg|ddgddgdS)Nr,rr)rr2rrrrrYr-r.rxs r$r2zTestROI.__init__Fs T3----- c +++ QFQF+++ QFQF+++ !!1c(S#J777 S!HsCj111 aVaV,,, aVaV,,,,,r&Nrrrr2rr&r$rrEs#-----r&rceZdZdZddZdS)ra Rectangular ROI subclass with a single scale handle at the top-right corner. ============== ============================================================= **Arguments** pos (length-2 sequence) The position of the ROI origin. See ROI(). size (length-2 sequence) The size of the ROI. See ROI(). centered (bool) If True, scale handles affect the ROI relative to its center, rather than its origin. sideScalers (bool) If True, extra scale handles are added at the top and right edges. \**args All extra keyword arguments are passed to ROI() ============== ============================================================= Fc tj|||fi||rddg}nddg}|ddg||rB|ddg|ddg|ddgd|dgdSdS)Nr,rr)rr2r)rYr-r.centered sideScalersrxrs r$r2zRectROI.__init__bs T3-----  3ZFFVF QFF+++  <   C6!9c*: ; ; ;   a3q *: ; ; ; ; ; < tj|||_||_g|_t |dkrtd||d|dd|ddD]}||dS)Nrz!Must start with at least 2 pointsrrT) connectTo scaleHandle) r QGraphicsObjectr2r[roiArgslinesrr addSegment)rYpointsr!r[rxr~s r$r2zMultiRectROI.__init__s!**4000  v;;???@@ @ q VAYDIII  A OOA      r&cdSr_r)rYrxs r$rzMultiRectROI.paint r&c(tjSr_)r rpras r$rtzMultiRectROI.boundingRects}r&c |jdjdd}|jddD]:}|jdd}||kr|d||z gddg;|j|dS)Nrr.rr(r,)r)rSrGrrgr)rYrrKw0s r$roiChangedEventzMultiRectROI.roiChangedEvents JqM  ' *ABB 3 3A#BBww GGS!B$KS G 2 2 2 2 ""4(((((r&c:|j|dSr_)rrras r$roiChangeStartedEventz"MultiRectROI.roiChangeStartedEvents #((.....r&c:|j|dSr_rlras r$roiChangeFinishedEventz#MultiRectROI.roiChangeFinishedEventrnr&cT||jddg}|jD]T}|||dU|S)z9Return the positions of all handles in local coordinates.rr)rrSrrr)rYr-rKs r$getHandlePositionszMultiRectROI.getHandlePositionss  A!9!9!;!;A!>!G!G!I!IJJK H HA JJt(():)C)C)E)EFF G G G G r&rc  g}|jD]+}|j||fdi|}|||,|jdkr dddt fd|D}t dg|djz t d| d< fd|D}tj|d S) a@ Return the result of :meth:`~pyqtgraph.ROI.getArrayRegion` for each rect in the chain concatenated into a single ndarray. See :meth:`~pyqtgraph.ROI.getArrayRegion` for a description of the arguments. Note: ``returnMappedCoords`` is not yet supported for this ROI type. rNrrc6g|]}|jdSr)r)rr#rs r$rz/MultiRectROI.getArrayRegion..s$111q!'$q'"111r&rrc:g|]}|tSr)rf)rr#rs r$rz/MultiRectROI.getArrayRegion..s#+++%)) +++r&)axis) rSrrrrrrr concatenate) rYarrrrrrgnsrKrmsrs ` @r$rzMultiRectROI.getArrayRegions  A"!"3??$?$??C{ KK     =K ' '":D 1111D111 2 2Dkk]T!W\ )Abkk47 ++++d+++~da1111r&rrFc|%|jdd}tdddgf||jd|j}|j|t |trR|jdddgddg| | || d n=|jdddgddg}| ||d |jdddgddg}| |||r| ddgddgd |_ |j |j|j|j|j|j|j |dS) z Add a new segment to the ROI connecting from the previous endpoint to *pos*. (pos is specified in the parent coordinate system of the MultiRectROI) Nrrrkr1)rZr[rr,rr)rXF)rSrrr[rRrrrrrbrrr8rgr.r[rr]rmr_r)rYr-rPrOnewRoirqs r$rTzMultiRectROI.addSegments   21133A6IUQFN4TXNNNN &!!! i ( ( ; JrN / /C1c( / S S S   Y (:(:(<(rr&r$rrs({{{{{r&rc8eZdZdZdZdZdZdZd d Zd Z dS) ra Elliptical ROI subclass with one scale handle and one rotation handle. ============== ============================================================= **Arguments** pos (length-2 sequence) The position of the ROI's origin. size (length-2 sequence) The size of the ROI's bounding rectangle. \**args All extra keyword arguments are passed to ROI() ============== ============================================================= c d|_tj|||fi||j|j|dSr_)rrr2rgr. _clearPath _addHandlesr=s r$r2zEllipseROI.__init__/sV  T3----- %%do666 r&cn|ddgddg|ddgddgdS)Nr(r,?3OP?)rrras r$rxzEllipseROI._addHandles5sG c3Z#s444 /1CDsCjQQQQQr&cd|_dSr_)rras r$rwzEllipseROI._clearPath9s  r&c(|}|tjjj|j||j| | | tj || z || z dd}||dSr)rtrxr ryrzr{r=r@rwrr!r"r rprr drawEllipser}s r$rzEllipseROI.paint<s       N % 2 O    !!!  188::&&& M!##%% /13355+;Qq A A ar&NrFc  |rtj||||fi|\}}ntj||||fi|}|.|jddks|jddkr|r||fS|S|jd |jd tj fd f}ddkr|j}fdt |jD}||}|r||z|fS||zS)aV Return the result of :meth:`~pyqtgraph.ROI.getArrayRegion` masked by the elliptical shape of the ROI. Regions outside the ellipse are set to 0. See :meth:`~pyqtgraph.ROI.getArrayRegion` for a description of the arguments. Note: ``returnMappedCoords`` is not yet supported for this ROI type. Nrrcftj|dzdz z dz |dzdz z dz dkS)Nr,rHr)rr)rr rqrs r$z+EllipseROI.getArrayRegion..cs?28aead^A5E!C%RSTVRVXYIY+[+[^_+_r&c&g|] \}}|vr|ndSrdr)rrnrs r$rz-EllipseROI.getArrayRegion..hs)IIISQqqDyy!!aIIIr&)rrrr fromfunctionrrr) rYrhrrrrrrrrqrs ` @@r$rzEllipseROI.getArrayRegionHst  @"1$S$2D N NHL N N 3 #D#sD$6@@:>@@3 ;#)DG,11SYtAw5G15L5L! L(( Id1g  Id1g _____bcefaghh 7T!W  6DIIIIIci4H4HIII||E""  :|+ +: r&c|jOtj}|}|}|dz }|dz }tjddtj zd}| |tj |zz}| |tj |zz}||d|dtdt!|D]$} ||| || %||_|jS)NrHrrr)rr rrtrr!r"rlinspacerrrr rrrrr) rYrbrrr1r2thetarr rs r$rzEllipseROI.shapeps 9 %''D""$$BYY[[FbBr!BK1ru9b11E R"&--//A R"&--//A KK!ad # # #1c!ff%% ( ( AaD!A$''''DIyr&)NrF) rrrrr2rxrwrrrrr&r$rr"s   RRR   &&&&Pr&rc eZdZdZddZdZdS)ra" Circular ROI subclass. Behaves exactly as EllipseROI, but may only be scaled proportionally to maintain its aspect ratio. ============== ============================================================= **Arguments** pos (length-2 sequence) The position of the ROI's origin. size (length-2 sequence) The size of the ROI's bounding rectangle. \**args All extra keyword arguments are passed to ROI() ============== ============================================================= Nc l||td|dz|dzf}tj|||fddi|dS)Nz#Must provide either size or radius.rr7T)rrr2)rYr-r.rrxs r$r2zCircleROI.__init__sU <~ EFFF1HfQh'DD#tGG$G$GGGGGr&c:|ddgddgdS)Nrzr,)rras r$rxzCircleROI._addHandless) /1CDsCjQQQQQr&NN)rrrrr2rxrr&r$rrsJ  HHHHRRRRRr&rceZdZdZddZddZdZdZdZd Z dd Z d Z dd Z dd Z ddZdZdZdZdZdZdZdZdS)rah Container class for multiple connected LineSegmentROIs. This class allows the user to draw paths of multiple line segments. ============== ============================================================= **Arguments** positions (list of length-2 sequences) The list of points in the path. Note that, unlike the handle positions specified in other ROIs, these positions must be expressed in the normal coordinate system of the ROI, rather than (0 to 1) relative to the size of the ROI. closed (bool) if True, an extra LineSegmentROI is added connecting the beginning and end points. \**args All extra keyword arguments are passed to ROI() ============== ============================================================= FNc |ddg}||_g|_tj||fdddgi|||dSru)closedsegmentsrr2 setPoints)rYrrr-rxs r$r2zPolyLineROI.__init__sY ;Q%C   T333aU3d333 y!!!!!r&cP|||_||D]}|||jrdnd}t|t |jdz D]=}||j|d|j|dzd>dS)a? Set the complete sequence of points displayed by this ROI. ============= ========================================================= **Arguments** points List of (x,y) tuples specifying handle locations to set. closed If bool, then this will set whether the ROI is closed (the last point is connected to the first point). If None, then the closed mode is left unchanged. ============= ========================================================= Nrrrrn)r clearPointsrrrrFrT)rYrUrr~startrs r$rzPolyLineROI.setPointss   DK  " "A   q ! ! ! !k(quc$,//122 P PA OODLOF3T\!A#5Fv5N O O O O P Pr&ct|jdkr@||jddt|jdk>dSdS)z2 Remove all handles and segments. rrnN)rrFrras r$rzPolyLineROI.clearPointss[$,!##   dl1of5 6 6 6$,!######r&ct|}|j|d<d|D|d<|S)NrcPg|]#}t|$Srr r-rs r$rz(PolyLineROI.getState..&EEEa5>>EEEr&rU)rrbrrrgs r$rbzPolyLineROI.getStatesD T""+hEE4??3D3DEEEh r&ct|}|j|d<d|D|d<|S)NrcPg|]#}t|$Srrfr-rs r$rz)PolyLineROI.saveState..rr&rU)rrhrrrgs r$rhzPolyLineROI.saveStatesD d##+hEE4??3D3DEEEh r&ct||||d|ddS)NrUr)r)rrlrrgs r$rlzPolyLineROI.setStates: T5!!! uXuX?????r&ct||f|j|j|d|j}||j|n|j|||j|j | tj j j||dz|jD]g}|dd|d |dtj j jzhdS)NF)rFr[rCrZr\r]rrnT)_PolyLineSegmentr[rCr=rrrrAr.segmentClickedr3r r4r5r rLrrFrr)rYh1h2rsegrqs r$rTzPolyLineROI.addSegments*BxTX &*ET_VVV = M  % % % % M  , , , t2333 ##FI$9$DEEE dkkmmAo&&& s sA fI " "4 ( ( ( fI - -ai.L.L.N.NQWQZQfQq.q r r r r s sr&czt|||jD]}||dSr_)rrrsetParentHover)rYrrs r$rzPolyLineROI.setMouseHoversJ $&&& $ $A  U # # # # $ $r&ct|||}|j|j|d|S)NrTr)rrr8r.rrrs r$rzPolyLineROI.addHandlesO MM$EM 2 2 $$T%6777 &&&r&c|(||}n|td|jdd}|j|}||||}||||dz| ||dS)Nz,Either an event or a position must be given.rrnr) rsr-rrFrrrrrTr)rYsegmentrr-rrh3s r$rzPolyLineROI.segmentClicked s >%%bffhh//CC [JKK K _Q  ' M   ( (   4+=+=b+A+A  B B Bac***b"%%%%%r&Tc"t|||j|j|sdS|jdd}t |dkr||dn|t |dkrid|djD}|||d ||d||d| ddS)Nrrcg|] }|d Srrrs r$rz,PolyLineROI.removeHandle..!s>>>Qqy>>>r&Tr) rrr8rorrrprFrrr)rYrupdateSegmentsrrFs r$rzPolyLineROI.removeHandles  v&&&!,,T->???  F;qqq> x==A     x{ + + + + ]]Q  >>(1+*=>>>G NN6 " " " QK % %fgaj 9 9 9   x{ + + + &&&&&r&c |jddD]}||d|j||j|j||dSr) rFrrrrArorrr)rYrrs r$rpzPolyLineROI.removeSegment'sk!!!n - -F   VF^ , , , , S!!! !!$"5666 $$$$$r&cp|jrt|jdkSt|jdkS)Nrr)rrrF)rYrqs r$rzPolyLineROI.checkRemoveHandle.s6 ; )t|$$q( (t|$$q( (r&cdSr_r)rYr~rxs r$rzPolyLineROI.paint5rWr&cN|Sr_r ras r$rtzPolyLineROI.boundingRect8zz||((***r&ctj}t|jdkr|S||jddt t|jD]:}||j|d;||jdd|S)Nrrn)r rrrFrr-rr)rYr~rs r$rzPolyLineROI.shape;s    t|   ! !H a(,,..///s4<(()) 4 4A HHT\!_V,0022 3 3 3 3 a(,,..///r&c|j|i|Sr_rrts r$rzPolyLineROI.getArrayRegionE4t4dCdCCCr&c^tj|g|Ri||jD]}|j|i|dSr_)rr@r)rYrxrrs r$r@zPolyLineROI.setPenHsW 4'$'''$'''= & &C CJ % % % % % & &r&)FNr_rr)rrrrr2rrrbrhrlrTrrrrrprrrtrrr@rr&r$rrsX$ " " " "PPPP2777  @@@ s s s s$$$  & & & &''''"%%%)))   +++DDD&&&&&r&rcbeZdZdZddZedZdZdZdZ d Z d Z d Z d Z ddZdS)ra ROI subclass with two freely-moving handles defining a line. ============== ============================================================= **Arguments** positions (list of two length-2 sequences) The endpoints of the line segment. Note that, unlike the handle positions specified in other ROIs, these positions must be expressed in the normal coordinate system of the ROI, rather than (0 to 1) relative to the size of the ROI. \**args All extra keyword arguments are passed to ROI() ============== ============================================================= rNc |ddg}tj||ddgfi|t|dkrtdt |D]"\}}||||#dS)NrrrzXLineSegmentROI must be defined by exactly 2 positions. For more points, use PolyLineROI.r)rr2rrrr)rYrr-rFrxrr~s r$r2zLineSegmentROI.__init__^s ;Q%C T31..... y>>A  vww wi(( 3 3DAq   qwqz  2 2 2 2 3 3r&c$d|jDS)Ncg|] }|d Srrrs r$rz,LineSegmentROI.endpoints..lrr&rras r$ endpointszLineSegmentROI.endpointsis104<0000r&c$d|jDS)NcBg|]}|dSr)r-)rr~s r$rz-LineSegmentROI.listPoints..os$666A& 666r&rras r$ listPointszLineSegmentROI.listPointsns666666r&c|t|}d|D|d<|S)NcPg|]#}t|$Srrrs r$rz+LineSegmentROI.getState..srr&rU)rrbrrgs r$rbzLineSegmentROI.getStateqs9 T""EE4??3D3DEEEh r&c|t|}d|D|d<|S)NcPg|]#}t|$Srrrs r$rz,LineSegmentROI.saveState..xrr&rU)rrhrrgs r$rhzLineSegmentROI.saveStatevs9 d##EE4??3D3DEEEh r&ct|||ddd|ddz|ddd|ddzg}|ddd|ddz|ddd|ddzg}||d|d||d|dS)NrUrr-rFr)rrlrbr)rYrGrZp2s r$rlzLineSegmentROI.setState{s T5!!!Hoa #E%LO3U8_Q5G5J5QV>> t((+R00000r&c@|tjjj|j||j|jd }|jd }| ||dS)Nrr) rxr ryrzr{r=r@rwrr-drawLine)rYr~rxrrs r$rzLineSegmentROI.paints  N % 2 O    !!! ^A  " " $ $ ^A  " " $ $ 2rr&cN|Sr_r ras r$rtzLineSegmentROI.boundingRectrr&ctj}|jd}|jd}||z }|dkr|S||d}||S|dz}|||z|||z|||z |||z |||z|S)Nrrr)r rrr-rV pixelVectorsrr)rYr~rrdhpxvs r$rzLineSegmentROI.shapes    ^A  " " $ $ ^A  " " $ $ U 99;;!  H##A& ;H q C C C C Cr&rrFc JfdjD}t|d|dz }t|d} tj|ft |ft|g| |||d|} | S)aT Use the position of this ROI relative to an imageItem to pull a slice from an array. Since this pulls 1D data from a 2D coordinate system, the return value will have ndim = data.ndim-1 See :meth:`~pyqtgraph.ROI.getArrayRegion` for a description of the arguments. c`g|]*}|+Sr)rr-)rrqrrYs r$rz1LineSegmentROI.getArrayRegion..s/GGG1$..aeegg..GGGr&rr)rrrrorderr)rr rArr'rVnorm) rYrrrrrrimgPtsrors ` ` r$rzLineSegmentROI.getArrayRegionsHGGGGGGG &)fQi' ( ( &)  nTc#ahhjj//);eAFFHHooEV_`gksxHZcc^bcc r&)rNr)rrF)rrrrr2propertyrrrbrhrlrrtrrrr&r$rrOs   3 3 3 311X1777  111+++,r&rc&eZdZdZdZdZdZdS)rc>d|_tj|g|Ri|dSrG)_parentHoveringrr2rts r$r2z_PolyLineSegment.__init__s1$4t444t44444r&cV|j|kr||_|dSdSr_)rrrs r$rz_PolyLineSegment.setParentHovers8  5 ( (#(D  " " $ $ $ $ $ ) (r&c:|js|jr|jS|jSr_)r?rrCr[ras r$rz_PolyLineSegment._makePens&   !5 = 8Or&c|jr)|tjjjt||Sr_) parentItemr8r r r4r5r rrr<s r$rz_PolyLineSegment.hoverEventsI ??   ) = NN690; < < <((r222r&N)rrrr2rrrrr&r$rrsP555%%%  33333r&rc2eZdZdZddZdZdZdZdZdS) rzzA crosshair ROI whose position is at the center of the crosshairs. By default, it is scalable, rotatable and translatable.Nc |ddg}|ddg}d|_tj|||fddi||j|j|tddtdddS)Nrrr7T)rrr2rgr. invalidaterr )rYr-r.rs r$r2zCrosshairROI.__init__s <AD ;Q%C  T3AA4A5AAA %%do666 !!%1++uQ{{;;;;;r&c<d|_|dSr_)rrras r$rzCrosshairROI.invalidates!  ""$$$$$r&cN|Sr_r ras r$rtzCrosshairROI.boundingRectrr&cz|j-|dd}tj}|t d| |t d||t | d|t |d||}tj}| d| |}| ||_|jS)Nr.rrr0) rrbr rrr r mapToDeviceQPainterPathStrokersetWidth createStroke mapFromDevice)rYrr~strokeroutlines r$rzCrosshairROI.shapes ; ]]__V,Q/F"$$A HHU1vg&& ' ' ' HHU1f%% & & & HHUF7A&& ' ' ' HHU61%% & & &  ##A/11G   R **1--G,,W55DK{r&c|dd}|tjjj|j||j| td| td|| t| dt|ddS)Nr.rr) rbrxr ryrzr{r=r@rwrr )rYr~rxrs r$rzCrosshairROI.paints(+  N % 2 O    !!! 5VG$$eAv&6&6777 5&!$$eFA&6&677777r&r) rrrrr2rrtrrrr&r$rrspEE < < < <%%%+++ 88888r&rceZdZdZdZdS)RulerROIctj||g|R|jdd}|jdd}||}||}t |t |z }|}|t dd} ||z } t | | } d||zz| dz| z z} | tj |dd| zz} |tj| d z | d z d d tjjj| dS) Nrrnrr,(m)suffixz %0.1f deg2d)rrrFr-rrr rVr/r rresetTransformrAsiFormatdrawTextr rpr4 AlignmentFlag AlignCenter)rYr~rxrrrZrvecrVr/pvecpvecTr-txts r$rzRulerROI.paint sT1,t,,,, \!_V $ ( ( * * \!_V $ ( ( * * [[]]  r " " [[]]  r " "Bii%))# %1++&&Bwdffhh **R"Wo U\\^^ ;; k&--- 0EE 6=SUUWWRZcBBFID[Dgilmmmmmr&ct|}|tddg}||Sd|z}|ddddS)Nrrri)rrt pixelLengthr rr)rYr#pxlpxws r$rtzRulerROI.boundingRect s]  ' ' - -uaV}}-- ;H3hzz#sB+++r&N)rrrrrtrr&r$rr s5nnn(,,,,,r&rc*eZdZdZdZdZdZdZdS)ra Equilateral triangle ROI subclass with one scale handle and one rotation handle. Arguments pos (length-2 sequence) The position of the ROI's origin. size (float) The length of an edge of the triangle. \**args All extra keyword arguments are passed to ROI() ============== ============================================================= c tj||||gfddi|tjdtjdzdz d}tjtj|tj|fjdzdz }tj |_ |D](}|j tj|)||dddg||d ddgdS) Nr7Trrrr(rHr,r)rr2rrrarrayrrrr QPolygonFpolyrr rrr)rYr-r.rxangles verticiesrs r$r2zTriangleROI.__init__+ s T3t HH4H4HHHQ A q11Xrvf~~rvf~~>??ACG3N O%%  2 2B I  V^R0 1 1 1 1 Yq\C:666 IaL3*55555r&ch|}|tjjj|j||| | |j | |j dSr_)rtrxr ryrzr{r=rr!r"r@rw drawPolygonr)rYr~rxr#s r$rzTriangleROI.paint5 s       N % 2 O     188::&&& !!! di     r&cftj|_|}tj}||||j|j | |jSr_) r rrrtrrr!r" addPolygonrr)rYr#rs r$rzTriangleROI.shape? s&((           188::&&& TY'''uuTYr&c|j|i|Sr_rrts r$rzTriangleROI.getArrayRegionH rr&N)rrrrr2rrrrr&r$rr! s_666!!!   DDDDDr&r)+rrmathrrrrrnumpyrr rAr r4r r r rrrQCoreApplicationr__all__r%rrrrWrrrrQrrrrrrrrrrrr&r$rs   00000000000000))))))))))''''''************  # -    III}}}}}.}}}@(RRRRR^RRRjDxDxDxDxDxvDxDxDxN - - - - -c - - -<<<<