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 _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)
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()
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()
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)
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))