Example #1
0
def main(camera):
    app = Qt.QApplication([])

    t = ParameterTree()
    t.resize(600, 800)
    t.show()

    def value_changed(param, value):
        try:
            setattr(camera, param.name(), value)
        except Exception as err:
            Qt.QMessageBox.critical(None,
                                    "Error setting {}".format(param.name()),
                                    repr(err))

    def connect(param, slot):
        param.sigValueChanged.connect(slot)
        for child in param.children():
            connect(child, slot)

    with camera:
        t.setWindowTitle(camera.device_info.GetFriendlyName())
        data = parameter_dict(camera)
        # limits are dynamic (ex: max offset-x depends on current value
        # of width).
        strip_limits(data)
        p = Parameter.create(**data)
        t.setParameters(p, showTop=False)
        connect(p, value_changed)
        app.exec_()
Example #2
0
def main():
    app = QtWidgets.QApplication(sys.argv)

    parametertree = ParameterTree()
    ParameterEx(parametertree)
    parametertree.show()

    sys.exit(app.exec_())
Example #3
0
class EyeTrackingExperimentWindow(SimpleExperimentWindow):
    """Window for controlling an experiment where the tail and the eyes
    of an embedded fish are tracked.

    Parameters
    ----------

    Returns
    -------

    """
    def __init__(self, *args, **kwargs):
        self.camera_display = CameraEyesSelection(
            experiment=kwargs["experiment"])

        self.camera_splitter = QSplitter(Qt.Horizontal)
        self.monitoring_widget = QWidget()
        self.monitoring_layout = QVBoxLayout()
        self.monitoring_widget.setLayout(self.monitoring_layout)

        # Stream plot:
        self.stream_plot = MultiStreamPlot(time_past=30)

        self.monitoring_layout.addWidget(self.stream_plot)

        # Tracking params button:
        self.button_tracking_params = QPushButton("Tracking params")
        self.button_tracking_params.clicked.connect(
            self.open_tracking_params_tree)
        self.monitoring_layout.addWidget(self.button_tracking_params)

        self.track_params_wnd = None
        # self.tracking_layout.addWidget(self.camera_display)
        # self.tracking_layout.addWidget(self.button_tracking_params)

        super().__init__(*args, **kwargs)

    def construct_ui(self):
        """ """
        self.stream_plot.add_stream(self.experiment.data_acc,
                                    ["th_e0", "th_e1"])
        self.experiment.gui_timer.timeout.connect(self.stream_plot.update)
        previous_widget = super().construct_ui()
        self.monitoring_layout.addWidget(previous_widget)
        self.monitoring_layout.setStretch(1, 1)
        self.monitoring_layout.setStretch(0, 1)
        self.camera_splitter.addWidget(self.camera_display)
        self.camera_splitter.addWidget(self.monitoring_widget)
        return self.camera_splitter

    def open_tracking_params_tree(self):
        """ """
        self.track_params_wnd = ParameterTree()
        self.track_params_wnd.setParameters(
            self.experiment.tracking_method.params, showTop=False)
        self.track_params_wnd.setWindowTitle("Tracking data")
        self.track_params_wnd.show()
Example #4
0
    def test_dict_to_pyqtgraph_with_options(self):
        cfg = collections.OrderedDict(
            {
                "bool": True,
                "int": 5,
                "expected_float": 2,
                "str": "strdrr",
                "vs": [1.0, 2.5, 7]
                # 'Area Sampling' : dictwidgetpyqtgraph.AreaSamplingParameter(name='Area Sampling')
            }
        )
        captions = {"int": "toto je int"}

        opts = {}
        opts = {
            "children": {
                "vs": {
                    "title": "voxelsize",
                    "children": {
                        "0": {"title": "z", "suffix": "m", "siPrefix": True},
                        "1": {"title": "x", "suffix": "m", "siPrefix": True},
                        "2": {"title": "y", "suffix": "m", "siPrefix": True},
                    },
                },
                "expected_float": {"type": "float", "title": "Exp. float"},
            }
        }

        params = ptools.to_pyqtgraph_struct("params", cfg, opts=opts)
        params["children"].append(ptools.AreaSamplingParameter(name="Area Sampling"))
        # logger.debug(params)

        # params[0]['title'] = "Pokusny title"
        # params[0]['my note'] = "poznamka"

        p = Parameter.create(**params)
        # p = Parameter.create(name='params', type='group', children=params)
        t = ParameterTree()
        logger.debug(p.getValues())
        lst = p.saveState()
        vals = p.getValues()

        name, dict_again = ptools.from_pyqtgraph_struct(lst)
        assert name == "params"
        assert "expected_float" in dict_again
        assert dict_again["expected_float"] == 2.0
        t.setParameters(p, showTop=False)
        t.show()
        val_before0 = p.param("Area Sampling", "areasize_px", "0").value()
        val_before1 = p.param("Area Sampling", "areasize_mm", "0").value()
        p.param("Area Sampling", "voxelsize_mm", "0").setValue(0.3)
        val_after0 = p.param("Area Sampling", "areasize_px", "0").value()
        val_after1 = p.param("Area Sampling", "areasize_mm", "0").value()
Example #5
0
def main():
    app = QtWidgets.QApplication(sys.argv)

    parametertree = ParameterTree()
    ptree = ParameterEx(parametertree)
    parametertree.show()
    ptree.settings.child('itemss', 'itemsbis').setValue(dict(all_items=['item1', 'item2', 'item3'],
                                                             selected=['item3']))

    ptree.settings.child('itemss', 'itemsbis').setValue(dict(all_items=['item1', 'item2', 'item3'],
                                                             selected=['item1', 'item3']))
    sys.exit(app.exec_())
