Пример #1
0
    def _initWidgets(self):
        # create a slider for time selection
        self.timeSlider = TimeRangeSlider()
        self.timeSlider.setFixedHeight(30)
        self.timeSlider.setMinimumWidth(600)
        self.timeSlider.setEnabled(False)

        # create a button for add condition
        self.btnAdd = QPushButton('Add new condition')
        self.btnAdd.setFixedSize(135, 50)

        # create a table for created condition
        self.conditionTable = QTableWidget()
        self.conditionTable.setColumnCount(3)
        self.conditionTable.setHorizontalHeaderLabels(
            ['Condition', 'Arrival', 'Duration'])
        vh = self.conditionTable.verticalHeader()
        vh.setSectionResizeMode(QHeaderView.Fixed)
        vh.setDefaultSectionSize(20)
        hh = self.conditionTable.horizontalHeader()
        hh.setDefaultSectionSize(150)
        self.conditionTable.setMaximumHeight(500)

        # create text boxes for displaying the time selection
        self.timeSelection = TimeSelection(self)
        self.timeSelection.startIndex.setEnabled(False)
        self.timeSelection.endIndex.setEnabled(False)
        self.timeSelection.startValue.setEnabled(False)
        self.timeSelection.endValue.setEnabled(False)

        # create the widget displaying message logs
        self.logTextBox = QPlainTextEditLogger(self)
        self.logTextBox.setFormatter(
            logging.Formatter('%(asctime)s - [%(levelname)s] - \n%(message)s'))
        logging.getLogger().addHandler(self.logTextBox)
        logging.getLogger().setLevel(self.parent.logging_level)

        # create a combo box for time unit
        self.unitBox = QComboBox()
        for unit in ['second', 'minute', 'hour', 'day', 'percentage']:
            self.unitBox.addItem(unit)
        self.unitBox.setFixedHeight(30)
        self.unitBox.setMaximumWidth(200)

        # create a check box for output file format (simple or double precision)
        self.singlePrecisionBox = QCheckBox(
            'Convert to SERAFIN \n(single precision)', self)
        self.singlePrecisionBox.setEnabled(False)

        # create the submit button
        self.btnSubmit = QPushButton('Submit',
                                     self,
                                     icon=self.style().standardIcon(
                                         QStyle.SP_DialogSaveButton))
        self.btnSubmit.setToolTip('<b>Submit</b> to write a Serafin output')
        self.btnSubmit.setFixedSize(105, 50)
        self.btnSubmit.setEnabled(False)
Пример #2
0
    def _initWidgets(self):
        # create a checkbox for operation selection
        self.opBox = QGroupBox('Compute')
        hlayout = QHBoxLayout()
        self.maxButton = QRadioButton('Max')
        self.minButton = QRadioButton('Min')
        meanButton = QRadioButton('Mean')

        hlayout.addWidget(self.maxButton)
        hlayout.addWidget(self.minButton)
        hlayout.addWidget(meanButton)

        self.opBox.setLayout(hlayout)
        self.opBox.setMaximumHeight(80)
        self.opBox.setMaximumWidth(200)
        self.maxButton.setChecked(True)

        # create a slider for time selection
        self.timeSlider = TimeRangeSlider()
        self.timeSlider.setFixedHeight(30)
        self.timeSlider.setMinimumWidth(600)
        self.timeSlider.setEnabled(False)

        # create text boxes for displaying the time selection
        self.timeSelection = TimeSelection(self)
        self.timeSelection.startIndex.setEnabled(False)
        self.timeSelection.endIndex.setEnabled(False)
        self.timeSelection.startValue.setEnabled(False)
        self.timeSelection.endValue.setEnabled(False)

        # create two 3-column tables for variables selection
        self.firstTable = VariableTable()
        self.secondTable = VariableTable()
        self.secondTable.setMinimumHeight(300)

        # create the widget displaying message logs
        self.logTextBox = QPlainTextEditLogger(self)
        self.logTextBox.setFormatter(
            logging.Formatter('%(asctime)s - [%(levelname)s] - \n%(message)s'))
        logging.getLogger().addHandler(self.logTextBox)
        logging.getLogger().setLevel(self.parent.logging_level)

        # create a check box for output file format (simple or double precision)
        self.singlePrecisionBox = QCheckBox(
            'Convert to SERAFIN \n(single precision)', self)
        self.singlePrecisionBox.setEnabled(False)

        # create the submit button
        self.btnSubmit = QPushButton('Submit',
                                     self,
                                     icon=self.style().standardIcon(
                                         QStyle.SP_DialogSaveButton))
        self.btnSubmit.setToolTip('<b>Submit</b> to write a Serafin output')
        self.btnSubmit.setFixedSize(105, 50)
        self.btnSubmit.setEnabled(False)
