コード例 #1
0
ファイル: window.py プロジェクト: prodigeni/moneyguru
 def show(self):
     # For non-modal dialogs, show() is not enough to bring the window at the forefront, we have
     # to call raise() as well
     QWidget.showNormal(self)
     QWidget.raise_(self)
     QWidget.activateWindow(self)
コード例 #2
0
ファイル: gentle.py プロジェクト: soumith/gentle
w.setLayout(layout)

txt = QLabel('''Gentle v%s

A robust yet lenient forced-aligner built on Kaldi.''' % (__version__))
layout.addWidget(txt)

btn = QPushButton('Open in browser')
btn.setStyleSheet("font-weight: bold;")
layout.addWidget(btn)
btn.clicked.connect(open_browser)

abt = QPushButton('About Gentle')
layout.addWidget(abt)
abt.clicked.connect(open_about)

quitb = QPushButton('Quit')
layout.addWidget(quitb)
quitb.clicked.connect(quit_server)

w.show()

w.raise_()
w.activateWindow()
 
app.exec_()

logging.info("Waiting for server to quit.")
reactor.callFromThread(reactor.stop)
webthread.join()
コード例 #3
0
class RemoconMain(QMainWindow):
    def __init__(self, parent, title, application):
        self._context = parent

        super(RemoconMain, self).__init__()
        self.initialised = False
        self.setObjectName('Remocon')

        self.host_name = "localhost"
        self.master_uri = "http://%s:11311" % (self.host_name)

        self.env_host_name = os.getenv("ROS_HOSTNAME")
        self.env_master_uri = os.getenv("ROS_MASTER_URI")
        if self.env_host_name == None:
            self.env_host_name = 'localhost'
        if self.env_master_uri == None:
            self.env_master_uri = "http://%s:11311" % (self.env_host_name)

        self.application = application
        self._widget_main = QWidget()

        self.rocon_master_list = {}
        self.cur_selected_rocon_master = None
        self.is_init = False

        path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../ui/remocon.ui")
        uic.loadUi(path, self._widget_main)

        utils.setup_home_dirs()
        self.rocon_master_list_cache_path = os.path.join(utils.get_settings_cache_home(), "rocon_master.cache")

        self.icon_paths = {}
        try:
            self.icon_paths['unknown'] = rocon_python_utils.ros.find_resource_from_string('rocon_icons/unknown', extension='png')
        except (rospkg.ResourceNotFound, ValueError):
            console.logerror("Remocon : couldn't find icons on the ros package path (install rocon_icons and rocon_bubble_icons")
            sys.exit(1)
        self.scripts_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../scripts/")

        #main widget
        self._widget_main.list_widget.setIconSize(QSize(50, 50))
        self._widget_main.list_widget.itemDoubleClicked.connect(self._connect_rocon_master)  # list item double click event
        self._widget_main.list_widget.itemClicked.connect(self._select_rocon_master)  # list item double click event

        self._widget_main.add_concert_btn.pressed.connect(self._set_add_rocon_master)  # add button event
        self._widget_main.delete_btn.pressed.connect(self._delete_rocon_master)  # delete button event
        self._widget_main.delete_all_btn.pressed.connect(self._delete_all_rocon_masters)  # delete all button event
        self._widget_main.refresh_btn.pressed.connect(self._refresh_rocon_master_list)  # refresh all button event

        #init
        self._init()
        self._widget_main.show()
        self._widget_main.activateWindow()  # give it the focus
        self._widget_main.raise_()          # make sure it is on top

    def __del__(self):
        print '[RemoconMain]: Destroy'

    def _init(self):

        self._connect_dlg_isValid = False
        self.cur_selected_rocon_master = None
        self._refresh_rocon_master_list()
        self.is_init = True
        pass

    def _check_up(self):
        for k in self.rocon_master_list.values():
            print("Concert: %s" % k)
            rocon_master_uri = k['master_uri']
            host_name = k['host_name']
            print "[_check_up]:MASTER_URI[%s], HOST_NAME[%s]" % (rocon_master_uri, host_name)

            output = subprocess.Popen([self.scripts_path + "rocon_remocon_check_up", rocon_master_uri, host_name], stdout=subprocess.PIPE)
            time_out_cnt = 0
            while True:
                print "checking: " + rocon_master_uri
                result = output.poll()
                if time_out_cnt > 30:
                    print "timeout: " + rocon_master_uri
                    try:
                        output.terminate()
                    except:
                        print "Error: output.terminate()"

                    k['name'] = "Unknown"
                    k['description'] = "Unknown."
                    k['icon'] = "unknown.png"
                    k['flag'] = '0'
                    break

                elif result == 0:
                    args = output.communicate()[0]
                    k['name'] = args.split('\n')[0]
                    k['description'] = args.split('\n')[1]
                    k['icon'] = args.split('\n')[2]

                    if k['name'] == "Unknown":
                        k['flag'] = '0'
                    else:
                        k['flag'] = '1'
                    break

                time.sleep(0.1)
                time_out_cnt += 1

    def _read_cache(self):
        #read cache and display the rocon master list
        try:
            cache_rocon_master_info_list = open(self.rocon_master_list_cache_path, 'r')
        except:
            console.logdebug("Remocon : no cached settings found, moving on.")
            return
        lines = cache_rocon_master_info_list.readlines()
        for line in lines:
            if line.count("[index="):
                rocon_master_index = line[string.find(line, "[index=") + len("[index="):string.find(line, ",name=")]
                rocon_master_name = line[string.find(line, "name=") + len("name="):string.find(line, ",master_uri=")]
                rocon_master_uri = line[string.find(line, ",master_uri=") + len(",master_uri="):string.find(line, ",host_name=")]
                rocon_master_host_name = line[string.find(line, ",host_name=") + len(",host_name="):string.find(line, ",description=")]
                rocon_master_description = line[string.find(line, ",description=") + len(",description="):string.find(line, ",icon=")]
                rocon_master_icon = line[string.find(line, ",icon=") + len(",icon="):string.find(line, ",flag=")]
                rocon_master_flag = line[string.find(line, ",flag=") + len(",flag="):string.find(line, "]")]

                self.rocon_master_list[rocon_master_index] = {}
                self.rocon_master_list[rocon_master_index]['index'] = rocon_master_index
                self.rocon_master_list[rocon_master_index]['name'] = rocon_master_name
                self.rocon_master_list[rocon_master_index]['master_uri'] = rocon_master_uri
                self.rocon_master_list[rocon_master_index]['host_name'] = rocon_master_host_name
                self.rocon_master_list[rocon_master_index]['icon'] = rocon_master_icon
                self.rocon_master_list[rocon_master_index]['description'] = rocon_master_description
                self.rocon_master_list[rocon_master_index]['flag'] = rocon_master_flag
        cache_rocon_master_info_list.close()

    def _delete_all_rocon_masters(self):
        for k in self.rocon_master_list.values():
            del self.rocon_master_list[k["index"]]
        self._update_rocon_master_list()

    def _delete_rocon_master(self):
        if self.cur_selected_rocon_master in self.rocon_master_list.keys():
            del self.rocon_master_list[self.cur_selected_rocon_master]
        self._update_rocon_master_list()

    def _add_rocon_master(self, params):
        rocon_master_uri = str(params['param1'].toPlainText())
        rocon_master_host_name = str(params['param2'].toPlainText())
        rocon_master_index = str(uuid.uuid4())
        self.rocon_master_list[rocon_master_index] = {}
        self.rocon_master_list[rocon_master_index]['index'] = rocon_master_index
        self.rocon_master_list[rocon_master_index]['name'] = "Unknown"
        self.rocon_master_list[rocon_master_index]['master_uri'] = rocon_master_uri
        self.rocon_master_list[rocon_master_index]['host_name'] = rocon_master_host_name
        self.rocon_master_list[rocon_master_index]['icon'] = "unknown.png"
        self.rocon_master_list[rocon_master_index]['description'] = ""
        self.rocon_master_list[rocon_master_index]['flag'] = "0"

        self._update_rocon_master_list()
        self._refresh_rocon_master_list()

    def _set_add_rocon_master(self):
        print '_add_rocon_master'
        if self._connect_dlg_isValid:
            print "Dialog is live!!"
            self._connect_dlg.done(0)

        #dialog
        self._connect_dlg = QDialog(self._widget_main)
        self._connect_dlg.setWindowTitle("Add Ros Master")
        self._connect_dlg.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
        self._connect_dlg.setMinimumSize(350, 0)
        # dlg_rect = self._connect_dlg.geometry()

        #dialog layout
        ver_layout = QVBoxLayout(self._connect_dlg)
        ver_layout.setContentsMargins(9, 9, 9, 9)

        #param layout
        text_grid_sub_widget = QWidget()
        text_grid_layout = QGridLayout(text_grid_sub_widget)
        text_grid_layout.setColumnStretch(1, 0)
        text_grid_layout.setRowStretch(2, 0)

        #param 1
        title_widget1 = QLabel("MASTER_URI: ")
        context_widget1 = QTextEdit()
        context_widget1.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
        context_widget1.setMinimumSize(0, 30)
        context_widget1.append(self.master_uri)

        #param 2
        title_widget2 = QLabel("HOST_NAME: ")
        context_widget2 = QTextEdit()
        context_widget2.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
        context_widget2.setMinimumSize(0, 30)
        context_widget2.append(self.host_name)

        #add param
        text_grid_layout.addWidget(title_widget1)
        text_grid_layout.addWidget(context_widget1)
        text_grid_layout.addWidget(title_widget2)
        text_grid_layout.addWidget(context_widget2)

        #add param layout
        ver_layout.addWidget(text_grid_sub_widget)

        #button layout
        button_hor_sub_widget = QWidget()
        button_hor_layout = QHBoxLayout(button_hor_sub_widget)

        params = {}
        params['param1'] = context_widget1
        params['param2'] = context_widget2

        #check box
        use_env_var_check = QCheckBox("Use environment variables")
        use_env_var_check.setCheckState(Qt.Unchecked)

        def set_use_env_var(data, text_widget1, text_widget2):
            if data == Qt.Unchecked:
                text_widget1.setText(self.master_uri)
                text_widget2.setText(self.host_name)
            elif data == Qt.Checked:
                self.master_uri = str(text_widget1.toPlainText())
                self.host_name = str(text_widget2.toPlainText())
                text_widget1.setText(self.env_master_uri)
                text_widget2.setText(self.env_host_name)

        def check_event(data):
            set_use_env_var(data, context_widget1, context_widget2)

        use_env_var_check.stateChanged.connect(check_event)
        ver_layout.addWidget(use_env_var_check)

        #button
        btn_call = QPushButton("Add")
        btn_cancel = QPushButton("Cancel")

        btn_call.clicked.connect(lambda: self._connect_dlg.done(0))
        btn_call.clicked.connect(lambda: self._add_rocon_master(params))

        btn_cancel.clicked.connect(lambda: self._connect_dlg.done(0))

        #add button
        button_hor_layout.addWidget(btn_call)
        button_hor_layout.addWidget(btn_cancel)

        #add button layout
        ver_layout.addWidget(button_hor_sub_widget)
        self._connect_dlg.setVisible(True)
        self._connect_dlg.finished.connect(self._destroy_connect_dlg)
        self._connect_dlg_isValid = True

    def _refresh_rocon_master_list(self):
        print '_refresh_rocon_master_list'
        if self.is_init:
            self._update_rocon_master_list()
        self._read_cache()
        self._widget_main.list_info_widget.clear()
        self._check_up()
        self._update_rocon_master_list()

    def _update_rocon_master_list(self):

        print '_update_rocon_master_list'
        self._widget_main.list_widget.clear()
        try:
            cache_rocon_master_info_list = open(self.rocon_master_list_cache_path, 'w')
        except:
            print "No directory or file: %s" % (self.rocon_master_list_cache_path)
            return
        for k in self.rocon_master_list.values():
            self._add_rocon_master_list_item(k)
            rocon_master_index = k['index']
            rocon_master_name = k['name']
            rocon_master_uri = k['master_uri']
            rocon_master_host_name = k['host_name']
            rocon_master_icon = k['icon']
            rocon_master_description = k['description']
            rocon_master_flag = k['flag']

            rocon_master_elem = '['
            rocon_master_elem += 'index=' + str(rocon_master_index) + ','
            rocon_master_elem += 'name=' + str(rocon_master_name) + ','
            rocon_master_elem += 'master_uri=' + str(rocon_master_uri) + ','
            rocon_master_elem += 'host_name=' + str(rocon_master_host_name) + ','
            rocon_master_elem += 'description=' + str(rocon_master_description) + ','
            rocon_master_elem += 'icon=' + rocon_master_icon + ','
            rocon_master_elem += 'flag=' + rocon_master_flag
            rocon_master_elem += ']\n'

            cache_rocon_master_info_list.write(rocon_master_elem)
        cache_rocon_master_info_list.close()

    def _add_rocon_master_list_item(self, rocon_master):
        print('_add_rocon_master_list_item [%s]' % rocon_master['name'])
        rocon_master_index = rocon_master['index']
        rocon_master_name = rocon_master['name']
        rocon_master_uri = rocon_master['master_uri']
        rocon_master_host_name = rocon_master['host_name']
        rocon_master_icon = rocon_master['icon']
        rocon_master_description = rocon_master['description']
        rocon_master['cur_row'] = str(self._widget_main.list_widget.count())

        display_name = str(rocon_master_name) + "\n" + "[" + str(rocon_master_uri) + "]"
        self._widget_main.list_widget.insertItem(self._widget_main.list_widget.count(), display_name)

        #setting the list font

        font = self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).font()
        font.setPointSize(13)
        self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setFont(font)

        #setToolTip
        rocon_master_info = ""
        rocon_master_info += "rocon_master_index: " + str(rocon_master_index) + "\n"
        rocon_master_info += "rocon_master_name: " + str(rocon_master_name) + "\n"
        rocon_master_info += "master_uri:  " + str(rocon_master_uri) + "\n"
        rocon_master_info += "host_name:  " + str(rocon_master_host_name) + "\n"
        rocon_master_info += "description:  " + str(rocon_master_description)
        self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setToolTip(rocon_master_info)

        #set icon
        if rocon_master_icon == "unknown.png":
            icon = QIcon(self.icon_paths['unknown'])
            self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setIcon(icon)
        elif len(rocon_master_icon):
            icon = QIcon(os.path.join(utils.get_icon_cache_home(), rocon_master_icon))
            self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setIcon(icon)
        else:
            print rocon_master_name + ': No icon'
        pass

    def _select_rocon_master(self, Item):
        list_widget = Item.listWidget()
        for k in self.rocon_master_list.values():
            if k["cur_row"] == str(list_widget.currentRow()):
                self.cur_selected_rocon_master = k['index']
                break
        self._widget_main.list_info_widget.clear()
        info_text = "<html>"
        info_text += "<p>-------------------------------------------</p>"
        info_text += "<p><b>name: </b>" + str(self.rocon_master_list[self.cur_selected_rocon_master]['name']) + "</p>"
        info_text += "<p><b>master_uri: </b>" + str(self.rocon_master_list[self.cur_selected_rocon_master]['master_uri']) + "</p>"
        info_text += "<p><b>host_name: </b>" + str(self.rocon_master_list[self.cur_selected_rocon_master]['host_name']) + "</p>"
        info_text += "<p><b>description: </b>" + str(self.rocon_master_list[self.cur_selected_rocon_master]['description']) + "</p>"
        info_text += "<p>-------------------------------------------</p>"
        info_text += "</html>"
        self._widget_main.list_info_widget.appendHtml(info_text)

    def _destroy_connect_dlg(self):
        print "[Dialog] Destroy!!!"
        self._connect_dlg_isValid = False

    def _connect_rocon_master(self):
        rocon_master_name = str(self.rocon_master_list[self.cur_selected_rocon_master]['name'])
        rocon_master_uri = str(self.rocon_master_list[self.cur_selected_rocon_master]['master_uri'])
        rocon_master_host_name = str(self.rocon_master_list[self.cur_selected_rocon_master]['host_name'])

        rocon_master_index = str(self.cur_selected_rocon_master)

        if self.rocon_master_list[rocon_master_index]['flag'] == '0':
            # DJS: unused reply box?
            # reply = QMessageBox.warning(self, 'ERROR', "YOU SELECT NO CONCERT", QMessageBox.Ok|QMessageBox.Ok)
            return

        execute_path = self.scripts_path + 'rocon_remocon_sub'  # command
        execute_path += " " + "'" + rocon_master_index + "'"  # arg1
        execute_path += " " + "'" + rocon_master_name + "'"  # arg2
        execute_path += " " + "'" + rocon_master_uri + "'"  # arg3
        execute_path += " " + "'" + rocon_master_host_name + "'"  # arg4

        self._widget_main.hide()
        os.execv(self.scripts_path + 'rocon_remocon_sub', ["", rocon_master_index, rocon_master_name, rocon_master_uri, rocon_master_host_name])
        print "Spawning: %s" % (execute_path)