Example #6
0
class View(QtGui.QWidget):
    def __init__(self, parent=None, with_config=False, **kargs):
        QtGui.QWidget.__init__(self, parent)

        self.resize(800, 600)

        mainlayout = QtGui.QVBoxLayout()
        self.setLayout(mainlayout)

        self.glview = gl.GLViewWidget()
        mainlayout.addWidget(self.glview)
        self.glview.setCameraPosition(160, 160, 15)

        if with_config:
            h = QtGui.QHBoxLayout()
            mainlayout.addLayout(h)
            but = QtGui.QPushButton('Config',
                                    icon=QtGui.QIcon.fromTheme('configure'))
            h.addWidget(but)
            but.clicked.connect(self.open_params)
            but = QtGui.QPushButton('Save png',
                                    icon=QtGui.QIcon.fromTheme('save'))
            h.addWidget(but)
            but.clicked.connect(self.open_save_dialog)

        _params = [
            {
                'name': 'cortical_mesh',
                'type': 'list',
                'values': cortical_meshes.keys(),
                'value': 'BrainMesh_ICBM152'
            },
            {
                'name': 'cortical_alpha',
                'type': 'float',
                'value': .1,
                'limits': [0., 1.],
                'step': .01
            },
            {
                'name': 'cortical_color',
                'type': 'color',
                'value': 'w'
            },
            {
                'name': 'background_color',
                'type': 'color',
                'value': 'k'
            },
        ]
        self.params = Parameter.create(name='params',
                                       type='group',
                                       children=_params)
        self.tree = ParameterTree(parent=self)
        self.tree.setParameters(self.params)
        self.tree.setWindowFlags(QtCore.Qt.Dialog)

        self.mesh = None
        for k, v in kargs.items():
            self.params[k] = v
        self.change_background_color()
        self.plot_mesh()
        self.change_color_mesh()

        self.params.param('cortical_mesh').sigValueChanged.connect(
            self.plot_mesh)
        self.params.param('cortical_alpha').sigValueChanged.connect(
            self.change_color_mesh)
        self.params.param('cortical_color').sigValueChanged.connect(
            self.change_color_mesh)
        self.params.param('background_color').sigValueChanged.connect(
            self.change_background_color)

        self.glview.resizeGL(self.glview.width(), self.glview.height())

    def open_params(self):
        self.tree.show()

    def change_background_color(self):
        background_color = self.params['background_color']
        try:
            self.glview.setBackgroundColor(background_color)
        except:
            #~ #FIXME this is buggy in pyqtgrap0.9.8
            bgcolor = pg.mkColor(QtGui.QColor(background_color))
            glClearColor(bgcolor.red() / 255.,
                         bgcolor.green() / 255.,
                         bgcolor.blue() / 255., 1.0)
            glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)
            self.glview.paintGL()
            self.glview.update()

    def plot_mesh(self):
        vertexes, faces = cortical_meshes[self.params['cortical_mesh']]
        alpha = self.params['cortical_alpha']
        c = self.params['cortical_color']
        color = (c.red() / 255., c.green() / 255., c.blue() / 255., alpha)

        if self.mesh is None:

            self.mesh = gl.GLMeshItem(
                vertexes=vertexes,
                faces=faces,
                smooth=True,
                drawFaces=True,
                drawEdges=False,
                edgeColor=(1., 1., 1., .2),
                color=color,
                computeNormals=False,
                glOptions='translucent',
                #~ shader='balloon',
                shader='shaded',
            )
            self.glview.addItem(self.mesh)
        else:
            self.mesh.setMeshData(vertexes=vertexes, faces=faces)
            #~ self.mesh.set

    def change_color_mesh(self):
        alpha = self.params['cortical_alpha']
        c = self.params['cortical_color']
        color = (c.red() / 255., c.green() / 255., c.blue() / 255., alpha)
        self.mesh.setColor(color)

    def add_node(self, coords, color=(1, 1, 1, 0), size=5):
        sp1 = gl.GLScatterPlotItem(pos=coords,
                                   size=size,
                                   color=color,
                                   pxMode=False)
        self.glview.addItem(sp1)

    def add_edge(self, node_coords, connection_with, color=(1, 1, 1, 1)):
        for i in range(connection_with.shape[0]):
            for j in range(connection_with.shape[1]):
                if connection_with[i, j] == 0: continue
                plt = gl.GLLinePlotItem(pos=np.vstack(
                    [node_coords[i], node_coords[j]]),
                                        color=color,
                                        width=connection_with[i, j])
                self.glview.addItem(plt)

    def open_save_dialog(self):

        pathname = unicode(
            QtGui.QDesktopServices.storageLocation(
                QtGui.QDesktopServices.DesktopLocation))
        filename = os.path.join(pathname, 'Il est beau le cerveau.png')
        filename = QtGui.QFileDialog.getSaveFileName(self, u'Save png',
                                                     filename, 'PNG (*.png)')
        if filename:
            self.to_file(filename)

    def to_file(self, filename):
        self.glview.readQImage().save(filename)
Example #7
0
        'name': 'TextParam',
        'type': 'text',
        'value': 'Some text...'
    },
]

#p = pTypes.ParameterSet("params", params)
p = Parameter(name='params', type='group', children=params)


def change(param, changes):
    print "tree changes:"
    for param, change, data in changes:
        print "  [" + '.'.join(p.childPath(param)) + "]   ", change, data


p.sigTreeStateChanged.connect(change)

t = ParameterTree()
t.setParameters(p, showTop=False)
t.show()
t.resize(400, 600)
t2 = ParameterTree()
t2.setParameters(p, showTop=False)
t2.show()
t2.resize(400, 600)

import sys
if sys.flags.interactive == 0:
    app.exec_()
Example #8
0
            print p['row'], p['col']
            pix = 8 * p['row'] + p['col']
            # retrieve interpolation data
            (xo, yo) = interpolation[pix]
            # calculate phase pattern
            fft_phase = gp.initial_phase_orig(257 - xo, 257 - yo, 512)
            gp.write2file(fft_phase, gp.phasemap, SLMpath, '99')
            shutil.copyfile(
                bobMirrorFileName,
                '/mnt/SLM/Dan/OptimizeSLM/Patterns/OrigSettings/SLM_100.dat')
            send(99)
            print 'From PC: ', wait()
            f = open(settingsFile, 'w')
            f.write('%d' % pix + '\n')
            f.flush()
            f.close()


p.sigTreeStateChanged.connect(change)
t = ParameterTree()
t.setParameters(p, showTop=False)
t.show()
t.raise_()
pix = 8 * p['row'] + p['col']

