class BtnFrame(QtWidgets.QFrame): sigReconstuctCurrent = QtCore.Signal() sigReconstructMulti = QtCore.Signal() sigQuickLoadData = QtCore.Signal() sigUpdate = QtCore.Signal() def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) reconCurrBtn = BetterPushButton('Reconstruct current') reconCurrBtn.clicked.connect(self.sigReconstuctCurrent) reconMultiBtn = BetterPushButton('Reconstruct multidata') reconMultiBtn.clicked.connect(self.sigReconstructMulti) quickLoadDataBtn = BetterPushButton('Quick load data') quickLoadDataBtn.clicked.connect(self.sigQuickLoadData) updateBtn = BetterPushButton('Update reconstruction') updateBtn.clicked.connect(self.sigUpdate) layout = QtWidgets.QGridLayout() self.setLayout(layout) layout.addWidget(quickLoadDataBtn, 0, 0, 1, 2) layout.addWidget(reconCurrBtn, 1, 0) layout.addWidget(reconMultiBtn, 1, 1) layout.addWidget(updateBtn, 2, 0, 1, 2)
class ViewWidget(Widget): """ View settings (liveview, grid, crosshair). """ sigGridToggled = QtCore.Signal(bool) # (enabled) sigCrosshairToggled = QtCore.Signal(bool) # (enabled) sigLiveviewToggled = QtCore.Signal(bool) # (enabled) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Graphical elements # Grid self.gridButton = guitools.BetterPushButton('Grid') self.gridButton.setCheckable(True) self.gridButton.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) # Crosshair self.crosshairButton = guitools.BetterPushButton('Crosshair') self.crosshairButton.setCheckable(True) self.crosshairButton.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) # liveview self.liveviewButton = guitools.BetterPushButton('LIVEVIEW') self.liveviewButton.setStyleSheet("font-size:20px") self.liveviewButton.setCheckable(True) self.liveviewButton.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) self.liveviewButton.setEnabled(True) # Add elements to GridLayout self.viewCtrlLayout = QtWidgets.QGridLayout() self.setLayout(self.viewCtrlLayout) self.viewCtrlLayout.addWidget(self.liveviewButton, 0, 0, 1, 2) self.viewCtrlLayout.addWidget(self.gridButton, 1, 0) self.viewCtrlLayout.addWidget(self.crosshairButton, 1, 1) # Connect signals self.gridButton.toggled.connect(self.sigGridToggled) self.crosshairButton.toggled.connect(self.sigCrosshairToggled) self.liveviewButton.toggled.connect(self.sigLiveviewToggled) def getLiveViewActive(self): return self.liveviewButton.isChecked() def setViewToolsEnabled(self, enabled): self.crosshairButton.setEnabled(enabled) self.gridButton.setEnabled(enabled) def setLiveViewActive(self, active): """ Sets whether the LiveView is active. """ self.liveviewButton.setChecked(active) def setLiveViewGridVisible(self, visible): """ Sets whether the LiveView grid is visible. """ self.crosshairButton.setChecked(visible) def setLiveViewCrosshairVisible(self, visible): """ Sets whether the LiveView crosshair is visible. """ self.gridButton.setChecked(visible)
class ThreadOneAcq(QtCore.QThread): '''Second thread for controling one acquisition independtly ''' newDataRun = QtCore.Signal(object) # signal to send data newStateCam = QtCore.Signal( bool) #signal to send the state of the camera (running or not) def __init__(self, parent, cam0=None, itrig=None, LineTrigger='Line2'): super(ThreadOneAcq, self).__init__(parent) self.parent = parent self.cam0 = cam0 self.stopRunAcq = False self.itrig = itrig self.LineTrigger = LineTrigger def newRun(self): self.stopRunAcq = False def run(self): self.cam0.feature('TriggerSource').value = 'Software' self.newStateCam.emit(True) for i in range(self.parent.nbShot): if self.stopRunAcq is not True: self.cam0.reset_frame_ready() self.cam0.start_live(show_display=False) self.cam0.enable_trigger(True) if not self.cam0.callback_registered: self.cam0.register_frame_ready_callback() if self.itrig == 'off': # si cam pas en mode trig externe on envoi un trig soft... self.cam0.send_trigger() self.cam0.wait_til_frame_ready(2000000) dat1 = self.cam0.get_image_data() if i < self.parent.nbShot - 1: self.newStateCam.emit(True) else: self.newStateCam.emit(False) time.sleep(0.1) if dat1 is not None: dat1 = np.array(dat1) #, dtype=np.double) dat1.squeeze() dat = dat1[:, :, 0] self.data = np.rot90(dat, 1) self.newDataRun.emit(self.data) self.newStateCam.emit(False) def stopThreadOneAcq(self): #self.cam0.send_trigger() self.stopRunAcq = True self.cam0.send_trigger()
class OneDViewer(Viewer, pg.PlotWidget): selection_changing = QtCore.Signal(object, object) # self, {axis: value, ...} selection_changed = QtCore.Signal(object, object) # self, {axis: value, ...} def __init__(self, axes): pg.PlotWidget.__init__(self) self.line = self.addLine(x=0, movable=True) self.curves = [] Viewer.__init__(self, axes) self.line.sigDragged.connect(self.line_moved) self.line.sigPositionChangeFinished.connect(self.line_move_finished) def update_selection(self): axis = self.selected_axes[0] with pg.SignalBlock(self.line.sigPositionChangeFinished, self.line_move_finished): self.line.setValue(self.data_axes[axis].index) Viewer.update_selection(self) def line_moved(self): ax = self.selected_axes[0] val = self.data_axes[ax].value_at(int(np.round(self.line.value()))) self.selection_changing.emit(self, {ax: val}) def line_move_finished(self): ax = self.selected_axes[0] val = self.data_axes[ax].value_at(int(np.round(self.line.value()))) self.selection_changed.emit(self, {ax: val}) def update_display(self): if self.data is None: self.clear_curves() return axis = self.selected_axes[0] self.setLabels(bottom=axis) data, colors = self.get_data() if colors is None: data = data[..., np.newaxis] colors = ['w'] new_curves = [] for i in range(data.shape[-1]): c = pg.PlotCurveItem(data[...,i], pen=colors[i], antialias=True) new_curves.append(c) self.addItem(c) self.clear_curves() self.curves = new_curves axvals = self.data_axes[axis].values self.getAxis('bottom').setTicks([[(i, "%0.2g"%axvals[i]) for i in range(len(axvals))]]) def clear_curves(self): for c in self.curves: self.removeItem(c) self.curves = []
class ThreadOneAcq(QtCore.QThread): '''Second thread for controling one acquisition independtly ''' newDataRun = QtCore.Signal(object) # signal to send data newStateCam = QtCore.Signal( bool) #signal to send the state of the camera (running or not) def __init__(self, parent): super(ThreadOneAcq, self).__init__(parent) self.parent = parent self.cam0 = self.parent.cam0 self.stopRunAcq = False self.itrig = self.parent.itrig def newRun(self): self.stopRunAcq = False def run(self): self.newStateCam.emit(True) self.cam0.reset_frame_ready() self.cam0.SetContinuousMode(0) self.cam0.StartLive(0) self.cam0.enable_trigger(True) if not self.cam0.callback_registered: self.cam0.SetFrameReadyCallback() for i in range(self.parent.nbShot): if self.stopRunAcq: break if self.stopRunAcq is not True: if self.itrig == 'off': # si cam pas en mode trig externe on envoi un trig soft... self.cam0.send_trigger() self.cam0.wait_til_frame_ready(2000000) data1 = self.cam0.GetImage() data1 = np.array(data1, dtype=np.double) data1.squeeze() data = data1[:, :, 0] self.data = np.rot90(data, 1) if i < self.parent.nbShot - 1: self.newStateCam.emit(True) else: self.newStateCam.emit(False) time.sleep(0.1) if np.max(self.data) > 0: self.newDataRun.emit(self.data) time.sleep(0.5) self.newStateCam.emit(False) def stopThreadOneAcq(self): self.stopRunAcq = True self.cam0.StopLive() self.cam0.send_trigger()
class ThreadOneAcq(QtCore.QThread): '''Second thread for controling one or anumber of acquisition independtly ''' newDataRun=QtCore.Signal(object) newStateCam=QtCore.Signal(bool) # signal to emit the state (running or not) of the camera def __init__(self, parent): super(ThreadOneAcq,self).__init__(parent) self.parent=parent self.cam0 = parent.cam0 self.stopRunAcq=False self.itrig= parent.itrig self.LineTrigger=parent.LineTrigger def newRun(self): self.stopRunAcq=False def run(self): self.newStateCam.emit(True) self.cam0.startStream() for i in range (self.parent.nbShot): if self.stopRunAcq is not True : self.data=self.cam0.getNextFrame() self.data=np.rot90(self.data,1) if i<self.parent.nbShot-1: self.newStateCam.emit(True) else: self.newStateCam.emit(False) time.sleep(0.1) if np.max(self.data)>0 : self.newDataRun.emit(self.data) print('newdata') else: break self.newStateCam.emit(False) def stopThreadOneAcq(self): try : trig=self.cam0.getTriggering() if trig=='on': self.cam0.setTriggering('software') print('send software trigger') self.cam0.getNextFrame() time.sleep(0.1) self.cam0.setTriggering('on') self.cam0.stopStream() except : pass self.stopRunAcq=True
class DragViewBox(pg.ViewBox): # A normal ViewBox, but with the ability to capture drag. # Effectively, if "dragging" is enabled, it captures press & release signals. # Otherwise it ignores the event, which then goes to the scene(), # which only captures click events. sigMouseDragged = QtCore.Signal(object, object, object) keyPressed = QtCore.Signal(int) def __init__(self, parent, enableDrag, thisIsAmpl, *args, **kwds): pg.ViewBox.__init__(self, *args, **kwds) self.enableDrag = enableDrag self.parent = parent self.thisIsAmpl = thisIsAmpl def mouseDragEvent(self, ev): print("Uncaptured drag event") # if self.enableDrag: # ## if axis is specified, event will only affect that axis. # ev.accept() # if self.state['mouseMode'] != pg.ViewBox.RectMode or ev.button() == QtCore.Qt.RightButton: # ev.ignore() # if ev.isFinish(): ## This is the final move in the drag; draw the actual box # print("dragging done") # self.rbScaleBox.hide() # self.sigMouseDragged.emit(ev.buttonDownScenePos(ev.button()),ev.scenePos(),ev.screenPos()) # else: # ## update shape of scale box # self.updateScaleBox(ev.buttonDownPos(), ev.pos()) # else: # pass def mousePressEvent(self, ev): if self.enableDrag and ev.button() == self.parent.MouseDrawingButton: if self.thisIsAmpl: self.parent.mouseClicked_ampl(ev) else: self.parent.mouseClicked_spec(ev) ev.accept() else: ev.ignore() def mouseReleaseEvent(self, ev): if self.enableDrag and ev.button() == self.parent.MouseDrawingButton: if self.thisIsAmpl: self.parent.mouseClicked_ampl(ev) else: self.parent.mouseClicked_spec(ev) ev.accept() else: ev.ignore() def keyPressEvent(self, ev): # This catches the keypresses and sends out a signal #self.emit(SIGNAL("keyPressed"),ev) super(DragViewBox, self).keyPressEvent(ev) self.keyPressed.emit(ev.key())
class CustomChannelMenu(QtGui.QWidget): sigReturn = QtCore.Signal(int) sigSpinChanged = QtCore.Signal(int, float) def __init__(self, parent=None): super(CustomChannelMenu, self).__init__() self._rowlen = 3 #self.w = QtGui.QWidget() self.layout = QtGui.QGridLayout() self.setLayout(self.layout) self.initUI() self.parent = parent self.id = None def initUI(self): label = QtGui.QLabel() label.setText("amplitude scale:") self.amplitude_scale = QtGui.QDoubleSpinBox() self.amplitude_scale.setMaximum(10000) self.amplitude_scale.setMinimum(1) self.amplitude_scale.valueChanged.connect(self.ampScale_value_changed) self.layout.addWidget(label) self.layout.addWidget(self.amplitude_scale) # self.amplitude_scale = QtGui.QLineEdit(self) # self.layout.addWidget(self.amplitude_scale) # sep=QtGui.QFrame(); # sep.setFrameShape(QtGui.QFrame.HLine) # sep.setFrameShadow(QtGui.QFrame.Sunken) # self.layout.addWidget(sep) # self.ok_button = QtGui.QPushButton("OK", self) # self.ok_button.clicked[bool].connect(self.ok_pressed) # self.cancel_button= QtGui.QPushButton("Cancel", self) # self.cancel_button.clicked[bool].connect(self.cancel_pressed) # self.layout.addWidget(self.ok_button) # self.layout.addWidget(self.cancel_button) def ok_pressed(self): if self.selected_id == -1: self.selected_id = -3 # ok pressed but no class change ( move, scale) self.sigReturn.emit(self.selected_id) self.selected_id = -1 self.parentWidget().close() pass def cancel_pressed(self): self.sigReturn.emit(-1) self.parentWidget().close() def set_ampScale(self, id, val): self.id = id self.amplitude_scale.setValue(val) def ampScale_value_changed(self, val): self.sigSpinChanged.emit(self.id, val)
class MatplotlibWindow(QtGui.QDialog): plot_clicked = QtCore.Signal(int) back_to_plot = QtCore.Signal() image_clicked = QtCore.Signal(np.ndarray) def __init__(self, parent=None): super().__init__(parent) # a figure instance to plot on self.figure = Figure() # this is the Canvas Widget that displays the `figure` # it takes the `figure` instance as a parameter to __init__ self.canvas = FigureCanvas(self.figure) # this is the Navigation widget # it takes the Canvas widget and a parent self.toolbar = NavigationToolbar(self.canvas, self) # set the layout layout = QtGui.QVBoxLayout() layout.addWidget(self.toolbar) layout.addWidget(self.canvas) self.setLayout(layout) self.canvas.mpl_connect('button_press_event', self.onclick) self.canvas.mpl_connect('pick_event', self.onpick) def onclick(self, event): try: if event.dblclick and event.button == 1: ns = self.figure.axes[0].get_subplotspec().get_gridspec( ).get_geometry() assert (ns[0] == ns[1]) ns = ns[0] #gets the number of the subplot that is of interest for us n_sub = event.inaxes.rowNum * ns + event.inaxes.colNum self.figure.clf() self.plot_clicked.emit(n_sub) elif event.button == 3: self.back_to_plot.emit() except: pass def onpick(self, event): artist = event.artist if isinstance(artist, AxesImage): im = artist A = im.get_array() print('image clicked', A.shape) self.image_clicked.emit(A) def plot(self): self.canvas.draw()
class BeadRecWidget(Widget): """ Displays the FFT transform of the image. """ sigROIToggled = QtCore.Signal(bool) # (enabled) sigRunClicked = QtCore.Signal() def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Viewbox self.cwidget = pg.GraphicsLayoutWidget() self.vb = self.cwidget.addViewBox(row=1, col=1) self.vb.setMouseMode(pg.ViewBox.RectMode) self.img = pg.ImageItem(axisOrder='row-major') self.img.translate(-0.5, -0.5) self.vb.addItem(self.img) self.vb.setAspectLocked(True) self.hist = pg.HistogramLUTItem(image=self.img) self.hist.vb.setLimits(yMin=0, yMax=66000) self.hist.gradient.loadPreset('greyclip') for tick in self.hist.gradient.ticks: tick.hide() self.cwidget.addItem(self.hist, row=1, col=2) self.roiButton = guitools.BetterPushButton('Show ROI') self.roiButton.setCheckable(True) self.runButton = QtWidgets.QCheckBox('Run') self.ROI = guitools.VispyROIVisual(rect_color='yellow', handle_color='orange') # Add elements to GridLayout grid = QtWidgets.QGridLayout() self.setLayout(grid) grid.addWidget(self.cwidget, 0, 0, 1, 6) grid.addWidget(self.roiButton, 1, 0, 1, 1) grid.addWidget(self.runButton, 1, 1, 1, 1) # Connect signals self.roiButton.toggled.connect(self.sigROIToggled) self.runButton.clicked.connect(self.sigRunClicked) def getROIGraphicsItem(self): return self.ROI def showROI(self, position, size): self.ROI.position = position self.ROI.size = size self.ROI.show() def hideROI(self): self.ROI.hide() def updateImage(self, image): self.img.setImage(image, autoLevels=False)
class DmcamThread(QtCore.QThread): # Signals to relay thread progress to the main GUI thread frameReadySignal = QtCore.Signal(int) captureDoneSignal = QtCore.Signal(int) run = True def __init__(self, parent=None): super(DmcamThread, self).__init__(parent) # You can change variables defined here after initialization - but before calling start() def stop_me(self): print('stop me ..') self.run = False def run(self): global frame_info print(" Start capture ...") dmcam.cap_start(dev) # blocking code goes here self.run = True while self.run: global f_dist, f_gray, frame_data, f_mutex if dev is None: time.sleep(0.5) # get one frame finfo = dmcam.frame_t() ret = dmcam.cap_get_frames(dev, 1, frame_data, finfo) # will blocking wait # ret = dmcam.cap_get_frame(dev, frame_data, None) # print("get %d frames" % ret) if ret > 0: w = finfo.frame_info.width h = finfo.frame_info.height # print(" frame @ %d, %dx%d (%d)" % # (finfo.frame_info.frame_idx, # finfo.frame_info.width, # finfo.frame_info.height, # finfo.frame_info.frame_size)) f_mutex.lock() frame_info = finfo.frame_info dist_cnt, f_dist = dmcam.frame_get_distance( dev, w * h, frame_data, finfo.frame_info) gray_cnt, f_gray = dmcam.frame_get_gray( dev, w * h, frame_data, finfo.frame_info) if dist_cnt != w * h: f_dist = None if gray_cnt != w * h: f_gray = None f_mutex.unlock() self.frameReadySignal.emit(0) self.captureDoneSignal.emit(int(self.run))
class ThreadOneAcq(QtCore.QThread): '''Second thread for controling one or anumber of acquisition independtly ''' newDataRun = QtCore.Signal(object) newStateCam = QtCore.Signal( bool) # signal to emit the state (running or not) of the camera def __init__(self, parent): super(ThreadOneAcq, self).__init__() self.parent = parent self.cam0 = parent.cam0 self.stopRunAcq = False self.itrig = parent.itrig self.LineTrigger = parent.LineTrigger self.converter = pylon.ImageFormatConverter() def newRun(self): self.stopRunAcq = False def run(self): self.newStateCam.emit(True) for i in range(self.parent.nbShot): if self.stopRunAcq is not True: data = self.cam0.GrabOne(200000) data = self.converter.Convert(data) data = data.GetArray() #, dtype=np.double) data.squeeze() self.data = np.rot90(data, 1) if i < self.parent.nbShot - 1: self.newStateCam.emit(True) else: self.newStateCam.emit(False) time.sleep(0.1) if np.max(self.data) > 0: self.newDataRun.emit(self.data) else: break self.newStateCam.emit(False) def stopThreadOneAcq(self): self.stopRunAcq = True try: self.cam0.ExecuteSoftwareTrigger() except: pass
class ULensesWidget(Widget): """ Alignment widget that shows a grid of points on top of the image in the viewbox.""" sigULensesClicked = QtCore.Signal() sigUShowLensesChanged = QtCore.Signal(bool) # (enabled) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Graphical Elements self.ulensesButton = guitools.BetterPushButton('uLenses') self.ulensesCheck = QtWidgets.QCheckBox('Show uLenses') self.xEdit = QtWidgets.QLineEdit('0') self.yEdit = QtWidgets.QLineEdit('0') self.pxEdit = QtWidgets.QLineEdit('157.5') self.upEdit = QtWidgets.QLineEdit('1182') self.ulensesPlot = guitools.VispyScatterVisual(color='red', symbol='x') # Add elements to GridLayout ulensesLayout = QtWidgets.QGridLayout() self.setLayout(ulensesLayout) ulensesLayout.addWidget(QtWidgets.QLabel('Pixel Size'), 0, 0) ulensesLayout.addWidget(self.pxEdit, 0, 1) ulensesLayout.addWidget(QtWidgets.QLabel('Periodicity'), 1, 0) ulensesLayout.addWidget(self.upEdit, 1, 1) ulensesLayout.addWidget(QtWidgets.QLabel('X offset'), 2, 0) ulensesLayout.addWidget(self.xEdit, 2, 1) ulensesLayout.addWidget(QtWidgets.QLabel('Y offset'), 3, 0) ulensesLayout.addWidget(self.yEdit, 3, 1) ulensesLayout.addWidget(self.ulensesButton, 4, 0) ulensesLayout.addWidget(self.ulensesCheck, 4, 1) # Connect signals self.ulensesButton.clicked.connect(self.sigULensesClicked) self.ulensesCheck.toggled.connect(self.sigUShowLensesChanged) def getParameters(self): """ Returns the X offset, Y offset, pixel size, and periodicity parameters respectively set by the user.""" return (np.float(self.xEdit.text()), np.float(self.yEdit.text()), np.float(self.pxEdit.text()), np.float(self.upEdit.text())) def getPlotGraphicsItem(self): return self.ulensesPlot def setData(self, x, y): """ Updates plot with new parameters. """ self.ulensesPlot.setData(x=x, y=y) def setULensesVisible(self, visible): """ Updates visibility of plot. """ self.ulensesPlot.setVisible(visible)
class Cursor(GraphicsObject): sigPlotChanged = QtCore.Signal(object) sigPositionChanged = QtCore.Signal(object) def __init__(self, pos): super().__init__() self.pos = pos self.pen = fn.mkPen((255, 255, 100), width=1) self.y1 = 5000 self.picture = None self._boundingRect = None self._line = None def dataBounds(self, ax, *args, **kws): if ax == 0: return self.pos, self.pos return 0, self.y1 def boundingRect(self): if self._boundingRect is not None: return self._boundingRect br = self.viewRect() if br is None: return QtCore.QRectF() px = self.pixelLength(direction=Point( 1, 0), ortho=True) or 0 # get pixel length orthog. to line w = 1 * px br.setLeft(-w) br.setRight(w) # br.setRight(0) br = br.normalized() self._boundingRect = br return br def paint(self, p, opt, widget, **args): p.setPen(self.pen) line = self._line if line is None: br = self.boundingRect() self._line = line = QtCore.QLineF(0.0, br.bottom(), 0.0, br.top()) p.drawLine(line) def setPos(self, pos): if pos != self.pos: self.pos = pos # self.informViewBoundsChanged() # self.sigPlotChanged.emit(self) # self._boundingRect = None GraphicsObject.setPos(self, Point([self.pos, 0]))
class OneDViewer(Viewer, pg.PlotWidget): selection_changed = QtCore.Signal(object, object) # self, {axis: value, ...} def __init__(self, axes): pg.PlotWidget.__init__(self) self.line = self.addLine(x=0, movable=True) self.curve = self.plot() Viewer.__init__(self, axes) self.line.sigDragged.connect(self.line_moved) def update_selection(self): axis = self.selected_axes[0] self.line.setValue(self.data_axes[axis].index) Viewer.update_selection(self) def line_moved(self): ax = self.selected_axes[0] val = self.data_axes[ax].value_at(int(np.round(self.line.value()))) self.selection_changed.emit(self, {ax: val}) def update_display(self): if self.data is None: self.curve.setData([]) return axis = self.selected_axes[0] self.setLabels(bottom=axis) data = self.get_data() self.curve.setData(data) axvals = self.data_axes[axis].values self.getAxis('bottom').setTicks([[(i, "%0.2g" % axvals[i]) for i in range(len(axvals))]])
class OscilloscopeThread(QtCore.QThread): sigNewData = QtCore.Signal( object ) ## (time, value) - emitted when a new value is read from the serial port def __init__(self, port): self.stopped = True QtCore.QThread.__init__(self) self.port = serial.Serial(port) def start(self): self.stopped = False QtCore.QThread.start(self) def stop(self): self.stopped = True def quit(self): self.stop() def run(self): while True: if self.stopped: break try: n = int(self.port.readline()) t = pg.time() except: continue self.sigNewData.emit((t, n))
class ThreadRunAcq(QtCore.QThread): newDataRun = QtCore.Signal(object) def __init__(self, parent=None): super(ThreadRunAcq, self).__init__(parent) self.parent = parent self.cam0 = self.parent.cam0 self.stopRunAcq = False self.itrig = self.parent.itrig self.seuil = self.parent.seuil def run(self): global data self.cam0.reset_frame_ready() self.cam0.start_live(show_display=False) self.cam0.enable_trigger(True) if not self.cam0.callback_registered: self.cam0.register_frame_ready_callback() #print('-----> Start multi acquisition') while True: self.cam0.reset_frame_ready() if self.stopRunAcq: break #print('-----> Acquisition ended') if self.itrig == 0 or self.itrig == 2: # si cam pas en mode trig externe on envoi un trig soft... self.cam0.send_trigger() # print('trigg') self.cam0.wait_til_frame_ready(2000) data1 = self.cam0.get_image_data() data1 = np.array(data1) #, dtype=np.double) data1.squeeze() data = data1[:, :, 0] self.data = np.rot90(data, 1) if self.itrig == 2: dataF = gaussian_filter(self.data, 3) self.maxx = round(dataF.max(), 3) if self.maxx >= self.seuil: self.newDataRun.emit(self.data) else: pass else: self.newDataRun.emit(self.data) def stopThreadRunAcq(self): #self.cam0.send_trigger() try: self.stopRunAcq = True except: pass self.cam0.stop_live()
class Thread(QtCore.QThread): dataChanged = QtCore.Signal(np.ndarray) def __init__(self, close_fun, data_function, plot_fun, interval, *args, **kwargs): super(Thread, self).__init__(*args, **kwargs) self.idx = 1 self.data_function = data_function self.dataChanged.connect(plot_fun) self.interval = interval self.stop_parent = close_fun def run(self): self.threadactive = True while self.threadactive: try: data = self.data_function(self.idx) self.dataChanged.emit(data) self.idx += 1 QtCore.QThread.msleep(self.interval) except StopIteration: self.stop() break def stop(self): self.threadactive = False self.stop_parent(None) self.wait()
class ThreadRec(ThreadPollInput): recv_start_index = QtCore.Signal(str, int) def __init__(self, name, input_stream, av_container, av_stream, timeout=200, parent=None): ThreadPollInput.__init__(self, input_stream, timeout=timeout, return_data=True, parent=parent) self.name = name self.av_container = av_container self.av_stream = av_stream self._start_index = None def process_data(self, pos, data): if self._start_index is None: self._start_index = int(pos - 1) self.recv_start_index.emit(self.name, self._start_index) frame = av.VideoFrame.from_ndarray(data, format='rgb24') for packet in self.av_stream.encode(frame): self.av_container.mux(packet)
class ColorMapWidget(ptree.ParameterTree): """ This class provides a widget allowing the user to customize color mapping for multi-column data. Given a list of field names, the user may specify multiple criteria for assigning colors to each record in a numpy record array. Multiple criteria are evaluated and combined into a single color for each record by user-defined compositing methods. For simpler color mapping using a single gradient editor, see :class:`GradientWidget <pyqtgraph.GradientWidget>` """ sigColorMapChanged = QtCore.Signal(object) def __init__(self): ptree.ParameterTree.__init__(self, showHeader=False) self.params = ColorMapParameter() self.setParameters(self.params) self.params.sigTreeStateChanged.connect(self.mapChanged) ## wrap a couple methods self.setFields = self.params.setFields self.map = self.params.map def mapChanged(self): self.sigColorMapChanged.emit(self)
class ColorAxisParam(pg.parametertree.types.GroupParameter): axis_color_changed = QtCore.Signal(object) # self def __init__(self, name, slicer): self.slicer = slicer pg.parametertree.types.GroupParameter.__init__( self, name=name, children=[ { 'name': 'axis', 'type': 'list', 'values': ['none'] }, { 'name': 'mode', 'type': 'list', 'values': ['discrete', 'range'], 'visible': False }, { 'name': 'colors', 'type': 'group', 'visible': False }, ]) self.update_axes() self.child('axis').sigValueChanged.connect(self.axis_changed) self.child('colors').sigTreeStateChanged.connect(self.colors_changed) def update_axes(self): axis_names = list(self.slicer.axes.keys()) self.child('axis').setLimits(['none'] + axis_names) def axis_changed(self): with pg.SignalBlock( self.child('colors').sigTreeStateChanged, self.colors_changed): if self['axis'] == 'none': self.child('mode').setOpts(visible=False) self.child('colors').setOpts(visible=False) else: self.child('mode').setOpts(visible=True) self.child('colors').setOpts(visible=True) values = self.slicer.axes[self['axis']].values for ch in self.child('colors').children(): self.child('colors').removeChild(ch) for i, v in enumerate(values): color = pg.mkColor((i, int(len(values) * 1.2))) ch = pg.parametertree.types.SimpleParameter(name=str(v), type='color', value=color) self.child('colors').addChild(ch) self.colors_changed() def colors_changed(self): self.colors = [ch.value() for ch in self.child('colors').children()] self.axis_color_changed.emit(self)
class SingleValueModel(QtCore.QObject): """A cursor position is either a float or int (determined at instantiation) and preserves the type in assignment. Furthermore, the object emits either an int or float pyqtSignal when the value is changed through the setter.""" value_changed = QtCore.Signal(object) def __init__(self, val: object): super().__init__() self._val = val def set_val(self, newval, block=False): if type(self._val) is type(newval): self._val = newval else: self._val = type(self._val)(newval) if not block: self.value_changed.emit(self._val) @property def val(self): return self._val @val.setter def val(self, newval): if type(self._val) is type(newval): self._val = newval else: self._val = type(self._val)(newval) self.value_changed.emit(self._val) @QtCore.pyqtSlot(object) def on_value_changed(self, newval): self.val = newval
class ThreadOneAcq(QtCore.QThread): newDataOne=QtCore.Signal(object) def __init__(self, parent=None): super(ThreadOneAcq,self).__init__(parent) self.parent=parent self.cam0 = self.parent.cam0 self.stopOneAcq=False self.itrig= self.parent.itrig self.converter=pylon.ImageFormatConverter() print('one img') def run(self): data=self.cam0.GrabOne(200000) data1=self.converter.Convert(data) data1 = data1.GetArray()#, dtype=np.double) data1.squeeze() # data=data1[:,:,0] data=np.rot90(data1,1) self.newDataOne.emit(data) def stopThreadOneAcq(self): #self.cam0.send_trigger() try : self.cam0.ExecuteSoftwareTrigger() self.stopRunAcq=True except : pass self.cam0.stop_live()
class SliderSpinBox(QtGui.QWidget): valueChanged = QtCore.Signal(float) updating = False def __init__(self, spin_args={}): super(SliderSpinBox, self).__init__() self.layout = QtGui.QGridLayout(self) self.spin = pg.SpinBox(value=0, **spin_args) self.spin.valueChanged.connect( lambda: self.setValue(self.spin.value())) self.slide = QtGui.QSlider(QtGui.Qt.Horizontal) self.slide.setTickPosition(2) self.slide.setTickInterval(1) self.slide.valueChanged.connect( lambda: self.setValue(self.slide.value())) self.layout.addWidget(self.slide, 0, 0, 1, 4) self.layout.addWidget(self.spin, 0, 4) self.setLayout(self.layout) def value(self): return self.spin.value() def setValue(self, value): if not self.updating: self.updating = True self.spin.setValue(value) self.slide.setValue(value) self.valueChanged.emit(value) self.updating = False
class ThreadRunAcq(QtCore.QThread): newDataRun=QtCore.Signal(object) def __init__(self, parent=None,mte=None): super(ThreadRunAcq,self).__init__(parent) self.mte = mte self.stopRunAcq=False def run(self): global data,a #print('-----> Start multi acquisition') #self.mte.Acquisition(timeout=2000) while True : if self.stopRunAcq: break if self.mte.IsAcquisitionRunning()==False: self.mte.Acquisition(N=1,timeout=120000) # print('-----> Acquisition ') try : data = self.mte.GetAcquiredData() data = np.array(data, dtype=np.double) self.data=np.rot90(self.data,1) self.newDataRun.emit(data) # print('acquisition done') except : pass else: print('acquisition en cours...') def stopThreadRunAcq(self): self.stopRunAcq=True self.mte.StopAcquisition()
class SplitContainer(Container, QtGui.QSplitter): """Horizontal or vertical splitter with some changes: - save/restore works correctly """ sigStretchChanged = QtCore.Signal() def __init__(self, area, orientation): QtGui.QSplitter.__init__(self) self.setOrientation(orientation) Container.__init__(self, area) #self.splitterMoved.connect(self.restretchChildren) def _insertItem(self, item, index): self.insertWidget(index, item) item.show( ) ## need to show since it may have been previously hidden by tab def saveState(self): sizes = self.sizes() if all([x == 0 for x in sizes]): sizes = [10] * len(sizes) return {'sizes': sizes} def restoreState(self, state): sizes = state['sizes'] self.setSizes(sizes) for i in range(len(sizes)): self.setStretchFactor(i, sizes[i]) def childEvent(self, ev): QtGui.QSplitter.childEvent(self, ev) Container.childEvent(self, ev)
class MeasurementThread(QtCore.QThread): newData = QtCore.Signal(object) measure = False start_time = None def start(self, port, speed, timeout): self.measure = True self.ser = serial.Serial(port, speed, timeout=timeout) super(MeasurementThread, self).start() def run(self): rb = RingBuffer(56) while self.measure: rb.append(self.ser.read(1)[0]) if rb[0] == ord("B") and rb[1] == ord("E") and rb[54] == ord( "E") and rb[55] == ord("N"): timestamp = int.from_bytes(bytes(rb[2:6]), byteorder="little") timestamp = timestamp & 0xffffffff data = np.fromstring(bytes(rb[6:54]), dtype="<f") if self.start_time is None: self.start_time = timestamp self.newData.emit([timestamp - self.start_time, data]) self.ser.close() def stop(self): self.measure = False self.start_time = None
class module(QtCore.QObject): paramListUpdated = QtCore.Signal(list) def __init__(self): super(module, self).__init__() moreparams = [{ 'name': 'SubModule', 'type': 'list', 'values': { 'sm1': submodule(), 'sm2': submodule(), 'sm3': submodule() }, 'set': self.setSubmodule }] self.params = Parameter.create(name='Test', type='group', children=moreparams) ExtendedParameter.setupExtended(self.params) self.sm = None def paramList(self): p = [self.params] if self.sm is not None: for a in self.sm.paramList(): p.append(a) return p def setSubmodule(self, sm): self.sm = sm self.paramListUpdated.emit(self.paramList())
class ToggleEye(QtGui.QLabel): activeChanged = QtCore.Signal(bool) def __init__(self, parent=None): super(ToggleEye, self).__init__(parent=parent) self._active = True self._eye_open = QtGui.QPixmap(":icons/icons/stock-eye-20.png") self._eye_closed = QtGui.QPixmap(":icons/icons/stock-eye-20-gray.png") self.setPixmap(self._eye_open) def active(self): return self._active def setActive(self, b): if b == self._active: return self._active = b if b: self.setPixmap(self._eye_open) else: self.setPixmap(self._eye_closed) def toggle(self): if self.active(): self.setActive(False) else: self.setActive(True) def mousePressEvent(self, ev): self.toggle() self.activeChanged.emit(self._active)
class SingleValueModel(QtCore.QObject): """A cursor position is either a float or int (determined at instantiation) and preserves the type in assignment. Furthermore, the object emits either an int or float pyqtSignal when the value is changed through the setter.""" value_set = QtCore.Signal(object) def __init__(self, val: object): super().__init__() self._value = val def __repr__(self): return f"Model[{self._value}]" def __str__(self): return self.__repr__() def set_value(self, newval, block=False): self._value = newval if not block: self.value_set.emit(self._value) @property def value(self): return self._value @value.setter def value(self, newval): self.set_value(newval, block=False)