コード例 #4
0
class RingWindow(QMainWindow):
    image: RingImageQLabel
    statusbar: QtGui.QStatusBar

    def __init__(self):
        super(RingWindow, self).__init__()
        path = os.path.join(sys.path[0], __package__)

        uic.loadUi(os.path.join(path, 'gui_ring.ui'), self)
        self.move(50, 0)

        self.ctrl = QWidget()
        uic.loadUi(os.path.join(path, 'gui_ring_controls.ui'), self.ctrl)
        self.ctrl.show()

        self.ctrl.zSpin.valueChanged.connect(self.onZValueChange)
        self.ctrl.openButton.pressed.connect(self.onOpenButton)
        self.ctrl.addButton.pressed.connect(self.onAddButton)
        self.ctrl.plotButton.pressed.connect(self.onPlotButton)
        self.ctrl.measureButton.pressed.connect(self.onMeasureButton)
        self.ctrl.dnaSpin.valueChanged.connect(self.onDnaValChange)
        self.ctrl.actSpin.valueChanged.connect(self.onActValChange)
        self.ctrl.dnaChk.toggled.connect(self.onImgToggle)
        self.ctrl.actChk.toggled.connect(self.onImgToggle)
        self.ctrl.renderChk.stateChanged.connect(self.onRenderChk)

        self.image.clicked.connect(self.onImgUpdate)
        self.image.lineUpdated.connect(self.onImgUpdate)
        self.image.linePicked.connect(self.onLinePickedFromImage)
        self.image.dnaChannel = self.ctrl.dnaSpin.value()
        self.image.actChannel = self.ctrl.actSpin.value()

        self.grph = GraphWidget()
        self.grph.show()

        self.grph.linePicked.connect(self.onLinePickedFromGraph)

        self.ctrl.setWindowFlags(self.ctrl.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint)
        self.grph.setWindowFlags(self.grph.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint)

        self.image.dnaChannel = self.ctrl.dnaSpin.value()
        self.image.actChannel = self.ctrl.actSpin.value()

        self.measure_n = 0
        self.selectedLine = None

        self.df = pd.DataFrame()
        self.file = "/Users/Fabio/data/lab/airyscan/nil.czi"

        self.resizeEvent(None)
        self.moveEvent(None)

    def resizeEvent(self, event):
        # this is a hack to resize everithing when the user resizes the main window
        self.grph.setFixedWidth(self.width())
        self.image.setFixedWidth(self.width())
        self.image.setFixedHeight(self.height())
        self.image.resizeEvent(None)
        self.moveEvent(None)

    def moveEvent(self, QMoveEvent):
        px = self.geometry().x()
        py = self.geometry().y()
        pw = self.geometry().width()
        ph = self.geometry().height()

        dw = self.ctrl.width()
        dh = self.ctrl.height()
        self.ctrl.setGeometry(px + pw, py, dw, dh)

        dw = self.grph.width()
        dh = self.grph.height()
        self.grph.setGeometry(px, py + ph + 20, dw, dh)
        # super(RingWindow, self).mouseMoveEvent(event)

    def closeEvent(self, event):
        if not self.df.empty:
            self.df.loc[:, "condition"] = self.ctrl.experimentLineEdit.text()
            self.df.loc[:, "l"] = self.df.loc[:, "l"].apply(lambda v: np.array2string(v, separator=','))
            self.df.to_csv(os.path.join(os.path.dirname(self.image.file), "ringlines.csv"))
        self.grph.close()
        self.ctrl.close()

    def focusInEvent(self, QFocusEvent):
        logger.debug('focusInEvent')
        self.ctrl.activateWindow()
        self.grph.activateWindow()

    def showEvent(self, event):
        self.setFocus()

    def _graphTendency(self):
        df = pd.DataFrame(self.image.measurements).drop(['x', 'y', 'c', 'ls0', 'ls1', 'd', 'sum'], axis=1)
        df.loc[:, "xx"] = df.loc[:, "l"].apply(
            lambda v: np.arange(start=0, stop=len(v) * self.image.dl, step=self.image.dl))
        df = m.vector_column_to_long_fmt(df, val_col="l", ix_col="xx")
        sns.lineplot(x="xx", y="l", data=df, ax=self.grph.ax, color='k', ci="sd", zorder=20)
        self.grph.ax.set_ylabel('')
        self.grph.ax.set_xlabel('')
        self.grph.canvas.draw()

    def _graph(self, alpha=1.0):
        self.grph.clear()
        if self.image.measurements is not None:
            for me in self.image.measurements:
                x = np.arange(start=0, stop=len(me['l']) * self.image.dl, step=self.image.dl)
                lw = 0.1 if self.image.selectedLine is not None and me != self.image.selectedLine else 0.5
                self.grph.ax.plot(x, me['l'], linewidth=lw, linestyle='-', color=me['c'], alpha=alpha, zorder=10,
                                  picker=5, label=me['n'])
            self.grph.format_ax()
            self.statusbar.showMessage("ptp: %s" % ["%d " % me['d'] for me in self.image.measurements])
            self.grph.canvas.draw()

    @QtCore.pyqtSlot()
    def onImgToggle(self):
        logger.debug('onImgToggle')
        if self.ctrl.dnaChk.isChecked():
            self.image.activeCh = "dna"
        if self.ctrl.actChk.isChecked():
            self.image.activeCh = "act"

    @QtCore.pyqtSlot()
    def onRenderChk(self):
        logger.debug('onRenderChk')
        self.image.render = self.ctrl.renderChk.isChecked()

    @QtCore.pyqtSlot()
    def onOpenButton(self):
        logger.debug('onOpenButton')
        qfd = QtGui.QFileDialog()
        path = os.path.dirname(self.file)
        if self.image.file is not None:
            self.statusbar.showMessage("current file: %s" % os.path.basename(self.image.file))
        flt = "zeiss(*.czi)"
        f = QtGui.QFileDialog.getOpenFileName(qfd, "Open File", path, flt)
        if len(f) > 0:
            self.image.file = f
            self.image.zstack = self.ctrl.zSpin.value()
            self.image.dnaChannel = self.ctrl.dnaSpin.value()
            self.ctrl.nchLbl.setText("%d channels" % self.image.nChannels)
            self.ctrl.nzsLbl.setText("%d z-stacks" % self.image.nZstack)
            self.ctrl.nfrLbl.setText("%d %s" % (self.image.nFrames, "frames" if self.image.nFrames > 1 else "frame"))

    @QtCore.pyqtSlot()
    def onImgUpdate(self):
        logger.debug('onImgUpdate')
        self.ctrl.renderChk.setChecked(True)
        self._graph()

    @QtCore.pyqtSlot()
    def onMeasureButton(self):
        logger.debug('onMeasureButton')
        self.image.paint_measures()
        self._graph(alpha=0.2)
        self._graphTendency()

    @QtCore.pyqtSlot()
    def onZValueChange(self):
        logger.debug('onZValueChange')
        self.image.zstack = self.ctrl.zSpin.value() % self.image.nZstack
        self.ctrl.zSpin.setValue(self.image.zstack)
        self._graph()

    @QtCore.pyqtSlot()
    def onDnaValChange(self):
        logger.debug('onDnaValChange')
        val = self.ctrl.dnaSpin.value() % self.image.nChannels
        self.ctrl.dnaSpin.setValue(val)
        self.image.dnaChannel = val
        if self.ctrl.dnaChk.isChecked():
            self.image.activeCh = "dna"
        self.ctrl.dnaChk.setChecked(True)

    @QtCore.pyqtSlot()
    def onActValChange(self):
        logger.debug('onActValChange')
        val = self.ctrl.actSpin.value() % self.image.nChannels
        self.ctrl.actSpin.setValue(val)
        self.image.actChannel = val
        if self.ctrl.actChk.isChecked():
            self.image.activeCh = "act"
        self.ctrl.actChk.setChecked(True)

    @QtCore.pyqtSlot()
    def onAddButton(self):
        logger.debug('onAddButton')
        if self.image.measurements is not None:
            new = pd.DataFrame(self.image.measurements)
            if self.selectedLine is not None:
                new = new.loc[new["n"] == self.selectedLine]
            new.loc[:, "m"] = self.measure_n
            new.loc[:, "z"] = self.image.zstack
            new.loc[:, "file"] = os.path.basename(self.image.file)
            # new.loc[:, "x"] = new.loc[:, "l"].apply(lambda v: np.arange(start=0, stop=len(v), step=self.image.dl))
            self.df = self.df.append(new, ignore_index=True, sort=False)
            self.measure_n += 1
            print(self.df)

    @QtCore.pyqtSlot()
    def onPlotButton(self):
        logger.debug('onPlotButton')
        if self.image.measurements is None: return
        import matplotlib.pyplot as plt
        import seaborn as sns
        from matplotlib.gridspec import GridSpec

        plt.style.use('bmh')
        pal = sns.color_palette("Blues", n_colors=len(self.image.measurements))
        fig = plt.figure(figsize=(2, 2 * 4), dpi=300)
        gs = GridSpec(nrows=2, ncols=1, height_ratios=[4, 0.5])
        ax1 = plt.subplot(gs[0, 0])
        ax2 = plt.subplot(gs[1, 0])
        self.image.drawMeasurements(ax1, pal)

        lw = 1
        for me, c in zip(self.image.measurements, pal):
            x = np.arange(start=0, stop=len(me['l']) * self.image.dl, step=self.image.dl)
            ax2.plot(x, me['l'], linewidth=lw, linestyle='-', color=c, alpha=1, zorder=10)

        ax1.xaxis.set_major_locator(ticker.MultipleLocator(20))
        ax1.xaxis.set_minor_locator(ticker.MultipleLocator(10))
        ax1.yaxis.set_major_locator(ticker.MultipleLocator(20))
        ax1.yaxis.set_minor_locator(ticker.MultipleLocator(10))

        ax2.xaxis.set_major_locator(ticker.MultipleLocator(1))
        ax2.xaxis.set_minor_locator(ticker.MultipleLocator(0.5))
        ax2.yaxis.set_major_locator(ticker.MultipleLocator(1e4))
        ax2.yaxis.set_minor_locator(ticker.MultipleLocator(5e3))
        ax2.yaxis.set_major_formatter(EngFormatter(unit=''))

        fig.savefig(os.path.basename(self.image.file) + ".pdf")

    @QtCore.pyqtSlot()
    def onLinePickedFromGraph(self):
        logger.debug('onLinePickedFromGraph')
        self.selectedLine = self.grph.selectedLine if self.grph.selectedLine is not None else None
        if self.selectedLine is not None:
            self.image.selectedLine = self.selectedLine
            self.statusbar.showMessage("line %d selected" % self.selectedLine)

    @QtCore.pyqtSlot()
    def onLinePickedFromImage(self):
        logger.debug('onLinePickedFromImage')
        self.selectedLine = self.image.selectedLine['n'] if self.image.selectedLine is not None else None
        if self.selectedLine is not None:
            self.statusbar.showMessage("line %d selected" % self.selectedLine)