send(pix)
if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()
Example #9
0
class SpectrumViewer(QtGui.QMainWindow):
        '''The application main window.'''

        def __init__(self, parent=None):
            # We're not calling the super method so we can span an new instance in
            # the new function.
            # However, when the first created window is closed, all windoes close
            # super(SpectrumViewer, self).__init__()
            QtGui.QMainWindow.__init__(self, parent)
            self.spectra = []
            self.plots = []
            self.initUI()

        def initToolBar(self):
            '''The main toolbar.'''
            # File actions
            self.newAction = QtGui.QAction(QtGui.QIcon('../icons/new.png'), '&New', self)
            self.newAction.setStatusTip('New molecule viewer')
            self.newAction.setShortcut('Ctrl+N')
            self.newAction.triggered.connect(self.new)

            self.openAction = QtGui.QAction(QtGui.QIcon('../icons/open.png'), '&Open', self)
            self.openAction.setStatusTip('Read molecule from file')
            self.openAction.setShortcut('Ctrl+O')
            self.openAction.triggered.connect(self.open)

            self.saveAction = QtGui.QAction(QtGui.QIcon('../icons/save.png'), '&Save', self)
            self.saveAction.setStatusTip('Write molecule to file')
            self.saveAction.setShortcut('Ctrl+S')
            self.saveAction.triggered.connect(self.save)

            self.saveimageAction = QtGui.QAction(QtGui.QIcon('../icons/picture-edit.png'), 'Save &image as PNG', self)
            self.saveimageAction.setStatusTip('Save image as PNG')
            self.saveimageAction.setShortcut('Ctrl+I')
            self.saveimageAction.triggered.connect(self.saveimage)

            self.exitAction = QtGui.QAction(QtGui.QIcon('../icons/exit.png'), '&Exit', self)
            self.exitAction.setShortcut('Ctrl+Q')
            self.exitAction.setStatusTip('Exit application')
            self.exitAction.triggered.connect(QtGui.qApp.quit)

            # View actions
            self.fullScreenAction = QtGui.QAction(QtGui.QIcon('../icons/fullscreen.png'), '&Full Screen', self)
            self.fullScreenAction.setStatusTip('Toggle full screen')
            self.fullScreenAction.setShortcut('F11')
            self.fullScreenAction.triggered.connect(self.fullscreen)

            self.toggleSidebarAction = QtGui.QAction('&Toggle sidebar', self)
            self.toggleSidebarAction.setStatusTip('Toggle sidebar')
            self.toggleSidebarAction.triggered.connect(self.togglesidebar)

            # Spectrum actions
            self.addspectrumAction = QtGui.QAction(QtGui.QIcon('../icons/addspectrum.png'), '&Add spectrum', self)
            self.addspectrumAction.setStatusTip('Add a new spectrum')
            self.addspectrumAction.setShortcut('Ctrl + A')
            self.addspectrumAction.triggered.connect(self.open)

            self.removespectrumAction = QtGui.QAction(QtGui.QIcon('../icons/removespectrum.png'), '&Remove spectrum', self)
            self.removespectrumAction.setStatusTip('Remove a spectrum')
            self.removespectrumAction.setShortcut('Ctrl + R')
            self.removespectrumAction.triggered.connect(self.removespectrum)

            # Toolbars
            self.filetoolbar = self.addToolBar('File')
            self.filetoolbar.addAction(self.newAction)
            self.filetoolbar.addAction(self.openAction)
            self.filetoolbar.addAction(self.saveAction)
            self.filetoolbar.addAction(self.saveimageAction)

            self.viewtoolbar = self.addToolBar('View')
            self.viewtoolbar.addAction(self.fullScreenAction)

            self.spectrumtoolbar = self.addToolBar('Spectrum')
            self.spectrumtoolbar.addAction(self.addspectrumAction)
            self.spectrumtoolbar.addAction(self.removespectrumAction)

        def initMenuBar(self):
            '''The main menubar.'''
            menubar = self.menuBar()
            menubar.setNativeMenuBar(True)

            # Create menus
            file = menubar.addMenu('&File')
            edit = menubar.addMenu('&Edit')
            view = menubar.addMenu('&View')
            spectrum = menubar.addMenu('&Spectrum')
            about = menubar.addMenu('&About')

            # File menu
            file.addAction(self.newAction)
            file.addAction(self.openAction)
            file.addAction(self.saveAction)
            file.addAction(self.saveimageAction)
            file.addSeparator()
            file.addAction(self.exitAction)

            # View menu
            view.addAction(self.fullScreenAction)
            view.addAction(self.toggleSidebarAction)

            # Spectrum menu
            spectrum.addAction(self.addspectrumAction)
            spectrum.addAction(self.removespectrumAction)

        def initParameterTree(self):
            '''The sidebar.'''
            self.parametertree = ParameterTree()
            self.params = []

        def initUI(self):
            '''Initializes the main window widgets.'''
            self.initToolBar()
            self.initMenuBar()
            self.initParameterTree()

            self.plotwidget = pg.PlotWidget()
            self.plot = self.plotwidget.plotItem
            self.plot.setMenuEnabled(False)
            #cross hair
            self.vLine = pg.InfiniteLine(angle=90, movable=False)
            self.hLine = pg.InfiniteLine(angle=0, movable=False)
            self.plotwidget.addItem(self.vLine, ignoreBounds=True)
            self.plotwidget.addItem(self.hLine, ignoreBounds=True)
            self.vb = self.plot.vb
            self.plot.scene().sigMouseMoved.connect(self.mouseMoved)

            widget = QtGui.QWidget()
            hbox = QtGui.QHBoxLayout(widget)
            hbox.addWidget(self.parametertree)
            hbox.addWidget(self.plotwidget, 1)

            self.setCentralWidget(widget)
            self.resize(1200, 600)
            self.setWindowTitle('Molviewer :: Spectrum main window')
            self.show()

        def mouseMoved(self, evt):
            '''Detect mouse movement.'''
            pos = evt
            if self.plot.sceneBoundingRect().contains(pos):
                mousePoint = self.vb.mapSceneToView(pos)
                self.vLine.setPos(mousePoint.x())
                self.hLine.setPos(mousePoint.y())

        def new(self):
            '''Spawn new main window.'''
            spawn = SpectrumViewer(self)
            spawn.setWindowTitle('Molviewer :: Spectrum main window (child)')
            spawn.show()

        def open(self):
            '''Open a new spectrum using the file dialog.'''
            filenames = QtGui.QFileDialog.getOpenFileNames(self, 'Open Files', '', '*.dx;; *.jdx')
            if filenames:
                for f in filenames:
                    spectrum = Spectrum(f)
                    self.addspectrum(spectrum)

        def save(self):
            pass

        def saveimage(self):
            pass

        def draw(self, spectrum):
            '''Draw a new spectrum.

            :param spectrum: The spectrum to draw.
            :type spectrum: spectrum.Spectrum
            :param color: The color in which the spectrum is drawn.

            '''
            p = self.plotwidget.plot(spectrum.x, spectrum.y, pen=spectrum.color)
            if p not in self.plots:
                self.plots.append(p)
            if spectrum.datatype.lower() == 'infrared spectrum':
                # Plot higher wavenumbers to the left hand side
                self.plotwidget.invertX(True)
                self.plotwidget.setLabel('bottom', '1/cm')
            else:
                self.plotwidget.setLabel('bottom', spectrum.xunits)

        def fullscreen(self):
            '''Toggle full screen window.'''
            if self.windowState() & QtCore.Qt.WindowFullScreen:
                self.showNormal()
            else:
                self.showFullScreen()

        def togglesidebar(self):
            if self.parametertree.isVisible():
                self.parametertree.hide()
            else:
                self.parametertree.show()

        def addspectrum(self, spectrum):
            '''Add a new spectrum.

            :param spectrum: The new spectrum.
            :type spectrum: spectrum.Spectrum

            '''
            self.spectra.append(spectrum)
            ind = self.spectra.index(spectrum)
            spectrum.color = spectrumcolors[ind]
            params = [
                {'name': spectrum.title, 'type': 'group', 'children': [
                    {'name': 'Number', 'type': 'int', 'value': self.spectra.index(spectrum)},
                    {'name': 'Color', 'type': 'color', 'value': spectrum.color},
                    {'name': 'Visible', 'type': 'bool', 'value': True},
                    {'name': 'Action Parameter', 'type': 'action'},
                    {'name': 'Spectrum', 'type': 'str', 'value': spectrum, 'visible': False}]
                }]

            p = Parameter.create(name='Files', type='group', children=params)
            p.sigTreeStateChanged.connect(self.change)
            self.parametertree.addParameters(p, showTop=False)
            self.params.append(p)
            self.draw(spectrum)

        def removespectrum(self):
            '''Remove a spectrum from display.'''
            num, ok = QtGui.QInputDialog.getText(self, 'Remove a spectrum', 'Enter spectrum number:')
            if ok and num:
                num = int(num)
                self.plotwidget.removeItem(self.plots[num])
                self.plots.pop(num)
                self.spectra.pop(num)
                self.params.pop(num)
                self.parametertree.clear()
                for p in self.params:
                    self.parametertree.addParameters(p, showTop=False)

        def change(self, param, changes):
            for param, change, data in changes:
                spec = param.parent().child('Spectrum').value()
                index = self.spectra.index(spec)

                if isinstance(param.value(), QtGui.QColor):
                    self.plots[index].setPen(param.value())
                    self.spectra[index].color = param.value()

                if param.name() == 'Visible':
                    if data is False:
                        self.plots[index].clear()
                    elif data is True:
                        self.plots[index].setData(self.spectra[index].x, self.spectra[index].y)