Пример #3
0
class SynchMaxTab(QWidget):
    def __init__(self, parent):
        super().__init__()
        self.data = None
        self.parent = parent

        self._initWidgets()
        self._setLayout()
        self._bindEvents()

    def _initWidgets(self):
        # create a combox box for variable selection
        self.varBox = QComboBox()
        self.varBox.setFixedSize(200, 30)

        # create a slider for time selection
        self.timeSlider = TimeRangeSlider()
        self.timeSlider.setFixedHeight(30)
        self.timeSlider.setMinimumWidth(600)
        self.timeSlider.setEnabled(False)

        # create text boxes for displaying the time selection
        self.timeSelection = TimeSelection(self)
        self.timeSelection.startIndex.setEnabled(False)
        self.timeSelection.endIndex.setEnabled(False)
        self.timeSelection.startValue.setEnabled(False)
        self.timeSelection.endValue.setEnabled(False)

        # create two 3-column tables for variables selection
        self.firstTable = VariableTable()
        self.secondTable = VariableTable()
        self.secondTable.setMinimumHeight(300)

        # create the widget displaying message logs
        self.logTextBox = QPlainTextEditLogger(self)
        self.logTextBox.setFormatter(
            logging.Formatter('%(asctime)s - [%(levelname)s] - \n%(message)s'))
        logging.getLogger().addHandler(self.logTextBox)
        logging.getLogger().setLevel(self.parent.logging_level)

        # create a check box for output file format (simple or double precision)
        self.singlePrecisionBox = QCheckBox(
            'Convert to SERAFIN \n(single precision)', self)
        self.singlePrecisionBox.setEnabled(False)

        # create the submit button
        self.btnSubmit = QPushButton('Submit',
                                     self,
                                     icon=self.style().standardIcon(
                                         QStyle.SP_DialogSaveButton))
        self.btnSubmit.setToolTip('<b>Submit</b> to write a Serafin output')
        self.btnSubmit.setFixedSize(105, 50)
        self.btnSubmit.setEnabled(False)

    def _setLayout(self):
        mainLayout = QVBoxLayout()
        mainLayout.addItem(QSpacerItem(1, 10))
        mainLayout.addWidget(self.timeSlider)
        mainLayout.addWidget(self.timeSelection)
        mainLayout.addItem(QSpacerItem(1, 10))

        hlayout = QHBoxLayout()
        hlayout.addWidget(QLabel('  Select the reference variable '))
        hlayout.addWidget(self.varBox, Qt.AlignLeft)
        hlayout.addStretch()
        mainLayout.addLayout(hlayout)
        mainLayout.addItem(QSpacerItem(1, 10))

        hlayout = QHBoxLayout()
        hlayout.addItem(QSpacerItem(30, 1))
        vlayout = QVBoxLayout()
        vlayout.setAlignment(Qt.AlignHCenter)
        lb = QLabel('Available variables')
        vlayout.addWidget(lb)
        vlayout.setAlignment(lb, Qt.AlignHCenter)
        vlayout.addWidget(self.firstTable)
        hlayout.addLayout(vlayout)
        hlayout.addItem(QSpacerItem(15, 1))
        vlayout = QVBoxLayout()
        lb = QLabel('Output variables')
        vlayout.addWidget(lb)
        vlayout.setAlignment(lb, Qt.AlignHCenter)
        vlayout.addWidget(self.secondTable)
        hlayout.addLayout(vlayout)
        hlayout.addItem(QSpacerItem(30, 1))

        mainLayout.addLayout(hlayout)
        mainLayout.addItem(QSpacerItem(50, 20))
        hlayout = QHBoxLayout()
        hlayout.addItem(QSpacerItem(50, 10))
        hlayout.addWidget(self.btnSubmit)
        hlayout.addItem(QSpacerItem(50, 10))
        hlayout.addWidget(self.singlePrecisionBox)
        hlayout.addItem(QSpacerItem(50, 10))
        mainLayout.addLayout(hlayout)
        mainLayout.addItem(QSpacerItem(30, 15))
        mainLayout.addWidget(QLabel('   Message logs'))
        mainLayout.addWidget(self.logTextBox.widget)
        self.setLayout(mainLayout)

    def _bindEvents(self):
        self.btnSubmit.clicked.connect(self.btnSubmitEvent)
        self.timeSelection.startIndex.editingFinished.connect(
            self.timeSlider.enterIndexEvent)
        self.timeSelection.endIndex.editingFinished.connect(
            self.timeSlider.enterIndexEvent)
        self.timeSelection.startValue.editingFinished.connect(
            self.timeSlider.enterValueEvent)
        self.timeSelection.endValue.editingFinished.connect(
            self.timeSlider.enterValueEvent)

    def _initVarTables(self):
        self.firstTable.fill(self.data.header)
        self.secondTable.insertRow(0)
        self.secondTable.setItem(0, 0, QTableWidgetItem('MAX TIME'))
        self.secondTable.setItem(0, 1, QTableWidgetItem('MAX TIME'))
        self.secondTable.setItem(0, 2, QTableWidgetItem('S'))
        for j in range(3):
            self.secondTable.item(0, j).setFlags(Qt.NoItemFlags)

    def _getSelectedVariables(self):
        return self.secondTable.get_selected_all()

    def reset(self):
        self.varBox.clear()
        self.firstTable.setRowCount(0)
        self.secondTable.setRowCount(0)
        self.timeSelection.disable()
        self.btnSubmit.setEnabled(False)
        self.singlePrecisionBox.setChecked(False)
        self.singlePrecisionBox.setEnabled(False)

    def getOutputHeader(self, selected_vars):
        output_header = self.data.header.copy()
        output_header.nb_var = len(selected_vars)
        output_header.var_IDs, output_header.var_names, output_header.var_units = [], [], []
        for var_ID, var_name, var_unit in selected_vars:
            output_header.var_IDs.append(var_ID)
            output_header.var_names.append(var_name)
            output_header.var_units.append(var_unit)
        if self.singlePrecisionBox.isChecked():
            output_header.to_single_precision()
        return output_header

    def getInput(self, data):
        self.data = data
        self._initVarTables()
        for var, var_name in zip(self.data.header.var_IDs,
                                 self.data.header.var_names):
            item = '%s (%s)' % (var, var_name.decode('utf-8').strip())
            self.varBox.addItem(item)

        self.btnSubmit.setEnabled(True)

        # unlock convert to single precision
        if self.data.header.is_double_precision():
            self.singlePrecisionBox.setEnabled(True)

        if self.data.header.date is not None:
            year, month, day, hour, minute, second = self.data.header.date
            start_time = datetime.datetime(year, month, day, hour, minute,
                                           second)
        else:
            start_time = datetime.datetime(1900, 1, 1, 0, 0, 0)

        time_frames = list(
            map(lambda x: datetime.timedelta(seconds=x), self.data.time))
        self.timeSlider.reinit(start_time, time_frames, self.timeSelection)
        self.timeSlider.setEnabled(True)
        self.timeSelection.enable()

    def btnSubmitEvent(self):
        # fetch the list of selected variables
        selected_vars = self._getSelectedVariables()
        if not selected_vars:
            QMessageBox.critical(self, 'Error',
                                 'Select at least one variable.',
                                 QMessageBox.Ok)
            return

        canceled, filename = save_dialog('Serafin', self.data.filename)
        if canceled:
            return

        # deduce header from selected variable IDs and write header
        output_header = self.getOutputHeader(selected_vars)

        start_index = int(self.timeSelection.startIndex.text()) - 1
        end_index = int(self.timeSelection.endIndex.text())
        time_indices = list(range(start_index, end_index))
        var = self.varBox.currentText().split(' (')[0]

        output_message = 'Computing SynchMax of variables %s between frame %d and %d.' \
                          % (str(list(map(lambda x: x[0], selected_vars[1:]))), start_index+1, end_index)
        self.parent.inDialog()
        logging.info(output_message)
        progressBar = OutputProgressDialog()

        # do some calculations
        with Serafin.Read(self.data.filename,
                          self.data.language) as input_stream:
            input_stream.header = self.data.header
            input_stream.time = self.data.time

            progressBar.setValue(5)
            QApplication.processEvents()

            with Serafin.Write(filename, self.data.language) as output_stream:
                process = SynchMaxThread(input_stream, selected_vars[1:],
                                         time_indices, var)
                progressBar.connectToThread(process)
                values = process.run()

                if not process.canceled:
                    output_stream.write_header(output_header)
                    output_stream.write_entire_frame(output_header,
                                                     self.data.time[0], values)
                    progressBar.outputFinished()

        progressBar.exec_()
        self.parent.outDialog()
