def update_virtual_detector_shape(self): """ Virtual detector shapes are mapped to integers, following the IDs assigned to the radio buttons in VirtualDetectorWidget in dialogs.py. They are as follows: 1: Rectangular 2: Circular 3: Annular """ detector_shape = self.settings.virtual_detector_shape.val x,y = self.diffraction_space_view.shape x0,y0 = x/2, y/2 xr,yr = x/10,y/10 # Remove existing detector if hasattr(self,'virtual_detector_roi'): self.diffraction_space_widget.view.scene().removeItem(self.virtual_detector_roi) if hasattr(self,'virtual_detector_roi_inner'): self.diffraction_space_widget.view.scene().removeItem(self.virtual_detector_roi_inner) if hasattr(self,'virtual_detector_roi_outer'): self.diffraction_space_widget.view.scene().removeItem(self.virtual_detector_roi_outer) # Rectangular detector if detector_shape==0: self.virtual_detector_roi = pg.RectROI([int(x0-xr/2),int(y0-yr/2)], [int(xr),int(yr)], pen=(3,9)) self.diffraction_space_widget.getView().addItem(self.virtual_detector_roi) self.virtual_detector_roi.sigRegionChangeFinished.connect(self.update_real_space_view) # Circular detector elif detector_shape==1: self.virtual_detector_roi = pg.CircleROI([int(x0-xr/2),int(y0-yr/2)], [int(xr),int(yr)], pen=(3,9)) self.diffraction_space_widget.getView().addItem(self.virtual_detector_roi) self.virtual_detector_roi.sigRegionChangeFinished.connect(self.update_real_space_view) # Annular dector elif detector_shape==2: # Make outer detector self.virtual_detector_roi_outer = pg.CircleROI([int(x0-xr),int(y0-yr)], [int(2*xr),int(2*yr)], pen=(3,9)) self.diffraction_space_widget.getView().addItem(self.virtual_detector_roi_outer) # Make inner detector self.virtual_detector_roi_inner = pg.CircleROI([int(x0-xr/2),int(y0-yr/2)], [int(xr),int(yr)], pen=(4,9), movable=False) self.diffraction_space_widget.getView().addItem(self.virtual_detector_roi_inner) # Connect size/position of inner and outer detectors self.virtual_detector_roi_outer.sigRegionChangeFinished.connect(self.update_annulus_pos) self.virtual_detector_roi_outer.sigRegionChangeFinished.connect(self.update_annulus_radii) self.virtual_detector_roi_inner.sigRegionChangeFinished.connect(self.update_annulus_radii) # Connect to real space view update function self.virtual_detector_roi_outer.sigRegionChangeFinished.connect(self.update_real_space_view) self.virtual_detector_roi_inner.sigRegionChangeFinished.connect(self.update_real_space_view) else: raise ValueError("Unknown detector shape value {}. Must be 0, 1, or 2.".format(detector_shape)) self.update_virtual_detector_mode() self.update_real_space_view()
def request_manual_adjustment(self): """ The user drags a circular ROI from the detected tip to the real tip.The ROI center is the tip location. We first check if a roi already exists, if so, we recycle it. If the tip ROI got removed then we place it back to its last known position. """ self.request_pause_button.setChecked(True) self.toggle_pauselive() self.clearROIs() coords = self.backend.pipette_coordinates_pair[1] if all(values is None for values in coords): coords = (0, 0) else: coords = (coords[0] - 30, coords[1] - 30) if not self.roimanager.contains('tip'): target = pg.CircleROI(pos=coords, radius=30, movable=True, pen=QPen(QColor(255, 0, 255), 0)) target.setZValue(10) self.roimanager.addROI('tip') self.liveView.addItem(target) else: idx = self.roimanager.giveROIindex('tip')[-1] self.liveView.addedItems[idx].translatable = True self.liveView.addedItems[idx].setPen(QPen(QColor(255, 0, 255), 0))
def zLineChanged(self): print('zLineChanged') #(ind, time) = self.timeIndex(self.ui.timeSlider) if self.ignoreZLine: return (ind, time) = self.layerIndex(self.zLine) print('ind') print(ind) print('time') print(time) print('zLineValue') print(self.zLine.value()) if ind != self.currentLayer: self.currentLayer = ind self.updateImage() #self.timeLine.setPos(time) #self.emit(QtCore.SIGNAL('timeChanged'), ind, time) self.sigTimeChanged.emit(ind, time) #remove old rois for croi in self.aaroi: self.view.removeItem( croi) #change layer number in textbox self.ui.ztext.setText(str(self.currentLayer)) #re-draw rois for the new layer for ckey in self.aroi.keys(): croi = self.aroi[ckey] if self.currentLayer in croi.keys(): #pdb.set_trace() if len(self.aroi[ckey][self.currentLayer]) == 2: self.aaroi.append(pg.CircleROI(self.circlePosition(self.aroi[ckey][self.currentLayer]), [self.markerRadius, self.markerRadius])) else: self.aaroi.append(pg.PolyLineROI(self.aroi[ckey][self.currentLayer], closed= True)) self.view.addItem(self.aaroi[-1])
def mouseClicked(self, pos): #pdb.set_trace() print('mouseClicked') print(QtCore.Qt.NoButton) print(pos.button()) #pdb.set_trace() self.view.scene() if self.ui.radioSinglePoint.isChecked(): mousePoint = self.view.mapSceneToView(pos.scenePos()) print('adding single point to roi list') #self.aroi.append([mousePoint.x(), mousePoint.y()]) testname = 0 while testname in self.aroi.keys(): testname += 1 self.aroi[testname] = {self.currentLayer : [mousePoint.x(), mousePoint.y()]} self.aaroi.append(pg.CircleROI(self.circlePosition([mousePoint.x(), mousePoint.y()]), [self.markerRadius,self.markerRadius], pen = (4,9))) self.view.addItem(self.aaroi[-1]) if self.ui.radioPolygon.isChecked(): mousePoint = self.view.mapSceneToView(pos.scenePos()) if pos.button() == 1: print('adding point to polygon') self.croi.append([mousePoint.x(), mousePoint.y()]) elif pos.button() == 2: print('finished polygon and adding to roi list') self.aroi.append(self.croi.append([mousePoint.x(), mousePoint.y()])) self.croi = []
def create_rois(self): """ """ xy_pixels = self.trajs.loc[:, ['x', 'y', 'w']] / self.scale_factor labels = xy_pixels.index.get_level_values('label').unique().tolist() # Setup color gradient for segment labels id_labels = np.arange(len(labels)) id_labels = id_labels / id_labels.max() * 255 cmap = plt.get_cmap(self.cmap) colors = [ cmap(int(l), alpha=self.alpha, bytes=True) for l in id_labels ] for t_stamp, peaks in xy_pixels.groupby(level='t_stamp'): for (t_stamp, label), peak in peaks.iterrows(): color = colors[labels.index(label)] pen = pg.mkPen(color=color) roi = pg.CircleROI( (peak['y'] - peak['w'] / 2, peak['x'] - peak['w'] / 2), peak['w'], pen=pen, movable=True, scaleSnap=False) roi.label = label roi.t_stamp = t_stamp if t_stamp not in self.overlay_rois.keys(): self.overlay_rois[t_stamp] = [] self.overlay_rois[t_stamp].append(roi)
def request_selecttarget(self): """ The user drags a circular ROI on top of the target cell. The ROI center is the target. We first check if a target already exists, if so, we recycle it. If the target ROI got removed then we place it back to its last known position. """ self.request_pause_button.setChecked(True) self.toggle_pauselive() coords = self.backend.target_coordinates if coords[0] is None and coords[1] is None: coords = (0, 0) else: coords = (coords[0] - 60, coords[1] - 60) if not self.roimanager.contains('target'): target = pg.CircleROI(pos=coords, radius=60, movable=True, pen=QPen(QColor(255, 255, 0), 0)) target.setZValue(10) self.roimanager.addROI('target') self.liveView.addItem(target) else: idx = self.roimanager.giveROIindex('target')[-1] self.liveView.addedItems[idx].translatable = True self.liveView.addedItems[idx].setPen(QPen(QColor(255, 255, 0), 0))
def add_circ_mask(self): new_roi = pg.CircleROI( pos=self.resolution / 2, size=self.resolution / 10, pen=pg.mkPen("r", width=4), ) self.viewer.addItem(new_roi) self.circ_masks.append(new_roi)
def change(self): self.col+=1 print self.col self.roiAll.append(pg.CircleROI([5, 5, 0], [20, 20], pen=(self.col, 15))) self.roiAll[len(self.roiAll) - 1].sigRegionChanged.connect(self.update) self.imv.addItem(self.roiAll[len(self.roiAll) - 1]) self.roiPos.append([5, 5, 0]) self.roiSize.append([20, 20]) print self.roiPos
def setupImageTab(self, options): self.imageTab.ci.layout.setContentsMargins(0, 0, 0, 0) self.image = pg.ImageItem(border=pg.mkPen('k')) self.imageTab.addViewBox(**options).addItem(self.image) pen = pg.mkPen('w', width=3) hoverPen = pg.mkPen('y', width=3) self.roi = pg.CircleROI([100, 100], radius=100., parent=self.image) self.roi.setPen(pen) self.roi.hoverPen = hoverPen self.roi.removeHandle(0)
def setROI(self, shape): make = [pg.LineROI, pg.RectROI] roi = None if shape == 0: roi = pg.LineROI([0, 60], [20, 80], width=1, pen=(1, 9)) elif shape == 1: roi = pg.RectROI([20, 20], [20, 20], pen=(0, 9)) else: roi = pg.CircleROI([80, 50], [20, 20], pen=(4, 9)) self.rois.append(roi) self.view.addItem(roi)
def pg_point_roi(view_box): """ Point selection. Based in pyqtgraph, and returns a pyqtgraph CircleROI object. This object has a sigRegionChanged.connect() signal method to connect to other functions. """ circ_roi = pg.CircleROI((-0.5, -0.5), (2, 2), movable=True, pen=(0, 9)) h = circ_roi.addTranslateHandle((0.5, 0.5)) h.pen = pg.mkPen('r') h.update() view_box.addItem(circ_roi) circ_roi.removeHandle(0) return circ_roi
def _setup(self): CrosshairBase._setup(self) x, y, radius = self.model.x, self.model.y, self.model.radius self.roi = pg.CircleROI([x - radius, y - radius], size=[2 * radius, 2 * radius], movable=False, rotatable=False, resizable=True, removable=False, pen='k') self.plot_item.addItem(self.roi)
def updateMaskingMode(self, data): self.maskingMode = data if self.maskingMode == 0: # display text self.parent.label.setText("") # do not display user mask self.displayMask() # remove ROIs self.parent.img.win.getView().removeItem(self.mask_rect) self.parent.img.win.getView().removeItem(self.mask_circle) self.parent.img.win.getView().removeItem(self.mask_poly) else: # display text self.parent.label.setText(self.masking_mode_message) # display user mask self.displayMask() # init masks if self.mask_rect is None: # Rect mask self.mask_rect = pg.ROI(pos=[-300, 0], size=[200, 200], snapSize=1.0, scaleSnap=True, translateSnap=True, pen={'color': 'r', 'width': 4}) self.mask_rect.addScaleHandle([1, 0.5], [0.5, 0.5]) self.mask_rect.addScaleHandle([0.5, 0], [0.5, 0.5]) self.mask_rect.addScaleHandle([0.5, 1], [0.5, 0.5]) self.mask_rect.addScaleHandle([0, 0.5], [0.5, 0.5]) self.mask_rect.addScaleHandle([0, 0], [1, 1]) # bottom,left handles scaling both vertically and horizontally self.mask_rect.addScaleHandle([1, 1], [0, 0]) # top,right handles scaling both vertically and horizontally self.mask_rect.addScaleHandle([1, 0], [0, 1]) # bottom,right handles scaling both vertically and horizontally self.mask_rect.addScaleHandle([0, 1], [1, 0]) # Circular mask self.mask_circle = pg.CircleROI([-300, 600], size=[200, 200], snapSize=1.0, scaleSnap=True, translateSnap=True, pen={'color': 'r', 'width': 4}) self.mask_circle.addScaleHandle([0.1415, 0.707 * 1.2], [0.5, 0.5]) self.mask_circle.addScaleHandle([0.707 * 1.2, 0.1415], [0.5, 0.5]) self.mask_circle.addScaleHandle([0.1415, 0.1415], [0.5, 0.5]) #self.mask_circle.addScaleHandle([0, 0.5], [0.5, 0.5]) # west: pyqtgraph error self.mask_circle.addScaleHandle([0.5, 0.0], [0.5, 0.5]) # south self.mask_circle.addScaleHandle([0.5, 1.0], [0.5, 0.5]) # north #self.mask_circle.addScaleHandle([1.0, 0.5], [0.5, 0.5]) # east: pyqtgraph error # Polygon mask self.mask_poly = pg.PolyLineROI([[-300, 300], [-300,500], [-100,500], [-100,400], [-225,400], [-225,300]], closed=True, snapSize=1.0, scaleSnap=True, translateSnap=True, pen={'color': 'r', 'width': 4}) # add ROIs self.parent.img.win.getView().addItem(self.mask_rect) self.parent.img.win.getView().addItem(self.mask_circle) self.parent.img.win.getView().addItem(self.mask_poly) if self.parent.args.v >= 1: print("Done updateMaskingMode: ", self.maskingMode)
def on_show_cross_change(self): if self.show_center.isChecked(): self.image_view.addItem(self.crosshair) if self.roi_outer is not None: self.image_view.removeItem(self.roi_outer) self.roi_outer = pg.CircleROI([0, 0], [1, 1], pen=pg.mkPen("r", width=1), movable=False) self.image_view.addItem(self.roi_outer) self.on_redraw_roi() self.on_move_cross() else: self.image_view.removeItem(self.crosshair) self.image_view.removeItem(self.roi_outer)
def _setup(self): CrosshairROIBase._setup(self) x, y = self.model.x, self.model.y radius, width = self.model.radius, self.model.width large_radius = radius + width self.annulus = pg.CircleROI([x - large_radius, y - large_radius], size=[2 * large_radius, 2 * large_radius], movable=False, rotatable=False, resizable=True, removable=False, pen='k') self.plot_item.addItem(self.annulus)
def line_clicked(self, plot_data_item): """line을 Shift키와 함께 click하면 marker를 표시한다.""" modifiers = QApplication.keyboardModifiers() if modifiers == Qt.ShiftModifier: x = plot_data_item.xData y = plot_data_item.yData if isinstance(x, ndarray) and isinstance(y, ndarray): idx_near = (np.abs(x - self.mouse_pos_x)).argmin() # calc radius idx_prev = idx_near - 1 if idx_near == 0: idx_prev = 1 radius = (min([ abs(x[idx_near] - x[idx_prev]), abs(y[idx_near] - y[idx_prev]) ]) / 2) roi = pg.CircleROI( pos=(x[idx_near] - radius, y[idx_near] - radius), radius=radius, movable=False, removable=True, ) roi.setAcceptedMouseButtons(Qt.LeftButton) arrow = pg.ArrowItem(angle=90, pos=(radius, radius)) arrow.setParentItem(roi) text = pg.TextItem( html=('<span style="font-family: D2Conding ligature;">' + f"x {x[idx_near]:g}<br>y {y[idx_near]:g}<br>" + f"idx {idx_near}" + "</span>"), border={ "color": "222222", "width": 1 }, anchor=(0.5, -0.5), fill=(250, 250, 255, 50), ) text.setParentItem(roi) roi.sigClicked.connect(self.roi_click) roi.sigRemoveRequested.connect(self.roi_remove) self.addItem(roi)
def loadCircleFromDatabase(self, x, y, d, color): """ Used to draw labels on an image based on locations saved in a database. Arguments: x - x axis center position y - y axis center position d - diameter """ roiCircle = pg.CircleROI(pos = [x, y], size=[d, d], snapSize=0.1, scaleSnap=False, translateSnap=False, pen={'color': color, 'width': 4, 'style': QtCore.Qt.DashLine}, removable = True) roiCircle.setAcceptedMouseButtons(QtCore.Qt.LeftButton) roiCircle.sigClicked.connect(self.removeROI) roiCircle.addScaleHandle([0.5, 0.0], [0.5, 0.5]) # south roiCircle.addScaleHandle([0.5, 1.0], [0.5, 0.5]) # north self.circleRois.append(roiCircle) self.parent.img.win.getView().addItem(roiCircle) print("Circle added at x = %d, y = %d" % (x, y))
def setup_figure(self): #self.ui = self.graph_layout = pg.GraphicsLayoutWidget() self.ui = load_qt_ui_file( sibling_path(__file__, 'galvo_scanner_control.ui')) self.ui.pos_plot.showGrid(True, True) self.ui.pos_plot.showAxis('right') self.ui.pos_plot.showAxis('top') self.ui.pos_plot.setContentsMargins(0, 0, 0, 0) self.ui.pos_plot.setLimits(xMin=-7.5, xMax=+7.5, yMin=-7.5, yMax=+7.5) self.ui.pos_plot.setRange(xRange=(-7.5, +7.5), yRange=(-7.5, +7.5)) self.ui.pos_plot.setAspectLocked(lock=True, ratio=1) self.current_stage_pos_arrow = pg.ArrowItem() self.current_stage_pos_arrow.setZValue(100) self.ui.pos_plot.addItem(self.current_stage_pos_arrow) #self.stage = self.app.hardware_components['dummy_xy_stage'] self.stage.settings.x_position_deg.updated_value.connect( self.update_arrow_pos, pg.QtCore.Qt.UniqueConnection) self.stage.settings.y_position_deg.updated_value.connect( self.update_arrow_pos, pg.QtCore.Qt.UniqueConnection) #self.stage.settings.x_position_deg.connect_to_widget(self.ui.x_doubleSpinBox) #self.stage.settings.y_position_deg.connect_to_widget(self.ui.y_doubleSpinBox) self.circ_roi_size = 1.0 self.pt_roi = pg.CircleROI((0, 0), (self.circ_roi_size, self.circ_roi_size), movable=True, pen=(0, 9)) h = self.pt_roi.addTranslateHandle((0.5, 0.5)) h.pen = pg.mkPen('r') h.update() self.ui.pos_plot.addItem(self.pt_roi) self.pt_roi.removeHandle(0) self.pt_roi.sigRegionChangeFinished[object].connect( self.on_update_pt_roi) self.trajectory_plotline = self.ui.pos_plot.plot(pen=(0, 9))
def setup(self): #self.ui = self.splitter = QtWidgets.QSplitter() #self.ui.setLayout(QtWidgets.QVBoxLayout()) self.ui = self.dockarea = dockarea.DockArea() self.imview = pg.ImageView() self.imview.getView().invertY(False) # lower left origin #self.splitter.addWidget(self.imview) self.dockarea.addDock(name='Image', widget=self.imview) self.graph_layout = pg.GraphicsLayoutWidget() #self.splitter.addWidget(self.graph_layout) self.dockarea.addDock(name='Spec Plot', widget=self.graph_layout) self.spec_plot = self.graph_layout.addPlot() self.rect_plotdata = self.spec_plot.plot() self.point_plotdata = self.spec_plot.plot(pen=(0,9)) # Rectangle ROI self.rect_roi = pg.RectROI([20, 20], [20, 20], pen=(0,9)) self.rect_roi.addTranslateHandle((0.5,0.5)) self.imview.getView().addItem(self.rect_roi) self.rect_roi.sigRegionChanged[object].connect(self.on_change_rect_roi) # Point ROI self.circ_roi = pg.CircleROI( (0,0), (2,2) , movable=True, pen=(0,9)) #self.circ_roi.removeHandle(self.circ_roi.getHandles()[0]) h = self.circ_roi.addTranslateHandle((0.5,.5)) h.pen = pg.mkPen('r') h.update() self.imview.getView().addItem(self.circ_roi) self.circ_roi.removeHandle(0) self.circ_roi_plotline = pg.PlotCurveItem([0], pen=(0,9)) self.imview.getView().addItem(self.circ_roi_plotline) self.circ_roi.sigRegionChanged[object].connect(self.on_update_circ_roi) self.hyperspec_data = None self.display_image = None self.spec_x_array = None self.scan_specific_setup()
def setup_figure(self): ToupCamLiveMeasure.setup_figure(self) U = self.settings.New_UI(include=[ 'img_chan', 'img_slicing', 'wl', 'NA', 'fit_gaus', 'spot_px_x', 'spot_px_y', ]) self.ui.settings_verticalLayout.addWidget(U) self.hist_plot = self.graph_layout.addPlot(row=1, col=0) self.hist_plot.setMinimumHeight(240) self.hist_plot.setMaximumHeight(250) self.hist_plot.enableAutoRange() self.hist_line = self.hist_plot.plot() self.linear_region_item = pg.LinearRegionItem() self.linear_region_item.setZValue(-1) self.hist_plot.addItem(self.linear_region_item) self.linear_region_item.setVisible(False) self.marker = pg.CircleROI((0, 0), (1, 1), movable=False, pen=pg.mkPen('r', width=3)) self.plot.addItem(self.marker) self.marker_label = pg.TextItem('', color='r') self.plot.addItem(self.marker_label) self.center_roi.setVisible(False) self.roi_label.setVisible(False) self.slice_indicator_line = pg.InfiniteLine(movable=False, angle=90, pen=(255, 0, 0, 200)) self.plot.addItem(self.slice_indicator_line)
def read_data(self): file_handling = QtGui.QFileDialog() file_handling.setFileMode(QtGui.QFileDialog.AnyFile) if file_handling.exec_(): self.filenames = file_handling.selectedFiles() print self.filenames[0] print str(self.filenames[0]) name = self.filenames[0] with open(str(name), 'r') as f: data = pickle.load(f) self.reset_roi() f_name = data[0] self.roiPos = data[1] self.roiSize = data[2] print f_name print self.roiPos for x in range(0, len(self.roiPos)): self.roiAll.append( pg.CircleROI([self.roiPos[x][0], self.roiPos[x][1]], [self.roiSize[x][0], self.roiSize[x][1]], pen=(9, 15))) self.roiAll[len(self.roiAll) - 1].sigRegionChanged.connect(self.update) self.imv.addItem(self.roiAll[len(self.roiAll) - 1])
def __init__(self, parent, fullColor): super(ImageWidget, self).__init__(parent) self.imageView = pg.ImageView() if fullColor: data = np.random.randint(0, 255, (200, 200, 3)) data = np.random.normal(size=(200, 200)) else: dataIndicies = np.random.choice(distinct_colors.shape[0], (200, 200)) data = distinct_colors[dataIndicies, :] self.image = data self.imageView.ui.roiBtn.hide() self.imageView.ui.menuBtn.hide() self.imageView.setImage(self.image) self.imageView.view.setLimits(xMin=-10, xMax=self.image.shape[0] + 10, yMin=-10, yMax=self.image.shape[1] + 10) self.blink = 0 self.pen = QtGui.QPen(QtGui.QColor(0xff, 0x00, 0x00)) self.pen.setWidthF(0.25) self.roi = pg.CircleROI([30.5, 40.5], [2, 2], movable=False, pen=self.pen) self.imageView.addItem(self.roi) self.roi.removeHandle(0) verticalLayout = QtGui.QVBoxLayout() verticalLayout.addWidget(self.imageView) self.setLayout(verticalLayout) self.imageView.scene.sigMouseClicked.connect(self.onClick)
v1a.addItem(img1a) img1b = pg.ImageItem() v1b.addItem(img1b) v1a.disableAutoRange('xy') v1b.disableAutoRange('xy') v1a.autoRange() v1b.autoRange() rois = [] rois.append(pg.RectROI([20, 20], [20, 20], pen=(0, 9))) rois[-1].addRotateHandle([1, 0], [0.5, 0.5]) rois.append(pg.LineROI([0, 60], [20, 80], width=5, pen=(1, 9))) rois.append( pg.MultiRectROI([[20, 90], [50, 60], [60, 90]], width=5, pen=(2, 9))) rois.append(pg.EllipseROI([60, 10], [30, 20], pen=(3, 9))) rois.append(pg.CircleROI([80, 50], [20, 20], pen=(4, 9))) #rois.append(pg.LineSegmentROI([[110, 50], [20, 20]], pen=(5,9))) rois.append( pg.PolyLineROI([[80, 60], [90, 30], [60, 40]], pen=(6, 9), closed=True)) def update(roi): img1b.setImage(roi.getArrayRegion(arr, img1a), levels=(0, arr.max())) v1b.autoRange() for roi in rois: roi.sigRegionChanged.connect(update) v1a.addItem(roi) update(rois[-1])
def initUI(self): ## 2D plot for the cspad and mask ################################# self.plot = pg.ImageView() ## save mask button ################################# save_button = QPushButton('save mask') save_button.clicked.connect(self.save_mask) # rectangular ROI selection ################################# self.roi = pg.RectROI([-200, -200], [100, 100]) self.plot.addItem(self.roi) self.roi.setZValue(10) # make sure ROI is drawn above image ROI_button = QPushButton('mask rectangular ROI') ROI_button.clicked.connect(lambda: self.mask_ROI(self.roi)) # circular ROI selection ################################# self.roi_circle = pg.CircleROI([-200, 200], [101, 101]) self.plot.addItem(self.roi_circle) self.roi.setZValue(10) # make sure ROI is drawn above image ROI_circle_button = QPushButton('mask circular ROI') ROI_circle_button.clicked.connect( lambda: self.mask_ROI_circle(self.roi_circle)) # histogram mask button ################################# hist_button = QPushButton('mask outside histogram') hist_button.clicked.connect(self.mask_hist) # prev / next buttons ################################# hbox = QHBoxLayout() prev_button = QPushButton('prev frame') prev_button.clicked.connect(self.prev_frame) next_button = QPushButton('next frame') next_button.clicked.connect(self.next_frame) hbox.addWidget(prev_button) hbox.addWidget(next_button) if self.index is None: next_button.setEnabled(False) prev_button.setEnabled(False) # toggle / mask / unmask checkboxes ################################# self.toggle_checkbox = QCheckBox('toggle') self.mask_checkbox = QCheckBox('mask') self.unmask_checkbox = QCheckBox('unmask') self.toggle_checkbox.setChecked(True) self.toggle_group = QButtonGroup() #"masking behaviour") self.toggle_group.addButton(self.toggle_checkbox) self.toggle_group.addButton(self.mask_checkbox) self.toggle_group.addButton(self.unmask_checkbox) self.toggle_group.setExclusive(True) # toggle / mask / unmask checkboxes ################################# self.toggle_checkbox = QCheckBox('toggle') self.mask_checkbox = QCheckBox('mask') self.unmask_checkbox = QCheckBox('unmask') self.toggle_checkbox.setChecked(True) self.toggle_group = QButtonGroup() #"masking behaviour") self.toggle_group.addButton(self.toggle_checkbox) self.toggle_group.addButton(self.mask_checkbox) self.toggle_group.addButton(self.unmask_checkbox) self.toggle_group.setExclusive(True) # mouse hover ij value label ################################# ij_label = QLabel() disp = 'ss fs {0:5} {1:5} value {2:2}'.format('-', '-', '-') ij_label.setText(disp) self.plot.scene.sigMouseMoved.connect( lambda pos: self.mouseMoved(ij_label, pos)) # unbonded pixels checkbox ################################# unbonded_checkbox = QCheckBox('unbonded pixels') unbonded_checkbox.stateChanged.connect(self.update_mask_unbonded) if self.cspad_shape_flag == 'other': unbonded_checkbox.setEnabled(False) # asic edges checkbox ################################# edges_checkbox = QCheckBox('asic edges') edges_checkbox.stateChanged.connect(self.update_mask_edges) if self.cspad_shape_flag == 'other': edges_checkbox.setEnabled(False) # mouse click mask ################################# self.plot.scene.sigMouseClicked.connect( lambda click: self.mouseClicked(self.plot, click)) # Create a grid layout to manage the widgets size and position ################################# layout = QGridLayout() self.setLayout(layout) ## Add widgets to the layout in their proper positions layout.addWidget(save_button, 0, 0) # upper-left layout.addWidget(ROI_button, 1, 0) # upper-left layout.addWidget(ROI_circle_button, 2, 0) # upper-left layout.addWidget(hist_button, 3, 0) # upper-left layout.addLayout(hbox, 4, 0) # upper-left layout.addWidget(self.toggle_checkbox, 5, 0) # upper-left layout.addWidget(self.mask_checkbox, 6, 0) # upper-left layout.addWidget(self.unmask_checkbox, 7, 0) # upper-left layout.addWidget(ij_label, 8, 0) # upper-left layout.addWidget(unbonded_checkbox, 9, 0) # middle-left layout.addWidget(edges_checkbox, 10, 0) # bottom-left layout.addWidget(self.plot, 0, 1, 10, 1) # plot goes on right side, spanning 3 rows layout.setColumnStretch(1, 1) layout.setColumnMinimumWidth(0, 250) # display the image self.generate_mask() self.updateDisplayRGB(auto=True)
def __init__(self, parent=None): super(ViewData, self).__init__(parent) self.widget = QtGui.QWidget() self.widget.setLayout(QtGui.QGridLayout()) ni = Image.open('DAC4-00002MODD.png') # default_image arr = np.array(ni) self.imv = pg.ImageView() button_new_target = QtGui.QPushButton("new target") button_new_target.clicked.connect(self.change) button_open_file = QtGui.QPushButton("open image") button_open_file.clicked.connect(self.open_file) button_write_to_file = QtGui.QPushButton("write to file") button_write_to_file.clicked.connect(self.write_data) button_reset_roi = QtGui.QPushButton("reset ROI") button_reset_roi.clicked.connect(self.reset_roi) button_read_file = QtGui.QPushButton("read file") button_read_file.clicked.connect(self.read_data) button_move_pellets = QtGui.QPushButton("move pellets") # button_move_pellets.clicked.connect(self.moveAll) button_move_pellets.clicked.connect(self.move_all_new) button_calibrate = QtGui.QPushButton("calibrate") button_calibrate.clicked.connect(self.calibrate) button_re_arrange = QtGui.QPushButton("rearrange") button_re_arrange.clicked.connect(self.rearrange) button_add_bs = QtGui.QPushButton("add_bs") button_add_bs.clicked.connect(self.test_find_path) mx = 'p02/motor/elab.01' # x_motor my = 'p02/motor/elab.02' # y_motor gr = 'p02/register/elab.out08' # io_register self.col = 1 #self.gripper = tango.DeviceProxy(gr) #self.motox = tango.DeviceProxy(mx) #self.motoy = tango.DeviceProxy(my) self.yBacklash = 3.0 # backlash self.amount = 5 # amount_of_beamstops self.imv.setImage(arr) self.roiAll = [] # create_list(roi means region of interest) self.roiPos = [] # create_list only for position data self.roiSize = [] # create_list which contains updated sizes of rois self.roiPosOld = [] # create roi pos list which is later used as buffer self.filenames = QtCore.QStringList() self.filenames.append('DAC4-00002MODD.png') self.roiPos.append([80, 50, 0]) # first_roi_default_position self.roiSize.append([20, 20]) # first_roi_default_size self.roiAll.append(pg.CircleROI([80, 50, 0], [20, 20], pen=(self.col, 15))) self.roiAll[0].sigRegionChanged.connect(self.update) it1 = self.imv.addItem(self.roiAll[0]) self.widget.layout().addWidget(self.imv, 0, 0, 3, 3) self.widget.layout().addWidget(button_new_target, 4, 0) self.widget.layout().addWidget(button_open_file, 4, 1) self.widget.layout().addWidget(button_write_to_file, 4, 2) self.widget.layout().addWidget(button_reset_roi, 5, 0) self.widget.layout().addWidget(button_move_pellets, 5, 1) self.widget.layout().addWidget(button_read_file, 5, 2) self.widget.layout().addWidget(button_calibrate, 6, 0) self.widget.layout().addWidget(button_re_arrange, 6, 1) self.widget.layout().addWidget(button_add_bs, 6, 2) self.setCentralWidget(self.widget) self.show()
def paintEvent(self, event): for point in self.control_points: self.reference_image_view.addItem(pg.CircleROI(point, 5)) print('drawing ellipse at ', point)
def draw_points(self, viewbox, pointlist): for point in pointlist: viewbox.addItem(pg.CircleROI(point, 5))
def __init__(self, image, *args, **kwargs): """ Parameters ---------- image : ndarray Diffraction pattern to be displayed. """ super().__init__(*args, **kwargs) self.setModal(True) self.setWindowTitle("Calculate azimuthal averages") title = QtWidgets.QLabel("<h2>Azimuthal Average Options<\h2>") title.setTextFormat(QtCore.Qt.RichText) title.setAlignment(QtCore.Qt.AlignCenter) explanation_label = QtWidgets.QLabel(explanation, parent=self) explanation_label.setWordWrap(True) self.viewer = pg.ImageView(parent=self) self.viewer.setSizePolicy( QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding, ) self.viewer.setImage(image) self.center_finder = pg.CircleROI( pos=np.array(image.shape) / 2 - 100, size=[200, 200], pen=pg.mkPen("r") ) self.viewer.getView().addItem(self.center_finder) self.partial_circle_btn = QtWidgets.QCheckBox("Restrict azimuthal angle", self) self.partial_circle_btn.setChecked(False) self.accept_btn = QtWidgets.QPushButton("Calculate", self) self.accept_btn.clicked.connect(self.accept) self.cancel_btn = QtWidgets.QPushButton("Cancel", self) self.cancel_btn.clicked.connect(self.reject) self.cancel_btn.setDefault(True) self.min_angular_bound_widget = QtWidgets.QDoubleSpinBox(parent=self) self.min_angular_bound_widget.setRange(0, 360) self.min_angular_bound_widget.setSingleStep(1) self.min_angular_bound_widget.setValue(0) self.min_angular_bound_widget.setSuffix(" deg") self.min_angular_bound_widget.setEnabled(False) self.partial_circle_btn.toggled.connect( self.min_angular_bound_widget.setEnabled ) self.max_angular_bound_widget = QtWidgets.QDoubleSpinBox(parent=self) self.max_angular_bound_widget.setRange(0, 360) self.max_angular_bound_widget.setSingleStep self.max_angular_bound_widget.setValue(360) self.max_angular_bound_widget.setSuffix(" deg") self.max_angular_bound_widget.setEnabled(False) self.partial_circle_btn.toggled.connect( self.max_angular_bound_widget.setEnabled ) self.min_angular_bound_widget.valueChanged.connect( self.max_angular_bound_widget.setMinimum ) self.max_angular_bound_widget.valueChanged.connect( self.min_angular_bound_widget.setMaximum ) self.normalize_widget = QtWidgets.QCheckBox("Normalize (?)", self) self.normalize_widget.setChecked(False) self.normalize_widget.setToolTip(normalize_help) angle_bounds_layout = QtWidgets.QFormLayout() angle_bounds_layout.addRow(self.partial_circle_btn) angle_bounds_layout.addRow("Min. angle: ", self.min_angular_bound_widget) angle_bounds_layout.addRow("Max. angle: ", self.max_angular_bound_widget) btns = QtWidgets.QHBoxLayout() btns.addWidget(self.accept_btn) btns.addWidget(self.cancel_btn) params_layout = QtWidgets.QVBoxLayout() params_layout.addWidget(title) params_layout.addWidget(explanation_label) params_layout.addWidget(self.normalize_widget) params_layout.addLayout(angle_bounds_layout) params_layout.addLayout(btns) params_widget = QtWidgets.QFrame(parent=self) params_widget.setLayout(params_layout) params_widget.setFrameShadow(QtWidgets.QFrame.Sunken) params_widget.setFrameShape(QtWidgets.QFrame.Panel) params_widget.setSizePolicy( QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum ) right_layout = QtWidgets.QVBoxLayout() right_layout.addWidget(params_widget) right_layout.addStretch() self.layout = QtWidgets.QHBoxLayout() self.layout.addWidget(self.viewer) self.layout.addLayout(right_layout) self.setLayout(self.layout)
def setup(self): TogOff=self.icon+'Toggle_Off.png' TogOn=self.icon+'Toggle_On.png' TogOff=pathlib.Path(TogOff) TogOff=pathlib.PurePosixPath(TogOff) TogOn=pathlib.Path(TogOn) TogOn=pathlib.PurePosixPath(TogOn) self.setStyleSheet("QCheckBox::indicator{width: 30px;height: 30px;}""QCheckBox::indicator:unchecked { image : url(%s);}""QCheckBox::indicator:checked { image: url(%s);}""QCheckBox{font :10pt;}" % (TogOff,TogOn) ) vbox1=QVBoxLayout() hbox=QHBoxLayout() self.checkBoxAuto=QCheckBox('Auto',self) self.checkBoxAuto.setChecked(True) hbox.addWidget(self.checkBoxAuto) self.resetButton=QPushButton('Reset',self) hbox.addWidget(self.resetButton) vbox1.addLayout(hbox) hbox0=QHBoxLayout() self.energieRes=QLabel('?') self.energieRes.setMaximumHeight(30) self.energieRes.setMaximumWidth(120) self.lEnergie=QLabel('s(E1)/s(E2) :') self.lEnergie.setStyleSheet("color:blue;font:14pt") self.lEnergie.setMaximumWidth(80) hbox0.addWidget(self.lEnergie) hbox0.addWidget(self.energieRes) #vbox1.addStretch(1) vbox1.addLayout(hbox0) LabelR1x=QLabel("fwhm X/0.85") LabelR1x.setStyleSheet("color:red;font:14pt") self.r1xBox=QSpinBox() #self.r1Box.setMaximumWidth(60) self.r1xBox.setMaximum(2000) LabelR1y=QLabel('fwhm Y/0.85') LabelR1y.setStyleSheet("color:green;font:14pt") self.r1yBox=QSpinBox() self.r1yBox.setMaximum(2000) #self.r2Box.setMaximumWidth(60) LabelR2=QLabel('R2') LabelR2.setStyleSheet("color:yellow;font:14pt") self.r2Box=QSpinBox() self.r2Box.setMaximum(2000) LabelE1=QLabel("E1 Sum ") LabelE1.setStyleSheet("color:red;font:14pt") self.LabelE1Sum=QLabel("? ") self.LabelE1Sum.setStyleSheet("color:red;font:14pt") LabelE1M=QLabel("E1 mean ") LabelE1M.setStyleSheet("color:red;font:14pt") self.LabelE1Mean=QLabel("? ") self.LabelE1Mean.setStyleSheet("color:red;font:14pt") LabelE2=QLabel("E2 Sum ") LabelE2.setStyleSheet("color:yellow;font:14pt") self.LabelE2Sum=QLabel("? ") self.LabelE2Sum.setStyleSheet("color:yellow;font:14pt") LabelE2M=QLabel("E2 mean ") LabelE2M.setStyleSheet("color:yellow ;font:14pt") self.LabelE2Mean=QLabel("? ") self.LabelE2Mean.setStyleSheet("color:yellow;font:14pt") grid_layout1 = QGridLayout() grid_layout1.addWidget(LabelR1x, 0, 0) grid_layout1.addWidget(self.r1xBox, 0, 1) grid_layout1.addWidget(LabelR1y, 1, 0) grid_layout1.addWidget(self.r1yBox, 1,1) grid_layout1.addWidget(LabelR2, 2, 0) grid_layout1.addWidget(self.r2Box, 2,1) grid_layout1.addWidget(LabelE1,3,0) grid_layout1.addWidget(self.LabelE1Sum,3,1) grid_layout1.addWidget(LabelE1M,4,0) grid_layout1.addWidget(self.LabelE1Mean,4,1) grid_layout1.addWidget(LabelE2,5,0) grid_layout1.addWidget(self.LabelE2Sum,5,1) grid_layout1.addWidget(LabelE2M,6,0) grid_layout1.addWidget(self.LabelE2Mean,6,1) vbox1.addLayout(grid_layout1) vbox1.addStretch(1) self.winImage = pg.GraphicsLayoutWidget() self.winImage.setContentsMargins(0,0,0,0) self.winImage.setAspectLocked(True) self.winImage.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) #self.winImage.ci.setContentsMargins(0,0,0,0) vbox2=QVBoxLayout() hbox2=QHBoxLayout() hbox2.addWidget(self.winImage) vbox2.addLayout(hbox2) vbox2.setContentsMargins(0,0,0,0) self.p1=self.winImage.addPlot() self.imh=pg.ImageItem() self.p1.addItem(self.imh) self.p1.setMouseEnabled(x=False,y=False) self.p1.setContentsMargins(0,0,0,0) self.p1.setAspectLocked(True,ratio=1) self.p1.showAxis('right',show=False) self.p1.showAxis('top',show=False) self.p1.showAxis('left',show=False) self.p1.showAxis('bottom',show=False) self.vLine = pg.InfiniteLine(angle=90, movable=False,pen='w') self.hLine = pg.InfiniteLine(angle=0, movable=False,pen='w') self.p1.addItem(self.vLine) self.p1.addItem(self.hLine) self.vLine.setPos(self.xec) self.hLine.setPos(self.yec) self.roi1=pg.CircleROI([self.xec,self.yec],[2*self.r1x,2*self.r1y],pen='r',movable=False) self.roi1.setPos([self.xec-(self.r1x),self.yec-(self.r1y)]) self.p1.addItem(self.roi1) self.roi2=pg.CircleROI([self.xec,self.yec],[2*self.r2,2*self.r2],pen='y',movable=False) self.roi2.setPos([self.xec-(self.r2),self.yec-(self.r2)]) self.p1.addItem(self.roi2) #histogramme self.hist = pg.HistogramLUTItem() self.hist.setImageItem(self.imh) self.hist.autoHistogramRange() self.hist.gradient.loadPreset('flame') self.curve2=pg.PlotCurveItem() self.curve3=pg.PlotCurveItem() # text pour afficher fwhm sur p1 self.textX = pg.TextItem(angle=-90) self.textY = pg.TextItem() self.p1.addItem(self.curve2) self.p1.addItem(self.curve3) self.p1.addItem(self.textX) self.p1.addItem(self.textY) hLayout1=QHBoxLayout() hLayout1.addLayout(vbox2) hLayout1.addLayout(vbox1) hLayout1.setContentsMargins(1,1,1,1) # hLayout1.setSpacing(1) # hLayout1.setStretch(10,1) vMainLayout=QVBoxLayout() vMainLayout.addLayout(hLayout1) self.winCurve=QVBoxLayout() self.win2=pg.PlotWidget() self.p2=self.win2.plot(pen='b',symbol='t',symboleSize=2,clear=True,symbolPen='b',symbolBrush='b',name="rapport") self.win2.setContentsMargins(0,0,0,0) self.win2.setLabel('left','E1/E2',units='%') self.hLineMeanE = pg.InfiniteLine(angle=0, movable=False,pen=pg.mkPen('b', width=3, style=QtCore.Qt.DashLine) ) self.win2.addItem(self.hLineMeanE, ignoreBounds=True) self.win2.addItem(self.hLineMeanE, ignoreBounds=True) self.winCurve.addWidget(self.win2) self.win3=pg.PlotWidget() self.p3=self.win3.plot(pen='r',symbol='t',symboleSize=2,clear=True,symbolPen='r',symbolBrush='r',name="x") self.win3.setContentsMargins(0,0,0,0) self.win3.setLabel('left','X')#,units='pixel') self.hLineMeanX = pg.InfiniteLine(angle=0, movable=False,pen=pg.mkPen('r', width=3, style=QtCore.Qt.DashLine)) self.win3.addItem(self.hLineMeanX, ignoreBounds=True) self.winCurve.addWidget(self.win3) self.win4=pg.PlotWidget() self.p4=self.win4.plot(pen='g',symbol='t',symboleSize=2,clear=True,symbolPen='g',symbolBrush='g',name="y") self.win4.setLabel('left','Y')#,units='pixel') self.win4.setLabel('bottom',"Shoot number") self.hLineMeanY = pg.InfiniteLine(angle=0, movable=False,pen=pg.mkPen('g', width=3, style=QtCore.Qt.DashLine)) self.win4.addItem(self.hLineMeanY, ignoreBounds=True) self.winCurve.addWidget(self.win4) labelMean=QLabel('<E1/E2> ') labelMean.setStyleSheet("color:blue;font:14pt") #labelMean.setMaximumWidth(120) self.meanAff=QLabel('?') #self.meanAff.setMaximumWidth(60) labelPV=QLabel('std E1/E2') labelPV.setStyleSheet("color:blue;font:14pt") self.PVAff=QLabel('?') labelMeanX=QLabel('<X>') self.meanXAff=QLabel() labelMeanX.setStyleSheet("color:red;font:14pt") labelMeanY=QLabel('<Y>') labelMeanY.setStyleSheet("color:green;font:14pt") self.meanYAff=QLabel() labelStdX=QLabel('std X') labelStdX.setStyleSheet("color:red;font:14pt") self.stdXAff=QLabel() labelStdY=QLabel('std Y') labelStdY.setStyleSheet("color:green;font:14pt") self.stdYAff=QLabel() grid_layout2 = QGridLayout() grid_layout2.addWidget(labelMean, 0, 0) grid_layout2.addWidget(self.meanAff, 0, 1) grid_layout2.addWidget(labelPV, 1, 0) grid_layout2.addWidget(self.PVAff, 1,1) grid_layout2.addWidget(labelMeanX, 2, 0) grid_layout2.addWidget(self.meanXAff, 2, 1) grid_layout2.addWidget(labelStdX, 3, 0) grid_layout2.addWidget(self.stdXAff, 3,1) grid_layout2.addWidget(labelMeanY, 4, 0) grid_layout2.addWidget(self.meanYAff, 4, 1) grid_layout2.addWidget(labelStdY, 5, 0) grid_layout2.addWidget(self.stdYAff, 5,1) hLayout2=QHBoxLayout() hLayout2.addLayout(self.winCurve) hLayout2.addLayout(grid_layout2) vMainLayout.addLayout(hLayout2) hMainLayout=QHBoxLayout() hMainLayout.addLayout(vMainLayout) self.setLayout(hMainLayout) self.setContentsMargins(1,1,1,1)
def __init__(self, parent=None): self.parent = parent ############################# ## Dock: ROI histogram ############################# self.dock = Dock("ROI Histogram", size=(1, 1)) self.win = pg.PlotWidget(title="ROI histogram") hist, bin = np.histogram(np.random.random(1000), bins=1000) self.win.plot(bin, hist, stepMode=True, fillLevel=0, brush=(0, 0, 255, 150), clear=True) self.dock.addWidget(self.win) self.roiCheckbox = QtGui.QCheckBox('Update ROI') self.roiCheckbox.setCheckState(True) self.roiCheckbox.setTristate(False) self.roiCheckbox.stateChanged.connect(self.updateRoiStatus) # Layout self.winL = pg.LayoutWidget() self.winL.addWidget(self.roiCheckbox, row=0, col=0) self.dock.addWidget(self.winL) ############################# # Local variables ############################# self.updateRoiStatus = True self.roiCurrent = None # Custom ROI for selecting an image region self.roi = pg.ROI(pos=[0, -250], size=[200, 200], snapSize=1.0, scaleSnap=True, translateSnap=True, pen={ 'color': 'g', 'width': 4, 'style': QtCore.Qt.DashLine }) self.roi.addScaleHandle([1, 0.5], [0.5, 0.5]) self.roi.addScaleHandle([0.5, 0], [0.5, 0.5]) self.roi.addScaleHandle([0.5, 1], [0.5, 0.5]) self.roi.addScaleHandle([0, 0.5], [0.5, 0.5]) self.roi.addScaleHandle( [0, 0], [1, 1 ]) # bottom,left handles scaling both vertically and horizontally self.roi.addScaleHandle( [1, 1], [0, 0 ]) # top,right handles scaling both vertically and horizontally self.roi.addScaleHandle([1, 0], [ 0, 1 ]) # bottom,right handles scaling both vertically and horizontally self.roi.addScaleHandle([0, 1], [1, 0]) self.roi.name = 'rect' self.parent.img.win.getView().addItem(self.roi) self.roiPoly = pg.PolyLineROI([[300, -250], [300, -50], [500, -50], [500, -150], [375, -150], [375, -250]], closed=True, snapSize=1.0, scaleSnap=True, translateSnap=True, pen={ 'color': 'g', 'width': 4, 'style': QtCore.Qt.DashLine }) self.roiPoly.name = 'poly' self.parent.img.win.getView().addItem(self.roiPoly) self.roiCircle = pg.CircleROI([600, -250], size=[200, 200], snapSize=0.1, scaleSnap=False, translateSnap=False, pen={ 'color': 'g', 'width': 4, 'style': QtCore.Qt.DashLine }) self.roiCircle.addScaleHandle([0.1415, 0.707 * 1.2], [0.5, 0.5]) self.roiCircle.addScaleHandle([0.707 * 1.2, 0.1415], [0.5, 0.5]) self.roiCircle.addScaleHandle([0.1415, 0.1415], [0.5, 0.5]) #self.roiCircle.addScaleHandle([0, 0.5], [0.5, 0.5]) # west: pyqtgraph error self.roiCircle.addScaleHandle([0.5, 0.0], [0.5, 0.5]) # south self.roiCircle.addScaleHandle([0.5, 1.0], [0.5, 0.5]) # north #self.roiCircle.addScaleHandle([1.0, 0.5], [0.5, 0.5]) # east: pyqtgraph error self.roiCircle.name = 'circ' self.parent.img.win.getView().addItem(self.roiCircle) self.rois = [] self.rois.append(self.roi) self.rois.append(self.roiPoly) self.rois.append(self.roiCircle) for roi in self.rois: roi.sigRegionChangeFinished.connect(self.updateRoi)