Example #10
0
class View(QtGui.QWidget):
    def __init__(self, parent = None, with_config = False, **kargs ):
        QtGui.QWidget.__init__(self, parent)
        
        self.resize(800,600)
        
        mainlayout = QtGui.QVBoxLayout()
        self.setLayout(mainlayout)
        
        self.glview = gl.GLViewWidget()
        mainlayout.addWidget(self.glview)
        self.glview .setCameraPosition(160,160,15)
        
        
        if with_config:
            h = QtGui.QHBoxLayout()
            mainlayout.addLayout(h)
            but =  QtGui.QPushButton('Config', icon = QtGui.QIcon.fromTheme('configure'))
            h.addWidget(but)
            but.clicked.connect(self.open_params)
            but =  QtGui.QPushButton('Save png', icon = QtGui.QIcon.fromTheme('save'))
            h.addWidget(but)
            but.clicked.connect(self.open_save_dialog)
            
        
        
        _params = [
                {'name': 'cortical_mesh', 'type': 'list', 'values': cortical_meshes.keys(), 'value' :  'BrainMesh_ICBM152'},
                {'name': 'cortical_alpha', 'type': 'float', 'value': .1, 'limits': [0., 1.], 'step' : .01},
                {'name': 'cortical_color', 'type': 'color', 'value':  'w'},
                {'name': 'background_color', 'type': 'color', 'value':  'k'},
            ]
        self.params = Parameter.create(name='params', type='group', children=_params)
        self.tree = ParameterTree(parent = self)
        self.tree.setParameters(self.params)
        self.tree.setWindowFlags(QtCore.Qt.Dialog)
        
        
        
        self.mesh = None
        for k,v in kargs.items():
            self.params[k] = v
        self.change_background_color()
        self.plot_mesh()
        self.change_color_mesh()

        self.params.param('cortical_mesh').sigValueChanged.connect(self.plot_mesh)
        self.params.param('cortical_alpha').sigValueChanged.connect(self.change_color_mesh)
        self.params.param('cortical_color').sigValueChanged.connect(self.change_color_mesh)
        self.params.param('background_color').sigValueChanged.connect(self.change_background_color)

        self.glview.resizeGL(self.glview.width(), self.glview.height())

    def open_params(self):
        self.tree.show()
    
    def change_background_color(self):
        background_color =  self.params['background_color']
        try:
            self.glview.setBackgroundColor(background_color)
        except:
            #~ #FIXME this is buggy in pyqtgrap0.9.8
            bgcolor = pg.mkColor(QtGui.QColor(background_color))
            glClearColor(bgcolor.red()/255., bgcolor.green()/255., bgcolor.blue()/255., 1.0)
            glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT )
            self.glview.paintGL()
            self.glview.update()
    
    
    def plot_mesh(self):
        vertexes, faces = cortical_meshes[self.params['cortical_mesh']]
        alpha =  self.params['cortical_alpha']
        c = self.params['cortical_color']
        color = (c.red()/255., c.green()/255.,c.blue()/255.,alpha)
        
        if self.mesh is None:
            
            self.mesh = gl.GLMeshItem(vertexes=vertexes, faces=faces, smooth=True, drawFaces=True,
                                                    drawEdges=False,
                                                    edgeColor=(1.,1.,1.,.2), 
                                                    color = color,
                                                    computeNormals = False,
                                                    glOptions='translucent',
                                                    #~ shader='balloon',
                                                    shader='shaded', 
                                                    )
            self.glview.addItem(self.mesh)
        else:
            self.mesh.setMeshData(vertexes=vertexes, faces=faces)
            #~ self.mesh.set
            
    
    def change_color_mesh(self):
        alpha =  self.params['cortical_alpha']
        c = self.params['cortical_color']
        color = (c.red()/255., c.green()/255.,c.blue()/255.,alpha)
        self.mesh.setColor(color)
    
    def add_node(self, coords, color = (1,1,1,0), size = 5):
        sp1 = gl.GLScatterPlotItem(pos=coords, size=size, color=color, pxMode=False)
        self.glview.addItem(sp1)
    
    def add_edge(self, node_coords, connection_with, color = (1,1,1,1)):
        for i in range(connection_with.shape[0]):
            for j in range(connection_with.shape[1]):
                if connection_with[i,j] == 0: continue
                plt = gl.GLLinePlotItem(pos=np.vstack([node_coords[i], node_coords[j]]), color=color, width = connection_with[i,j])
                self.glview.addItem(plt)
    
    def open_save_dialog(self):
        
        pathname =  unicode(QtGui.QDesktopServices.storageLocation(QtGui.QDesktopServices.DesktopLocation))
        filename = os.path.join(pathname, 'Il est beau le cerveau.png')
        filename = QtGui.QFileDialog.getSaveFileName( self, u'Save png',  filename, 'PNG (*.png)')
        if filename:
            self.to_file( filename)
    
    def to_file(self, filename):
        self.glview.readQImage().save(filename)