Пример #4
0
class ArrivalDurationTab(QWidget):
    def __init__(self, parent):
        super().__init__()
        self.data = None
        self.parent = parent

        self.conditions = []

        self._initWidgets()
        self._setLayout()
        self._bindEvents()

    def _initWidgets(self):
        # create a slider for time selection
        self.timeSlider = TimeRangeSlider()
        self.timeSlider.setFixedHeight(30)
        self.timeSlider.setMinimumWidth(600)
        self.timeSlider.setEnabled(False)

        # create a button for add condition
        self.btnAdd = QPushButton('Add new condition')
        self.btnAdd.setFixedSize(135, 50)

        # create a table for created condition
        self.conditionTable = QTableWidget()
        self.conditionTable.setColumnCount(3)
        self.conditionTable.setHorizontalHeaderLabels(
            ['Condition', 'Arrival', 'Duration'])
        vh = self.conditionTable.verticalHeader()
        vh.setSectionResizeMode(QHeaderView.Fixed)
        vh.setDefaultSectionSize(20)
        hh = self.conditionTable.horizontalHeader()
        hh.setDefaultSectionSize(150)
        self.conditionTable.setMaximumHeight(500)

        # create text boxes for displaying the time selection
        self.timeSelection = TimeSelection(self)
        self.timeSelection.startIndex.setEnabled(False)
        self.timeSelection.endIndex.setEnabled(False)
        self.timeSelection.startValue.setEnabled(False)
        self.timeSelection.endValue.setEnabled(False)

        # create the widget displaying message logs
        self.logTextBox = QPlainTextEditLogger(self)
        self.logTextBox.setFormatter(
            logging.Formatter('%(asctime)s - [%(levelname)s] - \n%(message)s'))
        logging.getLogger().addHandler(self.logTextBox)
        logging.getLogger().setLevel(self.parent.logging_level)

        # create a combo box for time unit
        self.unitBox = QComboBox()
        for unit in ['second', 'minute', 'hour', 'day', 'percentage']:
            self.unitBox.addItem(unit)
        self.unitBox.setFixedHeight(30)
        self.unitBox.setMaximumWidth(200)

        # create a check box for output file format (simple or double precision)
        self.singlePrecisionBox = QCheckBox(
            'Convert to SERAFIN \n(single precision)', self)
        self.singlePrecisionBox.setEnabled(False)

        # create the submit button
        self.btnSubmit = QPushButton('Submit',
                                     self,
                                     icon=self.style().standardIcon(
                                         QStyle.SP_DialogSaveButton))
        self.btnSubmit.setToolTip('<b>Submit</b> to write a Serafin output')
        self.btnSubmit.setFixedSize(105, 50)
        self.btnSubmit.setEnabled(False)

    def _setLayout(self):
        mainLayout = QVBoxLayout()
        mainLayout.addItem(QSpacerItem(1, 10))
        mainLayout.addWidget(self.timeSlider)
        mainLayout.addWidget(self.timeSelection)
        mainLayout.addItem(QSpacerItem(1, 10))

        hlayout = QHBoxLayout()
        hlayout.addItem(QSpacerItem(50, 10))
        hlayout.addWidget(self.btnAdd)
        lb = QLabel(
            'Double click on the cells to edit Arrival / Duration variable names'
        )
        hlayout.addWidget(lb)
        hlayout.setAlignment(lb, Qt.AlignBottom | Qt.AlignRight)
        mainLayout.addLayout(hlayout)
        mainLayout.addItem(QSpacerItem(1, 5))
        mainLayout.addWidget(self.conditionTable)

        mainLayout.addItem(QSpacerItem(1, 10))
        hlayout = QHBoxLayout()
        hlayout.addItem(QSpacerItem(50, 10))
        hlayout.addWidget(self.btnSubmit)
        hlayout.addItem(QSpacerItem(10, 10))
        vlayout = QVBoxLayout()
        vlayout.addWidget(QLabel('Time unit'))
        vlayout.addWidget(self.unitBox)
        hlayout.addLayout(vlayout)
        hlayout.addItem(QSpacerItem(10, 10))
        hlayout.addWidget(self.singlePrecisionBox)
        hlayout.addItem(QSpacerItem(50, 10))
        mainLayout.addLayout(hlayout)
        mainLayout.addItem(QSpacerItem(30, 15))
        mainLayout.addWidget(QLabel('   Message logs'))
        mainLayout.addWidget(self.logTextBox.widget)
        self.setLayout(mainLayout)

    def _bindEvents(self):
        self.btnAdd.clicked.connect(self.btnAddEvent)
        self.btnSubmit.clicked.connect(self.btnSubmitEvent)
        self.conditionTable.cellChanged.connect(self._checkName)
        self.timeSelection.startIndex.editingFinished.connect(
            self.timeSlider.enterIndexEvent)
        self.timeSelection.endIndex.editingFinished.connect(
            self.timeSlider.enterIndexEvent)
        self.timeSelection.startValue.editingFinished.connect(
            self.timeSlider.enterValueEvent)
        self.timeSelection.endValue.editingFinished.connect(
            self.timeSlider.enterValueEvent)

    def _current_names(self, ignore_row, ignore_column):
        names = []
        for row in range(self.conditionTable.rowCount()):
            for column in range(1, 3):
                if row == ignore_row and column == ignore_column:
                    continue
                item = self.conditionTable.item(row, column)
                if item is not None:
                    names.append(item.text())
        return names

    def _current_conditions(self):
        conditions = []
        for row in range(self.conditionTable.rowCount()):
            conditions.append(self.conditionTable.item(row, 0).text())
        return conditions

    def _checkName(self, row, column):
        if column == 1 or column == 2:
            name = self.conditionTable.item(row, column).text()
            if len(name) < 2 or len(name) > 16:
                QMessageBox.critical(
                    self, 'Error',
                    'The variable names should be between 2 and 16 characters!',
                    QMessageBox.Ok)
            elif name in self._current_names(row, column):
                QMessageBox.critical(self, 'Error', 'Duplicated name.',
                                     QMessageBox.Ok)
            else:
                return
            # back to default
            condition = self.conditionTable.item(row, 0).text()
            condition_tight = operations.tighten_expression(condition)
            if column == 1:
                self.conditionTable.setItem(
                    row, column, QTableWidgetItem(
                        ('A ' + condition_tight)[:16]))
            else:
                self.conditionTable.setItem(
                    row, column, QTableWidgetItem(
                        ('D ' + condition_tight)[:16]))

    def _convertTimeUnit(self, time_indices, values):
        time_unit = self.unitBox.currentText()
        if time_unit == 'minute':
            values /= 60
        elif time_unit == 'hour':
            values /= 3600
        elif time_unit == 'day':
            values /= 86400
        elif time_unit == 'percentage':
            values *= 100 / (self.input.time[time_indices[-1]] -
                             self.input.time[time_indices[0]])
        return values

    def reset(self):
        self.conditions = []
        self.conditionTable.setRowCount(0)
        self.timeSelection.disable()
        self.btnSubmit.setEnabled(False)
        self.singlePrecisionBox.setChecked(False)
        self.singlePrecisionBox.setEnabled(False)

    def getInput(self, data):
        self.btnSubmit.setEnabled(True)
        self.data = data

        # unlock convert to single precision
        if self.data.header.is_double_precision():
            self.singlePrecisionBox.setEnabled(True)

        if self.data.header.date is not None:
            year, month, day, hour, minute, second = self.data.header.date
            start_time = datetime.datetime(year, month, day, hour, minute,
                                           second)
        else:
            start_time = datetime.datetime(1900, 1, 1, 0, 0, 0)

        time_frames = list(
            map(lambda x: datetime.timedelta(seconds=x), self.data.time))
        self.timeSlider.reinit(start_time, time_frames, self.timeSelection)

        self.timeSlider.setEnabled(True)
        self.timeSelection.enable()

    def getOutputHeader(self):
        output_header = self.data.header.copy()
        output_header.nb_var = 2 * len(self.conditions)
        output_header.var_IDs, output_header.var_names, output_header.var_units = [], [], []
        for row in range(self.conditionTable.rowCount()):
            a_name = self.conditionTable.item(row, 1).text()
            d_name = self.conditionTable.item(row, 2).text()
            for name in [a_name, d_name]:
                output_header.var_IDs.append('')
                output_header.var_names.append(bytes(name, 'utf-8').ljust(16))
                output_header.var_units.append(
                    bytes(self.unitBox.currentText().upper(),
                          'utf-8').ljust(16))
        if self.singlePrecisionBox.isChecked():
            output_header.to_single_precision()
        return output_header

    def btnAddEvent(self):
        dlg = ConditionDialog(self.data.header.var_IDs,
                              self.data.header.var_names)
        value = dlg.exec_()
        if value == QDialog.Rejected:
            return
        condition = str(dlg.condition)
        if condition in self._current_conditions():
            QMessageBox.critical(self, 'Error',
                                 'This condition is already added!',
                                 QMessageBox.Ok)
            return
        condition_tight = operations.tighten_expression(
            condition)  # used to define variable names
        self.conditions.append(dlg.condition)

        row = self.conditionTable.rowCount()
        self.conditionTable.insertRow(row)
        condition_item = QTableWidgetItem(condition)
        condition_item.setFlags(Qt.ItemIsEditable)
        self.conditionTable.setItem(row, 0, condition_item)
        self.conditionTable.setItem(
            row, 1, QTableWidgetItem(('A ' + condition_tight)[:16]))
        self.conditionTable.setItem(
            row, 2, QTableWidgetItem(('D ' + condition_tight)[:16]))

    def btnSubmitEvent(self):
        if not self.conditions:
            QMessageBox.critical(self, 'Error', 'Add at least one condition.',
                                 QMessageBox.Ok)
            return

        start_index = int(self.timeSelection.startIndex.text()) - 1
        end_index = int(self.timeSelection.endIndex.text())
        time_indices = list(range(start_index, end_index))

        if len(time_indices) == 1:
            QMessageBox.critical(self, 'Error',
                                 'Start and end frame cannot be the same.',
                                 QMessageBox.Ok)
            return

        canceled, filename = save_dialog('Serafin', self.data.filename)
        if canceled:
            return

        # deduce header from selected variable IDs and write header
        output_header = self.getOutputHeader()
        output_message = 'Computing Arrival / Duration between frame %d and %d.' \
                          % (start_index+1, end_index)
        self.parent.inDialog()
        logging.info(output_message)
        progressBar = OutputProgressDialog()

        # do some calculations
        with Serafin.Read(self.data.filename,
                          self.data.language) as input_stream:
            input_stream.header = self.data.header
            input_stream.time = self.data.time

            progressBar.setValue(5)
            QApplication.processEvents()

            with Serafin.Write(filename, self.data.language) as output_stream:
                process = ArrivalDurationThread(input_stream, self.conditions,
                                                time_indices)
                progressBar.connectToThread(process)
                values = process.run()

                if not process.canceled:
                    values = self._convertTimeUnit(time_indices, values)
                    output_stream.write_header(output_header)
                    output_stream.write_entire_frame(output_header,
                                                     self.data.time[0], values)
                    progressBar.outputFinished()

        progressBar.exec_()
        self.parent.outDialog()
