def _initWidget(self): # create two 3-column tables for variables selection self.firstTable = VariableTable() self.secondTable = VariableTable() # create the options self.intersect = QCheckBox() self.intersect.setChecked(True) self.timeSelection = SimpleTimeDateSelection() self.referenceLine = QComboBox() # create the submit button self.btnSubmit = QPushButton('Submit\nto .csv', self, icon=self.style().standardIcon( QStyle.SP_DialogSaveButton)) self.btnSubmit.setToolTip('<b>Write</b> output to .csv') self.btnSubmit.setFixedSize(105, 50) self.btnSubmit.setEnabled(False) # create the output file name box self.csvNameBox = QLineEdit() self.csvNameBox.setReadOnly(True) self.csvNameBox.setFixedHeight(30) # 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)
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)
def __init__(self, inputTab, timeSelection, parent): super().__init__() self.inputTab = inputTab self.data = None self.timeSelection = timeSelection self.parent = parent # 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) # bind events self.btnSubmit.clicked.connect(self.btnSubmitEvent) # set layout mainLayout = QVBoxLayout() 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 _initWidgets(self): """! @brief (Used in __init__) Create widgets """ # create the group box for coordinate transformation self.confBox = QGroupBox('Apply coordinate transformation (optional)') self.confBox.setStyleSheet( 'QGroupBox {font-size: 12px;font-weight: bold;}') self.btnConfig = QPushButton('Load\nTransformation', self) self.btnConfig.setToolTip('<b>Open</b> a transformation config file') self.btnConfig.setFixedSize(105, 50) self.confNameBox = QLineEdit() self.confNameBox.setReadOnly(True) self.confNameBox.setFixedHeight(30) self.fromBox = QComboBox() self.fromBox.setFixedWidth(150) self.toBox = QComboBox() self.toBox.setFixedWidth(150) # create the open button self.btnOpen = QPushButton('Open', self, icon=self.style().standardIcon( QStyle.SP_DialogOpenButton)) self.btnOpen.setToolTip( '<b>Open</b> a geometry file (.shp .xyz .i2s .i3s)') self.btnOpen.setFixedSize(105, 50) # create some text fields displaying the IO files info self.inNameBox = QLineEdit() self.inNameBox.setReadOnly(True) self.inNameBox.setFixedHeight(30) # 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)
def _initWidgets(self): # create a text field for mesh intersection info display self.infoBox = QPlainTextEdit() self.infoBox.setFixedHeight(60) self.infoBox.setReadOnly(True) # create two 3-column tables for variables selection self.firstTable = VariableTable() self.secondTable = VariableTable() # create combo box widgets for choosing the operation self.operationBox = QComboBox() self.operationBox.setFixedSize(400, 30) for op in [ 'Project B on A', 'B - A', 'A - B', 'max(A, B)', 'min(A, B)' ]: self.operationBox.addItem(op) # 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)
class SubmitTab(QWidget): def __init__(self, inputTab, parent): super().__init__() self.input = inputTab self.parent = parent self._initWidgets() self._bindEvents() self._setLayout() def _initWidgets(self): # create a text field for mesh intersection info display self.infoBox = QPlainTextEdit() self.infoBox.setFixedHeight(60) self.infoBox.setReadOnly(True) # create two 3-column tables for variables selection self.firstTable = VariableTable() self.secondTable = VariableTable() # create combo box widgets for choosing the operation self.operationBox = QComboBox() self.operationBox.setFixedSize(400, 30) for op in [ 'Project B on A', 'B - A', 'A - B', 'max(A, B)', 'min(A, B)' ]: self.operationBox.addItem(op) # 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) def _bindEvents(self): self.btnSubmit.clicked.connect(self.btnSubmitEvent) def _setLayout(self): mainLayout = QVBoxLayout() mainLayout.addItem(QSpacerItem(1, 10)) mainLayout.addWidget(self.infoBox) mainLayout.addItem(QSpacerItem(1, 15)) hlayout = QHBoxLayout() hlayout.addItem(QSpacerItem(30, 1)) vlayout = QVBoxLayout() 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)) glayout = QGridLayout() glayout.addWidget(QLabel(' Select an operation'), 1, 1) glayout.addWidget(self.operationBox, 1, 2) glayout.setSpacing(10) mainLayout.addLayout(glayout) mainLayout.setAlignment(glayout, Qt.AlignTop | Qt.AlignLeft) 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 _initVarTables(self, common_vars): for i, (var_ID, var_name, var_unit) in enumerate(common_vars): self.firstTable.insertRow(self.firstTable.rowCount()) id_item = QTableWidgetItem(var_ID.strip()) name_item = QTableWidgetItem(var_name.decode('utf-8').strip()) unit_item = QTableWidgetItem(var_unit.decode('utf-8').strip()) self.firstTable.setItem(i, 0, id_item) self.firstTable.setItem(i, 1, name_item) self.firstTable.setItem(i, 2, unit_item) def _getSelectedVariables(self): return self.secondTable.get_selected_all() def _getOutputHeader(self): selected_vars = self._getSelectedVariables() output_header = self.input.first_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 _updateInfo(self): self.infoBox.clear() self.infoBox.appendPlainText( 'The two files has {} common variables and {} common frames.\n' 'The mesh A has {} / {} nodes inside the mesh B.'.format( self.firstTable.rowCount() + self.secondTable.rowCount(), len(self.input.common_frames), sum(self.input.is_inside), self.input.first_data.header.nb_nodes)) def reset(self): self.firstTable.setRowCount(0) self.secondTable.setRowCount(0) self.singlePrecisionBox.setChecked(False) self.singlePrecisionBox.setEnabled(False) def resetFirst(self): common_vars = [ (var_ID, var_name, var_unit) for var_ID, var_name, var_unit in zip( self.input.first_data.header.var_IDs, self.input.first_data. header.var_names, self.input.first_data.header.var_units) if var_ID in self.input.second_data.header.var_IDs ] if not common_vars: self.firstTable.setRowCount(0) self.secondTable.setRowCount(0) return False else: # recover, if possible, old variable selection old_selected = self._getSelectedVariables() self.firstTable.setRowCount(0) self.secondTable.setRowCount(0) self._initVarTables([(var_ID, var_name, var_unit) for var_ID, var_name, var_unit in common_vars if var_ID not in old_selected]) for var_ID, var_name, var_unit in common_vars: if var_ID in old_selected: row = self.secondTable.rowCount() self.secondTable.insertRow(row) id_item = QTableWidgetItem(var_ID.strip()) name_item = QTableWidgetItem( var_name.decode('utf-8').strip()) unit_item = QTableWidgetItem( var_unit.decode('utf-8').strip()) self.secondTable.setItem(row, 0, id_item) self.secondTable.setItem(row, 1, name_item) self.secondTable.setItem(row, 2, unit_item) return True def getSecond(self, old_second, common_vars): if not old_second: self.firstTable.setRowCount(0) self.secondTable.setRowCount(0) self._initVarTables(common_vars) if self.input.first_data.header.is_double_precision(): self.singlePrecisionBox.setEnabled(True) self._updateInfo() def btnSubmitEvent(self): if self.secondTable.rowCount() == 0: QMessageBox.critical( self, 'Error', 'Choose at least one output variable before submit!', QMessageBox.Ok) return canceled, filename = save_dialog('Serafin', input_names=[ self.input.first_data.filename, self.input.second_data.filename ]) if canceled: return # deduce header from selected variable IDs output_header = self._getOutputHeader() time_indices = self.input.common_frames operation_type = { 0: operations.PROJECT, 1: operations.DIFF, 2: operations.REV_DIFF, 3: operations.MAX_BETWEEN, 4: operations.MIN_BETWEEN }[self.operationBox.currentIndex()] self.parent.inDialog() progressBar = OutputProgressDialog() # do some calculations with Serafin.Read(self.input.first_data.filename, self.input.first_data.language) as first_in: first_in.header = self.input.first_data.header first_in.time = self.input.first_data.time with Serafin.Read(self.input.second_data.filename, self.input.second_data.language) as second_in: second_in.header = self.input.second_data.header second_in.time = self.input.second_data.time progressBar.setValue(5) QApplication.processEvents() with Serafin.Write( filename, self.input.first_data.language) as out_stream: out_stream.write_header(output_header) process = ProjectMeshThread(first_in, second_in, out_stream, output_header, self.input.is_inside, self.input.point_interpolators, time_indices, operation_type) progressBar.connectToThread(process) process.run() if not process.canceled: progressBar.outputFinished() progressBar.exec_() self.parent.outDialog()
def _initWidgets(self): # create a text for input information self.inputBox = QPlainTextEdit() self.inputBox.setFixedHeight(60) self.inputBox.setReadOnly(True) # 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.input.parent.logging_level) # create a combo box for output file type self.outTypeBox = QComboBox() self.outTypeBox.setFixedHeight(30) # create a text box for output file name self.outNameBox = QLineEdit() self.outNameBox.setReadOnly(True) self.outNameBox.setFixedHeight(30) # create the option panel self.stack = QStackedLayout() self.empty = QWidget() self.bkshp = QWidget() hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Attribute name')) self.bkshpname = QLineEdit('Value') self.bkshpname.setFixedHeight(30) hlayout.addWidget(self.bkshpname) self.bkshp.setLayout(hlayout) self.zfield = QWidget() hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Fill Z with')) self.zfieldchoice = QComboBox() self.zfieldchoice.setFixedHeight(30) hlayout.addWidget(self.zfieldchoice, Qt.AlignLeft) self.zfield.setLayout(hlayout) self.mfield = QWidget() hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Fill M with')) self.mfieldchoice = QComboBox() self.mfieldchoice.setFixedHeight(30) hlayout.addWidget(self.mfieldchoice, Qt.AlignLeft) self.mfield.setLayout(hlayout) self.shpbk = QWidget() hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Fill attribute with')) self.shpbkmethod = QComboBox() self.shpbkmethod.setFixedHeight(30) hlayout.addWidget(self.shpbkmethod, Qt.AlignLeft) self.shpbk.setLayout(hlayout) self.shpbkz = QWidget() vlayout = QVBoxLayout() hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Fill Z with')) self.zfieldchoicebis = QComboBox() self.zfieldchoicebis.setFixedHeight(30) hlayout.addWidget(self.zfieldchoicebis, Qt.AlignLeft) vlayout.addLayout(hlayout) hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Fill attribute with')) self.shpbkmethodbis = QComboBox() self.shpbkmethodbis.setFixedHeight(30) hlayout.addWidget(self.shpbkmethodbis, Qt.AlignLeft) vlayout.addLayout(hlayout) self.shpbkz.setLayout(vlayout) self.shpzm = QWidget() vlayout = QVBoxLayout() hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Fill Z with')) self.zfieldchoiceter = QComboBox() self.zfieldchoiceter.setFixedHeight(30) hlayout.addWidget(self.zfieldchoiceter, Qt.AlignLeft) vlayout.addLayout(hlayout) hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Fill M with')) self.mfieldchoicebis = QComboBox() self.mfieldchoicebis.setFixedHeight(30) hlayout.addWidget(self.mfieldchoicebis, Qt.AlignLeft) vlayout.addLayout(hlayout) self.shpzm.setLayout(vlayout) for panel in [ self.empty, self.bkshp, self.zfield, self.mfield, self.shpbk, self.shpbkz, self.shpzm ]: self.stack.addWidget(panel) self.stackbis = QStackedLayout() self.emptybis = QWidget() self.resample = QGroupBox('Re-sample lines by Maximum Length') self.resample.setCheckable(True) vlayout = QVBoxLayout() self.valueButton = QRadioButton('Use constant') self.valueBox = QLineEdit('1') self.choiceButton = QRadioButton('Use attribute') self.choiceBox = QComboBox() hlayout = QHBoxLayout() hlayout.addWidget(self.valueButton) hlayout.addWidget(self.valueBox) vlayout.addLayout(hlayout) hlayout = QHBoxLayout() hlayout.addWidget(self.choiceButton) hlayout.addWidget(self.choiceBox, Qt.AlignLeft) vlayout.addLayout(hlayout) self.resample.setLayout(vlayout) self.choiceBox.setVisible(False) self.valueBox.setVisible(False) self.resample.setChecked(False) self.valueButton.toggled.connect( lambda checked: self.valueBox.setVisible(checked)) self.choiceButton.toggled.connect( lambda checked: self.choiceBox.setVisible(checked)) self.valueButton.setChecked(True) self.stackbis.addWidget(self.emptybis) self.stackbis.addWidget(self.resample) self.stackbis.setCurrentIndex(1) # create the submit button self.btnSubmit = QPushButton('Submit', self, icon=self.style().standardIcon( QStyle.SP_DialogSaveButton)) self.btnSubmit.setToolTip('<b>Submit</b>') self.btnSubmit.setFixedSize(105, 50)
class FileConverterOutputTab(QWidget): def __init__(self, inputTab): super().__init__() self.input = inputTab self.EMPTY = 0 self.BK_SHP = 1 self.Z_FROM_SHP = 2 self.M_FROM_SHP = 3 self.SHP_BK = 4 self.Z_AND_BK = 5 self.Z_AND_M = 6 self.convert_type = { 'xyz': { 'xyz': self.EMPTY, 'shp PointZ': self.BK_SHP, 'csv': self.EMPTY }, 'i2s': { 'i2s': self.EMPTY, 'shp Polyline': self.BK_SHP, 'shp Polygon': self.BK_SHP, 'csv': self.EMPTY }, 'i3s': { 'i3s': self.EMPTY, 'i2s': self.EMPTY, 'shp PolylineZ': self.BK_SHP, 'shp PolygonZ': self.BK_SHP, 'csv': self.EMPTY }, 'shp Point': { 'shp Point': self.EMPTY, 'shp PointZ': self.Z_AND_M, 'xyz': self.Z_FROM_SHP, 'csv': self.EMPTY }, 'shp PointZ': { 'shp Point': self.EMPTY, 'shp PointZ': self.Z_AND_M, 'shp PointM': self.M_FROM_SHP, 'xyz': self.Z_FROM_SHP, 'csv': self.EMPTY }, 'shp PointM': { 'shp Point': self.EMPTY, 'shp PointM': self.M_FROM_SHP, 'shp PointZ': self.Z_AND_M, 'xyz': self.Z_FROM_SHP, 'csv': self.EMPTY }, 'shp Polyline': { 'shp Polyline': self.EMPTY, 'shp PolylineZ': self.Z_AND_M, 'i2s': self.SHP_BK, 'i3s': self.Z_AND_BK, 'csv': self.EMPTY }, 'shp Polygon': { 'shp Polygon': self.EMPTY, 'shp PolygonZ': self.Z_AND_M, 'i2s': self.SHP_BK, 'i3s': self.Z_AND_BK, 'csv': self.EMPTY }, 'shp PolylineZ': { 'shp PolylineZ': self.Z_AND_M, 'shp Polyline': self.EMPTY, 'i2s': self.SHP_BK, 'i3s': self.Z_AND_BK, 'csv': self.EMPTY }, 'shp PolygonZ': { 'shp PolygonZ': self.Z_AND_M, 'shp Polygon': self.EMPTY, 'i2s': self.SHP_BK, 'i3s': self.Z_AND_BK, 'csv': self.EMPTY }, 'shp PolylineM': { 'shp Polyline': self.EMPTY, 'shp PolylineM': self.M_FROM_SHP, 'shp PolylineZ': self.Z_AND_M, 'i2s': self.SHP_BK, 'i3s': self.Z_AND_BK, 'csv': self.EMPTY }, 'shp PolygonM': { 'shp Polygon': self.EMPTY, 'shp PolygonM': self.M_FROM_SHP, 'shp PolygonZ': self.Z_AND_M, 'i2s': self.SHP_BK, 'i3s': self.Z_AND_BK, 'csv': self.EMPTY }, 'shp Multipoint': { 'shp MultiPoint': self.EMPTY, 'shp Point': self.EMPTY, 'csv': self.EMPTY }, 'shp MultiPoint': { 'shp MultiPoint': self.EMPTY, 'shp Point': self.EMPTY, 'csv': self.EMPTY }, 'shp MultiPointZ': { 'shp MultiPointZ': self.EMPTY, 'shp PointZ': self.EMPTY, 'csv': self.EMPTY }, 'shp MultiPointM': { 'shp MultiPointM': self.EMPTY, 'shp PointM': self.EMPTY, 'csv': self.EMPTY } } self._initWidgets() self._setLayout() self._bindEvents() def _initWidgets(self): # create a text for input information self.inputBox = QPlainTextEdit() self.inputBox.setFixedHeight(60) self.inputBox.setReadOnly(True) # 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.input.parent.logging_level) # create a combo box for output file type self.outTypeBox = QComboBox() self.outTypeBox.setFixedHeight(30) # create a text box for output file name self.outNameBox = QLineEdit() self.outNameBox.setReadOnly(True) self.outNameBox.setFixedHeight(30) # create the option panel self.stack = QStackedLayout() self.empty = QWidget() self.bkshp = QWidget() hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Attribute name')) self.bkshpname = QLineEdit('Value') self.bkshpname.setFixedHeight(30) hlayout.addWidget(self.bkshpname) self.bkshp.setLayout(hlayout) self.zfield = QWidget() hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Fill Z with')) self.zfieldchoice = QComboBox() self.zfieldchoice.setFixedHeight(30) hlayout.addWidget(self.zfieldchoice, Qt.AlignLeft) self.zfield.setLayout(hlayout) self.mfield = QWidget() hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Fill M with')) self.mfieldchoice = QComboBox() self.mfieldchoice.setFixedHeight(30) hlayout.addWidget(self.mfieldchoice, Qt.AlignLeft) self.mfield.setLayout(hlayout) self.shpbk = QWidget() hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Fill attribute with')) self.shpbkmethod = QComboBox() self.shpbkmethod.setFixedHeight(30) hlayout.addWidget(self.shpbkmethod, Qt.AlignLeft) self.shpbk.setLayout(hlayout) self.shpbkz = QWidget() vlayout = QVBoxLayout() hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Fill Z with')) self.zfieldchoicebis = QComboBox() self.zfieldchoicebis.setFixedHeight(30) hlayout.addWidget(self.zfieldchoicebis, Qt.AlignLeft) vlayout.addLayout(hlayout) hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Fill attribute with')) self.shpbkmethodbis = QComboBox() self.shpbkmethodbis.setFixedHeight(30) hlayout.addWidget(self.shpbkmethodbis, Qt.AlignLeft) vlayout.addLayout(hlayout) self.shpbkz.setLayout(vlayout) self.shpzm = QWidget() vlayout = QVBoxLayout() hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Fill Z with')) self.zfieldchoiceter = QComboBox() self.zfieldchoiceter.setFixedHeight(30) hlayout.addWidget(self.zfieldchoiceter, Qt.AlignLeft) vlayout.addLayout(hlayout) hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Fill M with')) self.mfieldchoicebis = QComboBox() self.mfieldchoicebis.setFixedHeight(30) hlayout.addWidget(self.mfieldchoicebis, Qt.AlignLeft) vlayout.addLayout(hlayout) self.shpzm.setLayout(vlayout) for panel in [ self.empty, self.bkshp, self.zfield, self.mfield, self.shpbk, self.shpbkz, self.shpzm ]: self.stack.addWidget(panel) self.stackbis = QStackedLayout() self.emptybis = QWidget() self.resample = QGroupBox('Re-sample lines by Maximum Length') self.resample.setCheckable(True) vlayout = QVBoxLayout() self.valueButton = QRadioButton('Use constant') self.valueBox = QLineEdit('1') self.choiceButton = QRadioButton('Use attribute') self.choiceBox = QComboBox() hlayout = QHBoxLayout() hlayout.addWidget(self.valueButton) hlayout.addWidget(self.valueBox) vlayout.addLayout(hlayout) hlayout = QHBoxLayout() hlayout.addWidget(self.choiceButton) hlayout.addWidget(self.choiceBox, Qt.AlignLeft) vlayout.addLayout(hlayout) self.resample.setLayout(vlayout) self.choiceBox.setVisible(False) self.valueBox.setVisible(False) self.resample.setChecked(False) self.valueButton.toggled.connect( lambda checked: self.valueBox.setVisible(checked)) self.choiceButton.toggled.connect( lambda checked: self.choiceBox.setVisible(checked)) self.valueButton.setChecked(True) self.stackbis.addWidget(self.emptybis) self.stackbis.addWidget(self.resample) self.stackbis.setCurrentIndex(1) # create the submit button self.btnSubmit = QPushButton('Submit', self, icon=self.style().standardIcon( QStyle.SP_DialogSaveButton)) self.btnSubmit.setToolTip('<b>Submit</b>') self.btnSubmit.setFixedSize(105, 50) def _bindEvents(self): self.btnSubmit.clicked.connect(self.btnSubmitEvent) self.outTypeBox.currentIndexChanged.connect(self.changeOutType) def _setLayout(self): mainLayout = QVBoxLayout() mainLayout.addItem(QSpacerItem(50, 20)) mainLayout.addWidget(self.inputBox) mainLayout.addItem(QSpacerItem(50, 20)) hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Output file type')) hlayout.addWidget(self.outTypeBox, Qt.AlignLeft) mainLayout.addLayout(hlayout) mainLayout.addItem(QSpacerItem(50, 10)) mainLayout.addLayout(self.stack) mainLayout.addItem(QSpacerItem(50, 10)) mainLayout.addLayout(self.stackbis) mainLayout.addItem(QSpacerItem(50, 10)) hlayout = QHBoxLayout() hlayout.addWidget(self.btnSubmit) hlayout.addWidget(self.outNameBox) mainLayout.addLayout(hlayout) mainLayout.addItem(QSpacerItem(30, 15)) mainLayout.addWidget(QLabel(' Message logs')) mainLayout.addWidget(self.logTextBox.widget) self.setLayout(mainLayout) def reset(self): self.inputBox.clear() self.outTypeBox.clear() self.outNameBox.clear() self.bkshpname.setText('Value') self.zfieldchoice.clear() self.zfieldchoicebis.clear() self.zfieldchoiceter.clear() self.mfieldchoice.clear() self.mfieldchoicebis.clear() self.shpbkmethod.clear() self.shpbkmethod.addItem('0') self.shpbkmethod.addItem('Iteration') self.shpbkmethodbis.clear() self.shpbkmethodbis.addItem('0') self.shpbkmethodbis.addItem('Iteration') self.choiceBox.clear() def changeOutType(self, index): if self.outTypeBox.currentText(): self.stack.setCurrentIndex(self.convert_type[self.input.from_type][ self.outTypeBox.currentText()]) def _check_options(self): current_type = self.stack.currentIndex() if current_type == self.BK_SHP: attribute_name = self.bkshpname.text() if not attribute_name: QMessageBox.critical(None, 'Error', 'The attribute name cannot be empty!', QMessageBox.Ok) return False, [] options = [attribute_name] elif current_type == self.Z_FROM_SHP: options = [self.zfieldchoice.currentText()] elif current_type == self.M_FROM_SHP: options = [self.mfieldchoice.currentText()] elif current_type == self.SHP_BK: options = [self.shpbkmethod.currentText()] elif current_type == self.Z_AND_BK: options = [ self.zfieldchoicebis.currentText(), self.shpbkmethodbis.currentText() ] elif current_type == self.Z_AND_M: options = [ self.zfieldchoiceter.currentText(), self.mfieldchoicebis.currentText() ] else: options = [] if self.stackbis.currentIndex() == 1: if self.resample.isChecked(): if self.valueButton.isChecked(): value = self.valueBox.text() try: value = float(value) except ValueError: QMessageBox.critical( None, 'Error', 'Re-sampling Maximum Length must be a number!', QMessageBox.Ok) return False, [] if value <= 0: QMessageBox.critical( None, 'Error', 'Re-sampling Maximum Length must be a positive!', QMessageBox.Ok) return False, [] options.append('v|' + str(value)) else: attribute = self.choiceBox.currentText() if not attribute: QMessageBox.critical( None, 'Error', 'No numeric attribute available for re-sampling.', QMessageBox.Ok) return False, [] options.append('a|' + attribute) else: options.append('') return True, options def getInput(self): self.reset() from_type = self.input.from_type message = 'The input format is of type {}.\n'.format(from_type) is_line = False possible_types = self.convert_type[from_type].keys() if from_type == 'i2s' or from_type == 'i3s': is_line = True self.choiceBox.addItem('Attribute') nb_closed, nb_open = self.input.converter.nb_closed, self.input.converter.nb_open if nb_closed > 0 and nb_open > 0: possible_types = self.convert_type[from_type].keys() elif nb_closed == 0: if from_type == 'i2s': possible_types = ['i2s', 'shp Polyline', 'csv'] else: possible_types = ['i3s', 'i2s', 'shp PolylineZ', 'csv'] else: if from_type == 'i2s': possible_types = ['i2s', 'shp Polygon', 'csv'] else: possible_types = ['i3s', 'i2s', 'shp PolygonZ', 'csv'] message += 'It has {} polygon{} and {} open polyline{}.\n'.format( nb_closed, 's' if nb_closed > 1 else '', nb_open, 's' if nb_open > 1 else '') elif from_type == 'shp Point': numeric_fields = self.input.converter.numeric_fields if numeric_fields: self.mfieldchoicebis.addItem('0') for index, name in numeric_fields: item = '%d - %s' % (index, name) self.zfieldchoice.addItem(item) self.zfieldchoiceter.addItem(item) self.mfieldchoicebis.addItem(item) else: possible_types = ['shp Point', 'csv'] elif from_type == 'shp PointM': numeric_fields = self.input.converter.numeric_fields self.mfieldchoice.addItem('M') self.mfieldchoicebis.addItem('M') if numeric_fields: for index, name in numeric_fields: item = '%d - %s' % (index, name) self.zfieldchoice.addItem(item) self.zfieldchoiceter.addItem(item) self.mfieldchoice.addItem(item) self.mfieldchoicebis.addItem(item) else: possible_types = ['shp PointM', 'shp Point', 'csv'] elif from_type == 'shp PointZ': self.zfieldchoice.addItem('Z') self.zfieldchoiceter.addItem('Z') self.mfieldchoice.addItem('M') self.mfieldchoicebis.addItem('M') numeric_fields = self.input.converter.numeric_fields if numeric_fields: for index, name in numeric_fields: item = '%d - %s' % (index, name) self.zfieldchoice.addItem(item) self.zfieldchoiceter.addItem(item) self.mfieldchoice.addItem(item) self.mfieldchoicebis.addItem(item) elif from_type == 'shp Polyline' or from_type == 'shp Polygon': is_line = True numeric_fields = self.input.converter.numeric_fields if numeric_fields: self.mfieldchoicebis.addItem('0') for index, name in numeric_fields: item = '%d - %s' % (index, name) self.zfieldchoiceter.addItem(item) self.mfieldchoicebis.addItem(item) self.zfieldchoicebis.addItem(item) self.shpbkmethod.addItem(item) self.shpbkmethodbis.addItem(item) self.choiceBox.addItem(item) else: possible_types = [from_type, 'i2s', 'csv'] elif from_type == 'shp PolylineZ' or from_type == 'shp PolygonZ': is_line = True self.zfieldchoiceter.addItem('Z') self.zfieldchoicebis.addItem('Z') self.mfieldchoicebis.addItem('M') numeric_fields = self.input.converter.numeric_fields if numeric_fields: for index, name in numeric_fields: item = '%d - %s' % (index, name) self.zfieldchoiceter.addItem(item) self.zfieldchoicebis.addItem(item) self.mfieldchoicebis.addItem(item) self.shpbkmethod.addItem(item) self.shpbkmethodbis.addItem(item) self.choiceBox.addItem(item) elif from_type == 'shp PolylineM' or from_type == 'shp PolygonM': is_line = True numeric_fields = self.input.converter.numeric_fields self.mfieldchoice.addItem('M') self.mfieldchoicebis.addItem('M') if numeric_fields: for index, name in numeric_fields: item = '%d - %s' % (index, name) self.mfieldchoice.addItem(item) self.zfieldchoiceter.addItem(item) self.zfieldchoicebis.addItem(item) self.mfieldchoicebis.addItem(item) self.shpbkmethod.addItem(item) self.shpbkmethodbis.addItem(item) self.choiceBox.addItem(item) else: possible_types = [from_type, from_type[:-1], 'i2s', 'csv'] for to_type in possible_types: self.outTypeBox.addItem(to_type) if is_line: self.stackbis.setCurrentIndex(1) else: self.stackbis.setCurrentIndex(0) message += 'It can be converted to the following types: {}.'.format( ', '.join(list(possible_types))) self.inputBox.appendPlainText(message) def btnSubmitEvent(self): # check the transformations options valid, options = self._check_options() if not valid: return # getting the converter options right if self.input.transformation is not None: from_index, to_index = self.input.fromBox.currentIndex( ), self.input.toBox.currentIndex() trans = self.input.transformation.get_transformation( from_index, to_index) self.input.converter.set_transformations(trans) out_type = self.outTypeBox.currentText() if out_type[:3] == 'shp': out_type = 'shp' filename, _ = QFileDialog.getSaveFileName( self, 'Choose the output file name', '', '%s Files (*.%s)' % (out_type, out_type), options=QFileDialog.Options() | QFileDialog.DontUseNativeDialog) if not filename: return if len(filename) < 5 or filename[-3:] != out_type: filename += '.' + out_type if filename == self.input.converter.from_file: QMessageBox.critical(self, 'Error', 'Cannot overwrite to the input file.', QMessageBox.Ok) return try: with open(filename, 'w') as f: pass except PermissionError: QMessageBox.critical( self, 'Error', 'Permission denied (Is the file opened by another application?).', QMessageBox.Ok) return None self.outNameBox.setText(filename) logging.info('Start conversion from %s\nto %s' % (self.input.converter.from_file, filename)) QApplication.processEvents() try: self.input.converter.write(self.outTypeBox.currentText(), filename, options) except RuntimeError: QMessageBox.critical( self, 'Error', 'The attribute used for re-sampling contains non-positive number.', QMessageBox.Ok) logging.info('Failed.') return None logging.info('Done.') QMessageBox.information(self, 'Success', 'File conversion finished successfully!', QMessageBox.Ok)
class FileConverterInputTab(QWidget): def __init__(self, parent): super().__init__() self.parent = parent self.transformation = None self.converter = None self.from_type = None self.frenchButton = QCheckBox() self.englishButton = QCheckBox() for button in (self.frenchButton, self.englishButton): button.setVisible(False) self._initWidgets() self._setLayout() self._bindEvents() def _initWidgets(self): """! @brief (Used in __init__) Create widgets """ # create the group box for coordinate transformation self.confBox = QGroupBox('Apply coordinate transformation (optional)') self.confBox.setStyleSheet( 'QGroupBox {font-size: 12px;font-weight: bold;}') self.btnConfig = QPushButton('Load\nTransformation', self) self.btnConfig.setToolTip('<b>Open</b> a transformation config file') self.btnConfig.setFixedSize(105, 50) self.confNameBox = QLineEdit() self.confNameBox.setReadOnly(True) self.confNameBox.setFixedHeight(30) self.fromBox = QComboBox() self.fromBox.setFixedWidth(150) self.toBox = QComboBox() self.toBox.setFixedWidth(150) # create the open button self.btnOpen = QPushButton('Open', self, icon=self.style().standardIcon( QStyle.SP_DialogOpenButton)) self.btnOpen.setToolTip( '<b>Open</b> a geometry file (.shp .xyz .i2s .i3s)') self.btnOpen.setFixedSize(105, 50) # create some text fields displaying the IO files info self.inNameBox = QLineEdit() self.inNameBox.setReadOnly(True) self.inNameBox.setFixedHeight(30) # 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) def _setLayout(self): mainLayout = QVBoxLayout() mainLayout.addItem(QSpacerItem(10, 10)) mainLayout.setSpacing(15) vlayout = QVBoxLayout() hlayout = QHBoxLayout() hlayout.addWidget(self.btnConfig) hlayout.addWidget(self.confNameBox) vlayout.addLayout(hlayout) hlayout = QHBoxLayout() hlayout.addWidget(QLabel(' Transform from')) hlayout.addWidget(self.fromBox) hlayout.addWidget(QLabel('to')) hlayout.addWidget(self.toBox) hlayout.setAlignment(Qt.AlignLeft) vlayout.addLayout(hlayout) vlayout.setSpacing(15) self.confBox.setLayout(vlayout) mainLayout.addWidget(self.confBox) mainLayout.addItem(QSpacerItem(10, 15)) hlayout = QHBoxLayout() hlayout.addWidget(self.btnOpen) hlayout.addWidget(self.inNameBox) mainLayout.addLayout(hlayout) mainLayout.addItem(QSpacerItem(10, 10)) mainLayout.addItem(QSpacerItem(10, 15)) mainLayout.addWidget(QLabel(' Message logs')) mainLayout.addWidget(self.logTextBox.widget) self.setLayout(mainLayout) def _bindEvents(self): self.btnOpen.clicked.connect(self.btnOpenEvent) self.btnConfig.clicked.connect(self.btnConfigEvent) def _handleOpenShapefile(self, filename): try: with open(filename, 'r') as f: pass except PermissionError: QMessageBox.critical(None, 'Error', 'Permission denied.', QMessageBox.Ok) self.parent.reset() return False try: shape_type = shp.get_shape_type(filename) except shapefile.ShapefileException: QMessageBox.critical( None, 'Error', 'Failed to open shp file (is the .dbf file present?).', QMessageBox.Ok) self.parent.reset() return False if shape_type == 1: self.from_type = 'shp Point' elif shape_type == 11: self.from_type = 'shp PointZ' elif shape_type == 21: self.from_type = 'shp PointM' elif shape_type == 3: self.from_type = 'shp Polyline' elif shape_type == 13: self.from_type = 'shp PolylineZ' elif shape_type == 23: self.from_type = 'shp PolylineM' elif shape_type == 5: self.from_type = 'shp Polygon' elif shape_type == 15: self.from_type = 'shp PolygonZ' elif shape_type == 25: self.from_type = 'shp PolygonM' elif shape_type == 8: self.from_type = 'shp MultiPoint' elif shape_type == 18: self.from_type = 'shp MultiPointZ' elif shape_type == 28: self.from_type = 'shp MultiPointM' elif shape_type == 0: QMessageBox.critical( None, 'Error', 'The shape type Null is currently not supported!', QMessageBox.Ok) self.parent.reset() return False else: QMessageBox.critical( None, 'Error', 'The shape type MultiPatch is currently not supported!', QMessageBox.Ok) self.parent.reset() return False if shape_type in (1, 11, 21): self.converter = convert.ShpPointConverter(filename, shape_type) elif shape_type in (3, 5, 13, 15, 23, 25): self.converter = convert.ShpLineConverter(filename, shape_type) else: self.converter = convert.ShpMultiPointConverter( filename, shape_type) return True def btnConfigEvent(self): filename, _ = QFileDialog.getOpenFileName( self, 'Choose the file name', '', 'All files (*)', options=QFileDialog.Options() | QFileDialog.DontUseNativeDialog) if not filename: return self.fromBox.clear() self.toBox.clear() self.confNameBox.clear() self.transformation = None success, self.transformation = load_transformation_map(filename) if not success: QMessageBox.critical(self, 'Error', 'The configuration is not valid.', QMessageBox.Ok) return self.confNameBox.setText(filename) for label in self.transformation.labels: self.fromBox.addItem(label) self.toBox.addItem(label) def btnOpenEvent(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog filename, _ = QFileDialog.getOpenFileName( self, 'Open a geometry file', '', 'Geometry Files (*.shp *.xyz *.i2s *.i3s)', options=options) if not filename: return self.inNameBox.setText(filename) suffix = filename[-4:] if suffix == '.xyz': self.converter = convert.XYZConverter(filename) self.from_type = 'xyz' elif suffix == '.shp': if not self._handleOpenShapefile(filename): return elif suffix == '.i2s' or suffix == '.i3s': self.converter = convert.BKLineConverter(filename) self.from_type = suffix[1:] self.converter.set_csv_separator(self.parent.csv_separator) logging.info('Reading the input file...') QApplication.processEvents() try: self.converter.read() except PermissionError: QMessageBox.critical( None, 'Error', 'Permission denied (Is the file opened by another application?).', QMessageBox.Ok) self.parent.reset() return except ValueError: QMessageBox.critical(None, 'Error', 'The file is empty!', QMessageBox.Ok) self.parent.reset() return except RuntimeError: QMessageBox.critical( None, 'Error', 'Failed to read the shp file: Inconsistent bytes.', QMessageBox.Ok) self.parent.reset() return logging.info('Finished reading the input file: %s' % filename) self.parent.getInput() QMessageBox.information( self, 'Success', 'Finished reading the input file. The file converter is ready!', QMessageBox.Ok)
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()
class CSVTab(QWidget): def __init__(self, inputTab, parent): super().__init__() self.input = inputTab self.parent = parent self._initWidget() self._setLayout() self.btnSubmit.clicked.connect(self.btnSubmitEvent) def _initWidget(self): # create two 3-column tables for variables selection self.firstTable = VariableTable() self.secondTable = VariableTable() # create the options self.intersect = QCheckBox() self.intersect.setChecked(True) self.timeSelection = SimpleTimeDateSelection() self.referenceLine = QComboBox() # create the submit button self.btnSubmit = QPushButton('Submit\nto .csv', self, icon=self.style().standardIcon( QStyle.SP_DialogSaveButton)) self.btnSubmit.setToolTip('<b>Write</b> output to .csv') self.btnSubmit.setFixedSize(105, 50) self.btnSubmit.setEnabled(False) # create the output file name box self.csvNameBox = QLineEdit() self.csvNameBox.setReadOnly(True) self.csvNameBox.setFixedHeight(30) # 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) def _setLayout(self): mainLayout = QVBoxLayout() mainLayout.setSpacing(15) mainLayout.addItem(QSpacerItem(10, 10)) mainLayout.addWidget(self.timeSelection) hlayout = QHBoxLayout() hlayout.addWidget(QLabel(' Reference line')) hlayout.addWidget(self.referenceLine) hlayout.setAlignment(self.referenceLine, Qt.AlignLeft) hlayout.addStretch() mainLayout.addLayout(hlayout) mainLayout.addItem(QSpacerItem(10, 10)) glayout = QGridLayout() hlayout = QHBoxLayout() hlayout.addItem(QSpacerItem(30, 1)) vlayout = QVBoxLayout() lb = QLabel('Available variables') vlayout.addWidget(lb) vlayout.setAlignment(lb, Qt.AlignHCenter) vlayout.addWidget(self.firstTable) hlayout2 = QHBoxLayout() hlayout2.addItem(QSpacerItem(30, 1)) hlayout2.addWidget(self.intersect) hlayout2.addWidget(QLabel('Add intersection points')) hlayout2.setAlignment(self.intersect, Qt.AlignLeft) hlayout2.addStretch() vlayout.addLayout(hlayout2) 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)) glayout.addLayout(hlayout, 1, 1) glayout.setAlignment(Qt.AlignLeft) glayout.setSpacing(10) mainLayout.addLayout(glayout) mainLayout.addItem(QSpacerItem(30, 10)) hlayout = QHBoxLayout() hlayout.addItem(QSpacerItem(30, 1)) hlayout.addWidget(self.btnSubmit) hlayout.addWidget(self.csvNameBox) mainLayout.addLayout(hlayout) mainLayout.addItem(QSpacerItem(30, 15)) mainLayout.addWidget(QLabel(' Message logs')) mainLayout.addWidget(self.logTextBox.widget) self.setLayout(mainLayout) def getSelectedVariables(self): return self.secondTable.get_selected() def _initVarTables(self): self.firstTable.fill(self.input.data.header) def getInput(self): self._initVarTables() self.btnSubmit.setEnabled(True) self.csvNameBox.clear() if self.input.data.header.date is not None: year, month, day, hour, minute, second = self.input.data.header.date start_time = datetime.datetime(year, month, day, hour, minute, second) else: start_time = datetime.datetime(1900, 1, 1, 0, 0, 0) frames = list( map(lambda x: start_time + datetime.timedelta(seconds=x), self.input.data.time)) self.timeSelection.initTime(self.input.data.time, frames) for i in range(len(self.input.lines)): id_line = str(i + 1) if self.input.line_interpolators[i][0]: self.referenceLine.addItem('Line %s' % id_line) def reset(self): self.firstTable.setRowCount(0) self.secondTable.setRowCount(0) self.intersect.setChecked(False) self.btnSubmit.setEnabled(False) self.timeSelection.clearText() self.csvNameBox.clear() self.referenceLine.clear() self.intersect.setChecked(True) def btnSubmitEvent(self): selected_var_IDs = self.getSelectedVariables() if not selected_var_IDs: QMessageBox.critical( self, 'Error', 'Choose at least one output variable before submit!', QMessageBox.Ok) return canceled, filename = save_dialog('CSV') if canceled: return self.csvNameBox.setText(filename) logging.info('Writing the output to %s' % filename) self.parent.inDialog() indices_nonempty = [ i for i in range(len(self.input.lines)) if self.input.line_interpolators[i][0] ] reference = self.input.lines[ int(self.referenceLine.currentText().split()[1]) - 1] time_index = int(self.timeSelection.index.text()) - 1 # initialize the progress bar process = WriteCSVProcess(self.parent.csv_separator, self.parent.digits, self.input.mesh) progressBar = OutputProgressDialog() with Serafin.Read(self.input.data.filename, self.input.data.language) as input_stream: input_stream.header = self.input.data.header input_stream.time = self.input.data.time progressBar.setValue(1) QApplication.processEvents() with open(filename, 'w') as output_stream: progressBar.connectToThread(process) if self.intersect.isChecked(): process.write_csv(input_stream, selected_var_IDs, output_stream, self.input.line_interpolators, indices_nonempty, reference, time_index) else: process.write_csv(input_stream, selected_var_IDs, output_stream, self.input.line_interpolators_internal, indices_nonempty, reference, time_index) if not process.canceled: progressBar.outputFinished() progressBar.exec_() self.parent.outDialog() if process.canceled: self.csvNameBox.clear() return
class SubmitTab(QWidget): def __init__(self, inputTab, timeSelection, parent): super().__init__() self.inputTab = inputTab self.data = None self.timeSelection = timeSelection self.parent = parent # 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) # bind events self.btnSubmit.clicked.connect(self.btnSubmitEvent) # set layout mainLayout = QVBoxLayout() 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 reset(self): 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 # unlock convert to single precision if self.data.header.is_double_precision(): self.singlePrecisionBox.setEnabled(True) # unlock the submit button self.btnSubmit.setEnabled(True) def btnSubmitEvent(self): canceled, filename = save_dialog('Serafin', self.data.filename) if canceled: return # fetch the list of selected variables selected_vars = self.inputTab.getSelectedVariables() # deduce header from selected variable IDs and write header output_header = self.getOutputHeader(selected_vars) # fetch the list of selected frames if self.timeSelection.manualSelection.hasData: output_time_indices = self.timeSelection.getManualTime() output_message = 'Writing the output with variables %s for %d frame%s between frame %d and %d.' \ % (str(output_header.var_IDs), len(output_time_indices), ['', 's'][len(output_time_indices) > 1], output_time_indices[0]+1, output_time_indices[-1]+1) else: start_index, end_index, sampling_frequency, output_time_indices = self.timeSelection.getTime( ) output_message = 'Writing the output with variables %s between frame %d and %d with sampling frequency %d.' \ % (str(output_header.var_IDs), start_index, end_index, sampling_frequency) self.parent.inDialog() progressBar = OutputProgressDialog() # do some calculations with Serafin.Read(self.data.filename, self.data.language) as input_stream: # instead of re-reading the header and the time, just do a copy 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: logging.info(output_message) output_stream.write_header(output_header) # do some additional computations necessary_equations = get_necessary_equations( self.data.header.var_IDs, output_header.var_IDs, is_2d=output_header.is_2d, us_equation=self.data.us_equation) process = ExtractVariablesThread(necessary_equations, self.data.us_equation, input_stream, output_stream, output_header, output_time_indices) progressBar.connectToThread(process) process.run() if not process.canceled: progressBar.outputFinished() progressBar.exec_() self.parent.outDialog()