Example #11
0
    def test_pyqtgraph(self):
        cfg = collections.OrderedDict({
            "bool": True,
            "int": 5,
            "expected_float": 2,
            'str': 'strdrr',
            'vs': [1.0, 2.5, 7]
            # 'Area Sampling' : dictwidgetpyqtgraph.AreaSamplingParameter(name='Area Sampling')
        })
        captions = {"int": "toto je int"}

        opts = {}
        opts = {
            "children": {
                "vs": {
                    "title": 'voxelsize [mm]',
                    "children": {
                        "0": {
                            "title": "z",
                            'suffix': 'm',
                            'siPrefix': True
                        },
                        "1": {
                            "title": "x",
                            'suffix': 'm',
                            'siPrefix': True
                        },
                        "2": {
                            "title": "y",
                            'suffix': 'm',
                            'siPrefix': True
                        }
                    }
                },
                "expected_float": {
                    "type": "float",
                    "title": "Exp. float"
                }
            }
        }
        import teigen.dictwidgetpg
        params = teigen.dictwidgetpg.to_pyqtgraph_struct('params', cfg, opts=opts)
        params['children'].append(
            teigen.dictwidgetpg.AreaSamplingParameter(name='Area Sampling'))
        # print params

        # params[0]['title'] = "Pokusny title"
        # params[0]['my note'] = "poznamka"


        from PyQt4.QtGui import QApplication, QFileDialog
        app = QApplication(sys.argv)
        p = Parameter.create(**params)
        # p = Parameter.create(name='params', type='group', children=params)
        t = ParameterTree()
        print(p.getValues())
        lst = p.saveState()
        vals = p.getValues()

        name, dict_again = teigen.dictwidgetpg.from_pyqtgraph_struct(lst)
        t.setParameters(p, showTop=False)
        t.show()

        app.exec_()
Example #12
0
class TrackingExperimentWindow(SimpleExperimentWindow):
    """Window for controlling an experiment where the tail of an
    embedded fish is tracked.

    Parameters
    ----------

    Returns
    -------

    """
    def __init__(self, tracking=True, tail=False, eyes=False, *args, **kwargs):
        # TODO refactor movement detection
        self.tracking = tracking
        self.tail = tail
        self.eyes = eyes

        if tail or eyes:
            self.camera_display = CameraEmbeddedTrackingSelection(
                experiment=kwargs["experiment"], tail=tail, eyes=eyes)
        else:
            self.camera_display = CameraViewWidget(
                experiment=kwargs["experiment"])

        self.camera_splitter = QSplitter(Qt.Horizontal)
        self.monitoring_widget = QWidget()
        self.monitoring_layout = QVBoxLayout()
        self.monitoring_widget.setLayout(self.monitoring_layout)

        # Stream plot:
        # if eyes:
        time_past = 30
        # else:
        #     time_past = 5
        self.stream_plot = MultiStreamPlot(time_past=time_past)

        self.monitoring_layout.addWidget(self.stream_plot)

        # Tracking params button:
        self.button_tracking_params = QPushButton(
            "Tracking params" if tracking else "Movement detection params")
        self.button_tracking_params.clicked.connect(
            self.open_tracking_params_tree)
        self.monitoring_layout.addWidget(self.button_tracking_params)

        self.track_params_wnd = None

        super().__init__(*args, **kwargs)

    def construct_ui(self):
        """ """
        self.experiment.gui_timer.timeout.connect(self.stream_plot.update)
        previous_widget = super().construct_ui()
        previous_widget.layout().setContentsMargins(0, 0, 0, 0)
        self.monitoring_layout.addWidget(previous_widget)
        self.monitoring_layout.setStretch(1, 1)
        self.monitoring_layout.setStretch(0, 1)
        self.camera_splitter.addWidget(self.camera_display)
        self.camera_splitter.addWidget(self.monitoring_widget)
        return self.camera_splitter

    def open_tracking_params_tree(self):
        """ """
        self.track_params_wnd = ParameterTree()
        self.track_params_wnd.addParameters(
            self.experiment.tracking_method.params)
        self.track_params_wnd.addParameters(
            self.experiment.preprocessing_method.params)
        self.track_params_wnd.setWindowTitle("Tracking parameters")

        self.track_params_wnd.show()