Пример #5
0
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        self.start_time = None
        self.time = []

        # create a slider for time selection
        self.timeSlider = TimeRangeSlider()
        self.timeSlider.setFixedHeight(30)
        self.timeSlider.setMinimumWidth(600)
        self.timeSlider.setEnabled(False)
        self.last_sampling_frequency = 1

        # create text boxes for displaying the time selection and sampling
        self.timeSelection = DoubleSliderBox(self)
        self.timeSelection.startIndex.setEnabled(False)
        self.timeSelection.endIndex.setEnabled(False)
        self.timeSelection.startValue.setEnabled(False)
        self.timeSelection.endValue.setEnabled(False)

        # create the tables for manual selection
        self.manualSelection = ManualTimeSelection(self)

        # create the button for manual selection
        self.btnManual = QPushButton('Manual selection')
        self.btnManual.setFixedSize(130, 50)
        self.btnManual.setEnabled(False)

        # create a text field for selection display
        self.selectionTextBox = QPlainTextEdit()

        # bind events
        self.timeSelection.startIndex.editingFinished.connect(
            self.timeSlider.enterIndexEvent)
        self.timeSelection.endIndex.editingFinished.connect(
            self.timeSlider.enterIndexEvent)
        self.timeSelection.startValue.editingFinished.connect(
            self.timeSlider.enterValueEvent)
        self.timeSelection.endValue.editingFinished.connect(
            self.timeSlider.enterValueEvent)

        self.btnManual.clicked.connect(self.btnManualEvent)
        self.timeSelection.startDate.textChanged.connect(
            self.regularSelectionEvent)
        self.timeSelection.endDate.textChanged.connect(
            self.regularSelectionEvent)
        self.timeSelection.timeSamplig.editingFinished.connect(
            self.regularSelectionEvent)

        # set layout
        mainLayout = QVBoxLayout()
        mainLayout.addItem(QSpacerItem(50, 20))
        mainLayout.addWidget(self.timeSlider)
        mainLayout.addItem(QSpacerItem(10, 5))
        mainLayout.addWidget(self.timeSelection)
        mainLayout.addItem(QSpacerItem(50, 20))
        hlayout = QHBoxLayout()
        hlayout.addItem(QSpacerItem(20, 20))
        hlayout.addWidget(self.btnManual)
        hlayout.addWidget(self.selectionTextBox, Qt.AlignLeft)
        hlayout.setSpacing(15)
        hlayout.setAlignment(self.btnManual, Qt.AlignTop)
        mainLayout.addLayout(hlayout)
        mainLayout.setAlignment(Qt.AlignTop)
        self.setLayout(mainLayout)

        self.setMinimumWidth(800)
        self.setWindowFlags(self.windowFlags() | Qt.CustomizeWindowHint)
Пример #6
0
class TimeTab(QWidget):
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        self.start_time = None
        self.time = []

        # create a slider for time selection
        self.timeSlider = TimeRangeSlider()
        self.timeSlider.setFixedHeight(30)
        self.timeSlider.setMinimumWidth(600)
        self.timeSlider.setEnabled(False)
        self.last_sampling_frequency = 1

        # create text boxes for displaying the time selection and sampling
        self.timeSelection = DoubleSliderBox(self)
        self.timeSelection.startIndex.setEnabled(False)
        self.timeSelection.endIndex.setEnabled(False)
        self.timeSelection.startValue.setEnabled(False)
        self.timeSelection.endValue.setEnabled(False)

        # create the tables for manual selection
        self.manualSelection = ManualTimeSelection(self)

        # create the button for manual selection
        self.btnManual = QPushButton('Manual selection')
        self.btnManual.setFixedSize(130, 50)
        self.btnManual.setEnabled(False)

        # create a text field for selection display
        self.selectionTextBox = QPlainTextEdit()

        # bind events
        self.timeSelection.startIndex.editingFinished.connect(
            self.timeSlider.enterIndexEvent)
        self.timeSelection.endIndex.editingFinished.connect(
            self.timeSlider.enterIndexEvent)
        self.timeSelection.startValue.editingFinished.connect(
            self.timeSlider.enterValueEvent)
        self.timeSelection.endValue.editingFinished.connect(
            self.timeSlider.enterValueEvent)

        self.btnManual.clicked.connect(self.btnManualEvent)
        self.timeSelection.startDate.textChanged.connect(
            self.regularSelectionEvent)
        self.timeSelection.endDate.textChanged.connect(
            self.regularSelectionEvent)
        self.timeSelection.timeSamplig.editingFinished.connect(
            self.regularSelectionEvent)

        # set layout
        mainLayout = QVBoxLayout()
        mainLayout.addItem(QSpacerItem(50, 20))
        mainLayout.addWidget(self.timeSlider)
        mainLayout.addItem(QSpacerItem(10, 5))
        mainLayout.addWidget(self.timeSelection)
        mainLayout.addItem(QSpacerItem(50, 20))
        hlayout = QHBoxLayout()
        hlayout.addItem(QSpacerItem(20, 20))
        hlayout.addWidget(self.btnManual)
        hlayout.addWidget(self.selectionTextBox, Qt.AlignLeft)
        hlayout.setSpacing(15)
        hlayout.setAlignment(self.btnManual, Qt.AlignTop)
        mainLayout.addLayout(hlayout)
        mainLayout.setAlignment(Qt.AlignTop)
        self.setLayout(mainLayout)

        self.setMinimumWidth(800)
        self.setWindowFlags(self.windowFlags() | Qt.CustomizeWindowHint)

    def getTime(self):
        start_index = int(self.timeSelection.startIndex.text())
        end_index = int(self.timeSelection.endIndex.text())
        try:
            sampling_frequency = int(self.timeSelection.timeSamplig.text())
        except ValueError:
            QMessageBox.critical(self, 'Error',
                                 'The sampling frequency must be a number!',
                                 QMessageBox.Ok)
            self.timeSelection.timeSamplig.setText(
                str(self.last_sampling_frequency))
            return []
        if sampling_frequency < 1 or sampling_frequency > end_index:
            QMessageBox.critical(
                self, 'Error',
                'The sampling frequency must be in the range [1; nbFrames]!',
                QMessageBox.Ok)
            self.timeSelection.timeSamplig.setText(
                str(self.last_sampling_frequency))
            return []
        self.last_sampling_frequency = sampling_frequency
        return start_index, end_index, sampling_frequency, list(
            range(start_index - 1, end_index, sampling_frequency))

    def getManualTime(self):
        selected_indices = []
        for i in range(self.manualSelection.secondTable.rowCount()):
            selected_indices.append(
                int(self.manualSelection.secondTable.item(i, 0).text()) - 1)
        return selected_indices

    def reset(self):
        self.timeSlider.setEnabled(False)
        self.timeSelection.startIndex.setEnabled(False)
        self.timeSelection.endIndex.setEnabled(False)
        self.timeSelection.startValue.setEnabled(False)
        self.timeSelection.endValue.setEnabled(False)
        self.btnManual.setEnabled(False)
        self.manualSelection.hasData = False
        self.manualSelection.time_frames = None
        self.timeSelection.visited = False
        self.selectionTextBox.clear()
        self.selectionTextBox.appendPlainText(
            '=== Manual selection mode OFF ===')

    def getInput(self, data):
        if data.header.date is not None:
            year, month, day, hour, minute, second = data.header.date
            self.start_time = datetime.datetime(year, month, day, hour, minute,
                                                second)
        else:
            self.start_time = datetime.datetime(1900, 1, 1, 0, 0, 0)

        self.time = data.time
        time_frames = list(
            map(lambda x: datetime.timedelta(seconds=x), data.time))
        self.timeSelection.clearText()
        self.timeSlider.reinit(self.start_time, time_frames,
                               self.timeSelection)

        if data.header.nb_frames > 1:
            self.timeSlider.setEnabled(True)
            self.timeSelection.startIndex.setEnabled(True)
            self.timeSelection.endIndex.setEnabled(True)
            self.timeSelection.startValue.setEnabled(True)
            self.timeSelection.endValue.setEnabled(True)
            self.btnManual.setEnabled(True)

    def regularSelectionEvent(self):
        if not self.timeSelection.visited:  # avoid redundant text display at initialization
            self.timeSelection.visited = True
            return
        selection = self.getTime()
        if not selection:
            return
        start_index, end_index, sampling_frequency, indices = selection
        message = 'Current selection: %d frame%s between frame %d and %d with sampling frequency %d.' \
                  % (len(indices), ['', 's'][len(indices) > 1], start_index, end_index, sampling_frequency)

        if self.manualSelection.hasData:
            reply = QMessageBox.warning(
                self, 'Confirm turn off selection',
                'Do you want to turn off the manuel selection mode?\n(Your manual selection will be cleared)',
                QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)
            if reply == QMessageBox.Cancel:
                return
            self.manualSelection.hasData = False
            self.selectionTextBox.appendPlainText(
                '== Manual selection mode OFF ==')
        self.selectionTextBox.appendPlainText(message)

    def btnManualEvent(self):
        if not self.manualSelection.hasData:
            reply = QMessageBox.warning(
                self, 'Confirm manuel selection',
                'Do you want to enter the manuel selection mode?',
                QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)
            if reply == QMessageBox.Cancel:
                return
            self.manualSelection.getData(self.time)
            self.selectionTextBox.appendPlainText(
                '=== Manual selection mode ON ===')
        self.parent.inDialog()
        self.manualSelection.show()

    def quitManualSelection(self):
        selected = self.getManualTime()
        if not selected:
            _ = QMessageBox.critical(self, 'Error',
                                     'Please select at least one frame',
                                     QMessageBox.Ok, QMessageBox.Ok)
            return
        self.parent.outDialog()
        self.manualSelection.hide()
        self.selectionTextBox.appendPlainText(
            'Current selection: %d frame%s between frame %d and %d.' %
            (len(selected), ['', 's'][len(selected) > 1], selected[0] + 1,
             selected[-1] + 1))