Example #13
0
    def _ui_config_init(self):

        self._ui_init_buttons()
        self.ui_output_dir_widget = iowidgetqt.SetDirWidget(
            self.teigen.config["filepattern"], "output directory")
        self.ui_output_dir_widget.setToolTip(
            "Data are stored in defined directory.\nOutput format is based on file extension.\n\
For saving into image stack use 'filename{:06d}.jpg'")
        self.mainLayout.addWidget(self.ui_output_dir_widget, 1, 1, 1,
                                  2)  # , (gd_max_i / 2), text_col)

        postprocessing_params = self.teigen.config["postprocessing"]

        hide_keys = [
            "build", "gtree", "voxelsize_mm", "areasize_px", "resolution",
            "n_slice", "dims", "tube_shape", "radius_distribution_normal",
            "radius_distribution_uniform", "radius_distribution_fixed",
            "allow_overlap"
        ]
        self._ui_generators_tab_wg = QTabWidget()
        self._ui_generators_tab_wg.setMinimumWidth(400)
        self.mainLayout.addWidget(self._ui_generators_tab_wg, 0, 1, 1, 2)
        # l = QVBoxLayout(self)

        rename_captions_dict = {
            "voxelsize_mm": "voxel size [mm]",
        }
        dropdownoboxes = {
            "radius_distribution": ["normal", "fixed", "uniform"]
        }

        # list is pointer. It causes problems with temporary reconstruction information
        # copy fix this issue
        teigen_config = copy.deepcopy(self.teigen.config)

        self._ui_generator_widgets = []
        for generator_name in teigen_config["generators"]:
            wg = dictwidgetqt.DictWidget(
                teigen_config["generators"][generator_name],
                hide_keys=hide_keys,
                captions=rename_captions_dict,
                ncols=1,
                dropdownboxes=dropdownoboxes,
            )
            self._ui_generator_widgets.append(wg)
            self._ui_generators_tab_wg.addTab(
                wg, generator_name.replace(" ", "\n"))
            # self._ui_generators_tab_wg.

        # l.addWidget(self._ui_generators_tab_wg)
        # wgn = QtGui.QWidget()
        # layout = QtGui.QFormLayout()
        # layout.addRow("Name", QtGui.QLineEdit())
        # layout.addRow("Address",QtGui.QLineEdit())
        # wgn.setLayout(layout)
        # self._ui_generators_tab_wg.addTab(wgn, "ahoj")
        id = self.teigen.get_generator_id_by_name_or_number(
            teigen_config["generator_id"])
        self._ui_generators_tab_wg.setCurrentIndex(id)
        # self.mainLayout.setColumnMinimumWidth(text_col, 500)

        # pyqtgraph experiments
        input_params = {
            "Area Sampling":
            dictwidgetpg.AreaSamplingParameter(
                name='Area Sampling', **self.teigen.config["areasampling"]),
            "Postprocessing":
            postprocessing_params,
            "Batch processing":
            dictwidgetpg.BatchFileProcessingParameter(name="Batch processing",
                                                      children=[
                                                          {
                                                              'name':
                                                              'Run batch',
                                                              'type': 'action'
                                                          },
                                                      ]),
            "Appearance":
            self.teigen.config["appearance"],
            "Output":
            self.teigen.config["output"],
            "Measurement":
            self.teigen.config["measurement"]
            # 'name': {'type': 'action'},
            # "dur": i5,
            # TODO add more lines here
            # "Intensity Profile": dictwidgetpyqtgraph.ScalableFloatGroup(
            #     name="Intensity Profile", children=[
            #         {'name': '0.2', 'type': 'float', 'value': "100"},
            #         {'name': '0.4', 'type': 'float', 'value': "115"},
            #     ])
        }
        gr_struct = dictwidgetpg.to_pyqtgraph_struct('params',
                                                     input_params,
                                                     opts={})
        dictwidgetpg.add_tip(gr_struct, "noise_preview", "this is noise")
        dictwidgetpg.add_tips(gr_struct, teigen_keysdoc)
        gr_struct["children"][1]['tip'] = "Apperance tip"
        gr_struct["children"][2]['tip'] = "output tip"
        gr_struct["children"][3]['tip'] = "post processing tip"
        gr_struct["children"][4]['tip'] = "measurement"
        p = Parameter.create(**gr_struct)

        t = ParameterTree()
        t.setParameters(p, showTop=False)
        t.setMinimumWidth(380)
        # t.setColumnCount(3)
        t.show()

        p.sigTreeStateChanged.connect(self._parameters_changed)
        p.param('Batch processing',
                'Run batch').sigActivated.connect(self.run_batch)

        # how to add button
        # i5  = pg.TreeWidgetItem(["Item 5"])
        # b5 = QtGui.QPushButton('Button')
        # i5.setWidget(1, b5)
        # t.addTopLevelItem(i5)

        self.mainLayout.addWidget(t, 0, 0, 6, 1)
        self.config_wg = t
        # self.config_wg.setToolTip(teigendoc)
        self.area_sampling_params = p
        self.teigen.progress_callback = self._progressbar_update
        self._ui_btn_step2.setEnabled(False)
    @interactor.decorate()
    @printResult
    def capslocknames(a=5):
        return a


@interactor.decorate(
    runOpts=(RunOpts.ON_CHANGED, RunOpts.ON_ACTION),
    a={
        "type": "list",
        "limits": [5, 10, 20]
    },
)
@printResult
def runOnBtnOrChange_listOpts(a=5):
    return a


@interactor.decorate(nest=False)
@printResult
def onlyTheArgumentsAppear(thisIsAFunctionArg=True):
    return thisIsAFunctionArg


tree = ParameterTree()
tree.setParameters(host)

tree.show()
if __name__ == "__main__":
    pg.exec()
Example #15
0
    def start_gui(self, skip_exec=False, qapp=None):

        from PyQt5 import QtWidgets
        # import scaffan.qtexceptionhook

        # import QApplication, QFileDialog
        if not skip_exec and qapp == None:
            qapp = QtWidgets.QApplication(sys.argv)

        self.parameters.param("Input", "Select").sigActivated.connect(
            self.select_file_gui)
        # self.parameters.param("Output", "Select").sigActivated.connect(
        #     self.select_output_dir_gui
        # )
        self.parameters.param(
            "Output", "Select Common Spreadsheet File").sigActivated.connect(
                self.select_output_spreadsheet_gui)
        self.parameters.param("Run").sigActivated.connect(self.run)
        self.parameters.param("Input", "X-Axis").sigValueChanged.connect(
            self._on_param_change)
        self.parameters.param("Input", "Y-Axis").sigValueChanged.connect(
            self._on_param_change)
        self.parameters.param("Input", "Time Axis").sigValueChanged.connect(
            self._on_param_change)
        self.parameters.param("Input", "C-Axis").sigValueChanged.connect(
            self._on_param_change)
        self.parameters.param("Input",
                              "Tracked Channel").sigValueChanged.connect(
                                  self._on_param_change)
        self.parameters.param("Input", "Preview Time").sigValueChanged.connect(
            self._on_param_change)

        # self.parameters.param("Processing", "Open output dir").setValue(True)
        t = ParameterTree()
        t.setParameters(self.parameters, showTop=False)
        t.setWindowTitle("pyqtgraph example: Parameter Tree")
        t.show()

        # print("run scaffan")
        win = QtGui.QWidget()
        win.setWindowTitle("CellTrack {}".format(celltrack.__version__))
        logo_fn = op.join(op.dirname(__file__), "celltrack_icon512.png")
        logo_fav_fn = op.join(op.dirname(__file__), "logo_fav.png")
        logo_prifuk = op.join(op.dirname(__file__), "logo_prifuk.png")
        app_icon = QtGui.QIcon()
        # app_icon.addFile(logo_fn, QtCore.QSize(16, 16))
        app_icon.addFile(logo_fn)
        win.setWindowIcon(app_icon)
        # qapp.setWindowIcon(app_icon)

        layout = QtGui.QGridLayout()
        layout.setColumnStretch(0, 2)
        layout.setColumnStretch(1, 3)
        win.setLayout(layout)

        # layout.setColumnStretch(2, 3)
        logolink = QGroupBox("Created by")
        logolink_layout = QtGui.QGridLayout()
        logolink.setLayout(logolink_layout)

        pic = QtGui.QLabel()
        urlLink = "<a href=\"http://www.google.com\">'Click this link to go to Google'</a>"
        pic.setText(urlLink)
        pic.setPixmap(QtGui.QPixmap(logo_fav_fn).scaled(50, 50))
        pic.setOpenExternalLinks(True)
        pic.show()

        urlLink = "<a href=\"http://www.google.com\">'Click this link to go to Google'</a>"
        pic2 = QtGui.QLabel()
        pic2.setText(urlLink)
        pic2.setPixmap(QtGui.QPixmap(logo_prifuk).scaled(50, 50))
        pic2.setOpenExternalLinks(True)
        pic2.show()

        # self.image1 = PlotCanvas()
        # self.image1.axes.set_axis_off()
        # self.image1.imshow(plt.imread(logo_fn))

        # self.image1.plot()
        self.image2 = PlotCanvas()
        self.image2.axes.text(0.1, 0.6, "Load Tiff file")
        self.image2.axes.text(0.1, 0.5, "Check pixelsize")
        self.image2.axes.text(0.1, 0.4, "Run")
        # self.image2.axes.text(0.1, 0.3, "Use Comparative Annotation (optimal in further iterations)")
        self.image2.axes.set_axis_off()
        self.image2.draw()
        # self.image2.plot()

        # self.addToolBar(NavigationToolbar(self.image1, self))
        # self.image1.setPixmap(QtGui.QPixmap(logo_fn).scaled(100, 100))
        # self.image1.show()
        # self.image2 = QtGui.QLabel()
        # self.image2.setPixmap(QtGui.QPixmap(logo_fn).scaled(100, 100))
        # self.image2.show()
        # layout.addWidget(QtGui.QLabel("These are two views of the same data. They should always display the same values."), 0,  0, 1, 2)
        logolink_layout.addWidget(pic, 1, 0, 1, 1)
        logolink_layout.addWidget(pic2, 1, 1, 1, 1)

        layout.addWidget(logolink, 1, 0, 1, 1)
        layout.addWidget(t, 2, 0, 1, 1)
        # layout.addWidget(NavigationToolbar(self.image2, win),1, 2, 1, 1)
        layout.addWidget(NavigationToolbar(self.image2, win), 1, 1, 1, 1)
        layout.addWidget(self.image2, 2, 1, 1, 1)
        # layout.addWidget(self.image2, 2, 2, 1, 1)
        # layout.addWidget(t2, 1, 1, 1, 1)

        win.show()
        win.resize(1200, 800)
        self.win = win
        # win.
        self.qapp = qapp
        if not skip_exec:

            qapp.exec_()
Example #16
0
    global state
    state = p.saveState()
    
def restore():
    global state
    add = p['Save/Restore functionality', 'Restore State', 'Add missing items']
    rem = p['Save/Restore functionality', 'Restore State', 'Remove extra items']
    p.restoreState(state, addChildren=add, removeChildren=rem)
p.param('Save/Restore functionality', 'Save State').sigActivated.connect(save)
p.param('Save/Restore functionality', 'Restore State').sigActivated.connect(restore)


## Create two ParameterTree widgets, both accessing the same data
t = ParameterTree()
t.setParameters(p, showTop=False)
t.show()
t.resize(400,800)
t2 = ParameterTree()
t2.setParameters(p, showTop=False)
t2.show()
t2.resize(400,800)
    
## test save/restore
s = p.saveState()
p.restoreState(s)


## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
Example #17
0
          plotList[0].setTitle(msg)
        if childName=='secondCh':
          print "data: ", data
          chB = p.param('secondCh').value()
          msg = "Ch%dCh%d" % (chA, chB)
          plotList[0].setTitle(msg)
                    

p.param('Reset Histogram').sigActivated.connect(resetHist)
p.param('Save Histogram').sigActivated.connect(saveHist)
p.param('Save Figure').sigActivated.connect(saveFig)

p.sigTreeStateChanged.connect(change)
t = ParameterTree()
t.setParameters(p, showTop = False)
t.show()  


chA = p.param('firstCh').value()
chB = p.param('secondCh').value()
if True:
  win = pg.GraphicsWindow()
  win.resize(1600,600)
  win.setWindowTitle('Real Time Histogram')
  plotList = []
  for i in range(p.param('numPlots').value()):
    if i == 3:
      plt = win.addPlot(labels = {'left': 'log10(Counts)', 'bottom': 'time'}, title = "Ch%dCh%d" %(chA,chB))
      plotList.append(plt)
      win.nextRow()
    else:
Example #18
0
class ProtocolControlWidget(QWidget):
    """GUI for controlling a ProtocolRunner.

    This class implements:

        - selection box of the Protocol to be run;
        - window for controlling Protocol parameters;
        - toggle button for starting/stopping the Protocol;
        - progress bar to display progression of the Protocol.

     Parameters
    ----------
    protocol_runner: :class:`ProtocolRunner <stytra.stimulation.ProtocolRunner>` object
        ProtocolRunner that is controlled by the GUI.

    **Signals**
    """
    sig_start_protocol = pyqtSignal()
    """ Emitted via the toggle button click, meant to
                         start the protocol """
    sig_stop_protocol = pyqtSignal()
    """ Emitted via the toggle button click, meant to
                         abort the protocol"""
    def __init__(self, protocol_runner=None, *args):
        """ """
        super().__init__(*args)
        self.protocol_runner = protocol_runner

        # Create parametertree for protocol parameter control
        self.protocol_params_tree = ParameterTree(showHeader=False)

        # Layout for selecting the protocol:
        self.lyt_prot_selection = QHBoxLayout()

        # Dropdown menu with the protocol classes found in the Experiment:
        self.combo_prot = QComboBox()
        self.combo_prot.addItems(
            list(self.protocol_runner.prot_class_dict.keys()))

        self.combo_prot.currentIndexChanged.connect(self.set_protocol)
        self.lyt_prot_selection.addWidget(self.combo_prot)

        # Window with the protocol parameters:
        self.protocol_params_butt = QPushButton("Protocol parameters")
        self.protocol_params_butt.clicked.connect(self.show_stim_params_gui)
        self.lyt_prot_selection.addWidget(self.protocol_params_butt)

        # Layout for protocol start and progression report:
        self.lyt_run = QHBoxLayout()

        # Button for startup:
        self.button_toggle_prot = QPushButton("▶")

        self.button_toggle_prot.clicked.connect(self.toggle_protocol_running)
        self.lyt_run.addWidget(self.button_toggle_prot)

        # Progress bar for monitoring the protocol:
        self.progress_bar = QProgressBar()
        self.progress_bar.setFormat("%p% %v/%m")

        self.lyt_run.addWidget(self.progress_bar)

        # Global layout:
        self.lyt = QVBoxLayout()
        self.lyt.setContentsMargins(0, 0, 0, 0)
        self.lyt.addLayout(self.lyt_run)
        self.lyt.addLayout(self.lyt_prot_selection)
        self.setLayout(self.lyt)

        self.timer = None

        # Connect events and signals from the ProtocolRunner to update the GUI:
        self.protocol_runner.sig_protocol_updated.connect(
            self.update_stim_duration)
        self.protocol_runner.sig_timestep.connect(self.update_progress)

        self.protocol_runner.sig_protocol_started.connect(self.toggle_icon)
        self.protocol_runner.sig_protocol_finished.connect(self.toggle_icon)

        self.protocol_runner.sig_protocol_updated.connect(
            self.update_stim_duration)

        # If a previous protocol was already set in the protocol runner
        # change the GUI values accordingly:
        if protocol_runner.protocol is not None:
            self.combo_prot.setCurrentText(protocol_runner.protocol.name)
        else:
            self.set_protocol()

    def show_stim_params_gui(self):
        """Create and show window to update protocol parameters.
        """
        if self.protocol_runner.protocol.params is not None:
            self.protocol_params_tree.setParameters(
                self.protocol_runner.protocol.params)
            self.protocol_params_tree.show()
            self.protocol_params_tree.setWindowTitle("Protocol parameters")
            self.protocol_params_tree.resize(300, 600)

    def toggle_protocol_running(self):
        """Emit the start and stop signals. These can be used in the Experiment
        class or directly connected with the respective ProtocolRunner
        start() and stop() methods.

        Parameters
        ----------

        Returns
        -------

        """
        # Start/stop the protocol:
        if not self.protocol_runner.running:
            self.sig_start_protocol.emit()
        else:
            self.sig_stop_protocol.emit()
            self.toggle_icon()

    def toggle_icon(self):
        """Change the play/stop icon of the GUI.
        """
        if self.button_toggle_prot.text() == "■":
            self.button_toggle_prot.setText("▶")
            self.progress_bar.setValue(0)
        else:
            self.button_toggle_prot.setText("■")

    def update_stim_duration(self):
        """ """
        self.progress_bar.setMaximum(int(self.protocol_runner.duration))
        self.progress_bar.setValue(0)

    def update_progress(self):
        """ """
        self.progress_bar.setValue(int(self.protocol_runner.t))

    def set_protocol(self):
        """Use value in the dropdown menu to change the protocol.
        """
        protocol_name = self.combo_prot.currentText()
        self.protocol_runner.set_new_protocol(protocol_name)
        self.button_toggle_prot.setEnabled(True)
Example #19
0
class CameraViewWidget(QWidget):
    """A widget to show images from a frame source and display the camera controls.
    
    ***It does not implement a frame dispatcher by itself so it may lag behind
    the camera at high frame rates!***

    Parameters
    ----------

    Returns
    -------

    """

    def __init__(self, experiment=None, camera=None):
        """
        :param experiment: experiment to which this belongs
                           (:class:Experiment <stytra.Experiment> object)
        """

        super().__init__()

        self.experiment = experiment
        if experiment is not None:
            self.camera = experiment.camera
            experiment.gui_timer.timeout.connect(self.update_image)
        else:
            self.camera = camera
            self.gui_timer = QTimer()
            self.gui_timer.setSingleShot(False)

        self.control_params = CameraControlParameters()

        # Create the layout for the camera view:
        self.camera_display_widget = pg.GraphicsLayoutWidget()

        # Display area for showing the camera image:
        self.display_area = pg.ViewBox(lockAspect=1, invertY=False)
        self.display_area.setRange(
            QRectF(0, 0, 640, 640), update=True, disableAutoRange=True
        )
        # Image to which the frame will be set, initially black:
        self.image_item = pg.ImageItem()
        self.image_item.setImage(np.zeros((640, 480), dtype=np.uint8))
        self.display_area.addItem(self.image_item)

        self.camera_display_widget.addItem(self.display_area)

        # Queue of frames coming from the camera
        if hasattr(experiment, "frame_dispatcher"):
            self.frame_queue = self.experiment.frame_dispatcher.gui_queue
        else:
            self.frame_queue = self.camera.frame_queue

        # Queue of control parameters for the camera:
        self.control_queue = self.camera.control_queue
        self.camera_rotation = self.camera.rotation

        self.camera_params_tree = ParameterTree(showHeader=False)

        # Connect changes in the camera parameters:
        for c in self.control_params.params.children():
            c.sigValueChanged.connect(self.update_controls)

        self.layout = QVBoxLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)

        self.layout.addWidget(self.camera_display_widget)

        self.layout_control = QHBoxLayout()
        if self.control_queue is not None:
            self.params_button = QPushButton("Camera params")
            self.params_button.clicked.connect(self.show_params_gui)
            self.layout_control.addWidget(self.params_button)

        self.captureButton = QPushButton("Capture frame")
        self.captureButton.clicked.connect(self.save_image)
        self.layout_control.addWidget(self.captureButton)

        self.layout.addLayout(self.layout_control)
        self.current_image = None

        self.setLayout(self.layout)

    def update_controls(self, value):
        """

        Parameters
        ----------
        value :
            Parameter object that have changed

        Returns
        -------

        """
        # Put in the queue tuple with name and new value of the parameter:
        self.control_queue.put((value.name(), value.value()))

    def update_image(self):
        """Update displayed frame while emptying frame source queue. This is done
        through a while loop that takes all available frames at every update.
        
        # TODO fix this somehow?
        
        **Important!** if the input queue is too fast this will produce an
        infinite loop and block the interface!

        Parameters
        ----------

        Returns
        -------

        """

        first = True
        while True:
            try:
                # In this way, the frame displayed is actually the most
                # recent one added to the queue, as a queue is FILO:
                if first:
                    time, self.current_image = self.frame_queue.get(timeout=0.0001)
                    first = False
                else:
                    # Else, get to free the queue:
                    _, _ = self.frame_queue.get(timeout=0.001)

            except Empty:
                break

        # Once obtained current image, display it:
        if self.current_image is not None:
            self.image_item.setImage(self.current_image)

    def save_image(self):
        """Save a frame to the current directory."""
        timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        imsave(
            self.experiment.filename_base() + timestamp + "_img.png",
            self.image_item.image,
        )

    def show_params_gui(self):
        """ """
        self.camera_params_tree.setParameters(self.control_params.params)
        self.camera_params_tree.show()
        self.camera_params_tree.setWindowTitle("Camera parameters")
        self.camera_params_tree.resize(450, 600)