class collectDelegate(QItemDelegate): def __init__(self, parent, module): self.module = module QItemDelegate.__init__(self, parent) def createEditor (self, parent, option, index): column = index.column() row = index.row() self.index = index content = index.model().data(index, Qt.EditRole) if column == 2: content = index.model().data(index, Qt.EditRole) label = index.model().data(index.model().index(row,1), Qt.EditRole) checkrowIndex = index.model().index(row,0) checkrowIndex = index.model().data(index.model().index(row,0), Qt.CheckStateRole) self.editorQWidget = QComboBox(parent) self.editorQWidget.setEditable(True) self.editorQWidget.addItems(self.module.fieldMapping.values()) self.editorQWidget.addItems(['GEOMETRY','ODKUUID']) if content in self.module.fieldMapping.values(): self.editorQWidget.setCurrentIndex(self.editorQWidget.findData(content)) #self.module.fieldTable.item(row,0).setCheckState(Qt.Checked) else: #self.editorQWidget.insertItem(0,label) self.editorQWidget.insertItem(0,'') #self.module.fieldTable.item(row,0).setCheckState(Qt.Unchecked) self.editorQWidget.setCurrentIndex(0) return self.editorQWidget else: return None return QItemDelegate.createEditor(self, parent, option, index)
class AddressColumnConfigurationWidget(columnproviders.AbstractColumnConfigurationWidget, QWidget): def __init__(self, parent, hex_widget, column): columnproviders.AbstractColumnConfigurationWidget.__init__(self) QWidget.__init__(self, parent) self.hexWidget = hex_widget self.column = column self.setLayout(QFormLayout()) self.cmbBase = QComboBox(self) self.cmbBase.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.layout().addRow(utils.tr('Base:'), self.cmbBase) for base in ((utils.tr('Hex'), 16), (utils.tr('Dec'), 10), (utils.tr('Oct'), 8), (utils.tr('Bin'), 2)): self.cmbBase.addItem(base[0], base[1]) if column is not None: self.cmbBase.setCurrentIndex(self.cmbBase.findData(column.formatter.base)) self.cmbStyle = QComboBox(self) self.cmbStyle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.layout().addRow(utils.tr('Style:'), self.cmbStyle) for style_data in ((utils.tr('No style'), 'none'), (utils.tr('C'), 'c'), (utils.tr('Assembler'), 'asm')): self.cmbStyle.addItem(style_data[0], style_data[1]) if column is not None: self.cmbStyle.setCurrentIndex(self.cmbStyle.findData(column.formatter.styleName)) self.intBaseAddress = integeredit.IntegerEdit(self) self.intBaseAddress.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.layout().addRow(utils.tr('Base address:'), self.intBaseAddress) self.intBaseAddress.minimum = -10000000000000 if column is not None: self.intBaseAddress.number = column.baseAddress @property def _formatter(self): formatter = formatters.IntegerFormatter() formatter.base = self.cmbBase.itemData(self.cmbBase.currentIndex()) formatter.style = self.cmbStyle.itemData(self.cmbStyle.currentIndex()) return formatter def createColumnModel(self, hex_widget): return AddressColumnModel(None, self._formatter, self.intBaseAddress.number) def saveToColumn(self, column): column.formatter = self._formatter column.baseAddress = self.intBaseAddress.number column.reset()
def addAutoFieldToAutoFieldsTable( self, autoField, candidateLayer ): """ Add a whole row to the AutoFields table """ row = self.tblAutoFields.rowCount() self.tblAutoFields.insertRow( row ) layerName = self.ogrLayerName( autoField['layer'] ) item = QTableWidgetItem( layerName if layerName else autoField['layer'] ) item.setData( Qt.UserRole, autoField['layer'] ) item.setData( Qt.ToolTipRole, autoField['layer'] ) self.tblAutoFields.setItem( row, 0, item ) item = QTableWidgetItem( autoField['field'] ) self.tblAutoFields.setItem( row, 1, item ) item = QTableWidgetItem( autoField['expression'] ) self.tblAutoFields.setItem( row, 2, item ) layerCombo = QComboBox() layerCombo.addItem( '[Select a layer]', None ) for layer in self.layers: layerCombo.addItem( layer.name(), layer.id() ) if candidateLayer: layerCombo.setCurrentIndex( layerCombo.findData( candidateLayer.id() ) ) layerCombo.currentIndexChanged.connect( partial( self.layerOrFieldCombosChanged, row ) ) self.tblAutoFields.setCellWidget( row, 4, layerCombo ) fieldCombo = QComboBox() fieldCombo.addItem( '[Select a field]', None ) if layerCombo.currentIndex() != 0: for field in candidateLayer.fields(): fieldCombo.addItem( field.name() ) fieldIndex = fieldCombo.findText( autoField['field'] ) fieldCombo.setCurrentIndex( fieldIndex if fieldIndex != -1 else 0 ) fieldCombo.currentIndexChanged.connect( partial( self.layerOrFieldCombosChanged, None ) ) self.tblAutoFields.setCellWidget( row, 5, fieldCombo ) label = self.getLabelWithArrow( layerCombo.currentIndex(), fieldCombo.currentIndex(), candidateLayer, autoField['field'] ) self.tblAutoFields.setCellWidget( row, 3, label ) self.layerOrFieldCombosChanged( None, None ) # Validate initial load of AutoFields/Layers
class collectDelegate(QItemDelegate): def __init__(self, parent, module): self.module = module QItemDelegate.__init__(self, parent) def createEditor(self, parent, option, index): column = index.column() self.index = index content = index.model().data(index, Qt.EditRole) if column == 2: self.content = index.model().data(index, Qt.EditRole) self.editorQWidget = QComboBox(parent) self.editorQWidget.setEditable(True) self.editorQWidget.addItems(self.module.fieldMapping.values()) if self.content in self.module.fieldMapping.values(): self.editorQWidget.setCurrentIndex( self.editorQWidget.findData(self.content)) else: self.editorQWidget.insertItem(0, '') self.editorQWidget.setCurrentIndex(0) return self.editorQWidget else: return None return QItemDelegate.createEditor(self, parent, option, index)
class SchemeSelector(QWidget): currentChanged = pyqtSignal() changed = pyqtSignal() def __init__(self, parent=None): super(SchemeSelector, self).__init__(parent) layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.label = QLabel() self.scheme = QComboBox() self.menuButton = QPushButton(flat=True) menu = QMenu(self.menuButton) self.menuButton.setMenu(menu) layout.addWidget(self.label) layout.addWidget(self.scheme) layout.addWidget(self.menuButton) layout.addStretch(1) # action generator def act(slot, icon=None): a = QAction(self, triggered=slot) self.addAction(a) icon and a.setIcon(icons.get(icon)) return a # add action a = self.addAction_ = act(self.slotAdd, 'list-add') menu.addAction(a) # remove action a = self.removeAction = act(self.slotRemove, 'list-remove') menu.addAction(a) # rename action a = self.renameAction = act(self.slotRename, 'document-edit') menu.addAction(a) menu.addSeparator() # import action a = self.importAction = act(self.slotImport, 'document-open') menu.addAction(a) # export action a = self.exportAction = act(self.slotExport, 'document-save-as') menu.addAction(a) self.scheme.currentIndexChanged.connect(self.slotSchemeChanged) app.translateUI(self) def translateUI(self): self.label.setText(_("Scheme:")) self.menuButton.setText(_("&Menu")) self.addAction_.setText(_("&Add...")) self.removeAction.setText(_("&Remove")) self.renameAction.setText(_("Re&name...")) self.importAction.setText(_("&Import...")) self.exportAction.setText(_("&Export...")) def slotSchemeChanged(self, index): """Called when the Scheme combobox is changed by the user.""" self.disableDefault(self.scheme.itemData(index) == 'default') self.currentChanged.emit() self.changed.emit() def disableDefault(self, val): self.removeAction.setDisabled(val) self.renameAction.setDisabled(val) def schemes(self): """Returns the list with internal names of currently available schemes.""" return [self.scheme.itemData(i) for i in range(self.scheme.count())] def currentScheme(self): """Returns the internal name of the currently selected scheme""" return self.scheme.itemData(self.scheme.currentIndex()) def insertSchemeItem(self, name, scheme): for i in range(1, self.scheme.count()): n = self.scheme.itemText(i) if n.lower() > name.lower(): self.scheme.insertItem(i, name, scheme) break else: self.scheme.addItem(name, scheme) def addScheme(self, name): num, key = 1, 'user1' while key in self.schemes() or key in self._schemesToRemove: num += 1 key = 'user{0}'.format(num) self.insertSchemeItem(name, key) self.scheme.setCurrentIndex(self.scheme.findData(key)) return key def slotAdd(self): name, ok = QInputDialog.getText(self, app.caption(_("Add Scheme")), _("Please enter a name for the new scheme:")) if ok: self.addScheme(name) def slotRemove(self): index = self.scheme.currentIndex() scheme = self.scheme.itemData(index) if scheme == 'default': return # default can not be removed self._schemesToRemove.add(scheme) self.scheme.removeItem(index) def slotRename(self): index = self.scheme.currentIndex() name = self.scheme.itemText(index) scheme = self.scheme.itemData(index) newName, ok = QInputDialog.getText(self, _("Rename"), _("New name:"), text=name) if ok: self.scheme.blockSignals(True) self.scheme.removeItem(index) self.insertSchemeItem(newName, scheme) self.scheme.setCurrentIndex(self.scheme.findData(scheme)) self.scheme.blockSignals(False) self.changed.emit() def slotImport(self): filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files")) caption = app.caption(_("dialog title", "Import color theme")) filename = QFileDialog.getOpenFileName(self, caption, os.environ['HOME'], filetypes) if filename: self.parent().import_(filename) def slotExport(self): name = self.scheme.currentText() filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files")) caption = app.caption(_("dialog title", "Export {name}").format(name=name)) path = os.path.join(os.environ['HOME'], name+'.xml') filename = QFileDialog.getSaveFileName(self, caption, path, filetypes) if filename: if os.path.splitext(filename)[1] != '.xml': filename += '.xml' self.parent().export(name, filename) def loadSettings(self, currentKey, namesGroup): # dont mark schemes for removal anymore self._schemesToRemove = set() s = QSettings() cur = s.value(currentKey, "default", type("")) # load the names for the shortcut schemes s.beginGroup(namesGroup) self.scheme.clear() self.scheme.addItem(_("Default"), "default") lst = [(s.value(key, key, type("")), key) for key in s.childKeys()] for name, key in sorted(lst, key=lambda f: f[0].lower()): self.scheme.addItem(name, key) block = self.scheme.blockSignals(True) # find out index index = self.scheme.findData(cur) self.disableDefault(cur == 'default') self.scheme.setCurrentIndex(index) self.scheme.blockSignals(block) self.currentChanged.emit() def saveSettings(self, currentKey, namesGroup, removePrefix=None): # first save new scheme names s = QSettings() s.beginGroup(namesGroup) for i in range(self.scheme.count()): if self.scheme.itemData(i) != 'default': s.setValue(self.scheme.itemData(i), self.scheme.itemText(i)) for scheme in self._schemesToRemove: s.remove(scheme) s.endGroup() if removePrefix: for scheme in self._schemesToRemove: s.remove("{0}/{1}".format(removePrefix, scheme)) # then save current scheme = self.currentScheme() s.setValue(currentKey, scheme) # clean up self._schemesToRemove = set()
class AnalogIn(PluginBase): def __init__(self, *args): PluginBase.__init__(self, BrickletAnalogIn, *args) self.ai = self.device self.cbe_voltage = CallbackEmulator(self.ai.get_voltage, self.cb_voltage, self.increase_error_count) self.voltage_label = VoltageLabel('Voltage: ') self.current_value = None plot_list = [['', Qt.red, self.get_current_value]] self.plot_widget = PlotWidget('Voltage [mV]', plot_list) layout_h2 = QHBoxLayout() layout_h2.addStretch() layout_h2.addWidget(self.voltage_label) layout_h2.addStretch() layout = QVBoxLayout(self) layout.addLayout(layout_h2) layout.addWidget(self.plot_widget) if self.firmware_version >= (2, 0, 1): self.combo_range = QComboBox() self.combo_range.addItem('Automatic', BrickletAnalogIn.RANGE_AUTOMATIC) if self.firmware_version >= (2, 0, 3): self.combo_range.addItem('0V - 3.30V', BrickletAnalogIn.RANGE_UP_TO_3V) self.combo_range.addItem('0V - 6.05V', BrickletAnalogIn.RANGE_UP_TO_6V) self.combo_range.addItem('0V - 10.32V', BrickletAnalogIn.RANGE_UP_TO_10V) self.combo_range.addItem('0V - 36.30V', BrickletAnalogIn.RANGE_UP_TO_36V) self.combo_range.addItem('0V - 45.00V', BrickletAnalogIn.RANGE_UP_TO_45V) self.combo_range.currentIndexChanged.connect(self.range_changed) layout_h1 = QHBoxLayout() layout_h1.addStretch() layout_h1.addWidget(QLabel('Range:')) layout_h1.addWidget(self.combo_range) if self.firmware_version >= (2, 0, 3): self.spin_average = QSpinBox() self.spin_average.setMinimum(0) self.spin_average.setMaximum(255) self.spin_average.setSingleStep(1) self.spin_average.setValue(50) self.spin_average.editingFinished.connect(self.spin_average_finished) layout_h1.addStretch() layout_h1.addWidget(QLabel('Average Length:')) layout_h1.addWidget(self.spin_average) layout_h1.addStretch() layout.addLayout(layout_h1) def get_range_async(self, range_): self.combo_range.setCurrentIndex(self.combo_range.findData(range_)) def get_averaging_async(self, average): self.spin_average.setValue(average) def start(self): if self.firmware_version >= (2, 0, 1): async_call(self.ai.get_range, None, self.get_range_async, self.increase_error_count) if self.firmware_version >= (2, 0, 3): async_call(self.ai.get_averaging, None, self.get_averaging_async, self.increase_error_count) async_call(self.ai.get_voltage, None, self.cb_voltage, self.increase_error_count) self.cbe_voltage.set_period(100) self.plot_widget.stop = False def stop(self): self.cbe_voltage.set_period(0) self.plot_widget.stop = True def destroy(self): pass def get_url_part(self): return 'analog_in' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletAnalogIn.DEVICE_IDENTIFIER def get_current_value(self): return self.current_value def cb_voltage(self, voltage): self.current_value = voltage self.voltage_label.setText(str(voltage/1000.0)) def range_changed(self, index): if index >= 0 and self.firmware_version >= (2, 0, 1): range_ = self.combo_range.itemData(index) async_call(self.ai.set_range, range_, None, self.increase_error_count) def spin_average_finished(self): self.ai.set_averaging(self.spin_average.value())
class TimesDialog(QDialog): def __init__(self, parent, params): QDialog.__init__(self, parent) self.parent = parent self.params = params self.setMinimumWidth(min_width) # Build dialog self.setWindowTitle('Options - Times') # TODO: softcode self.setWindowModality(QtCore.Qt.ApplicationModal) self.fra_form = QFrame(self) fra_form_lay = QFormLayout(self.fra_form) fra_form_lay.setContentsMargins(10, 10, 10, 10) self.lbl_units = QLabel('Units:') # TODO: softocode self.cbo_units = QComboBox() fra_form_lay.addRow(self.lbl_units, self.cbo_units) self.lbl_duration = QLabel('Duration:') # TODO: softocode self.txt_duration = QLineEdit() fra_form_lay.addRow(self.lbl_duration, self.txt_duration) self.lbl_hydraulic_timestep = QLabel( 'Hydraulic timestep:') # TODO: softocode self.txt_hydraulic_timestep = QLineEdit() fra_form_lay.addRow(self.lbl_hydraulic_timestep, self.txt_hydraulic_timestep) self.lbl_quality_timestep = QLabel( 'Quality timestep:') # TODO: softocode self.txt_quality_timestep = QLineEdit() fra_form_lay.addRow(self.lbl_quality_timestep, self.txt_quality_timestep) self.lbl_rule_timestep = QLabel('Rule timestep:') # TODO: softocode self.txt_rule_timestep = QLineEdit() fra_form_lay.addRow(self.lbl_rule_timestep, self.txt_rule_timestep) self.lbl_pattern_timestep = QLabel( 'Pattern timestep:') # TODO: softocode self.txt_pattern_timestep = QLineEdit() fra_form_lay.addRow(self.lbl_pattern_timestep, self.txt_pattern_timestep) self.lbl_pattern_start = QLabel('Pattern start:') # TODO: softocode self.txt_pattern_start = QLineEdit() fra_form_lay.addRow(self.lbl_pattern_start, self.txt_pattern_start) self.lbl_report_timestep = QLabel( 'Report timestep:') # TODO: softocode self.txt_report_timestep = QLineEdit() fra_form_lay.addRow(self.lbl_report_timestep, self.txt_report_timestep) self.lbl_report_start = QLabel('Report start:') # TODO: softocode self.txt_report_start = QLineEdit() fra_form_lay.addRow(self.lbl_report_start, self.txt_report_start) self.lbl_clock_time_start = QLabel( 'Clock start time:') # TODO: softocode self.txt_clock_time_start = QLineEdit() fra_form_lay.addRow(self.lbl_clock_time_start, self.txt_clock_time_start) self.lbl_statistic = QLabel('Statistic:') # TODO: softocode self.cbo_statistic = QComboBox() fra_form_lay.addRow(self.lbl_statistic, self.cbo_statistic) # Buttons self.fra_buttons = QFrame(self) fra_buttons_lay = QHBoxLayout(self.fra_buttons) self.btn_Ok = QPushButton('OK') self.btn_Cancel = QPushButton('Cancel') fra_buttons_lay.addWidget(self.btn_Ok) fra_buttons_lay.addWidget(self.btn_Cancel) # Add to main fra_main_lay = QVBoxLayout(self) fra_main_lay.setContentsMargins(0, 0, 0, 0) fra_main_lay.addWidget(self.fra_form) fra_main_lay.addWidget(self.fra_buttons) self.setup() def setup(self): for key, text in self.params.times.unit_text.iteritems(): self.cbo_units.addItem(text, key) # Buttons self.btn_Cancel.clicked.connect(self.btn_cancel_clicked) self.btn_Ok.clicked.connect(self.btn_ok_clicked) # Validators self.txt_duration.setValidator(RegExValidators.get_pos_int()) self.txt_duration.setInputMask('0009:99') self.txt_duration.setValidator(RegExValidators.get_time_hs_mm()) self.txt_hydraulic_timestep.setInputMask('009:99') self.txt_hydraulic_timestep.setValidator( RegExValidators.get_time_hs_mm()) self.txt_quality_timestep.setInputMask('009:99') self.txt_quality_timestep.setValidator( RegExValidators.get_time_hs_mm()) self.txt_rule_timestep.setInputMask('009:99') self.txt_rule_timestep.setValidator(RegExValidators.get_time_hs_mm()) self.txt_pattern_timestep.setInputMask('009:99') self.txt_pattern_timestep.setValidator( RegExValidators.get_time_hs_mm()) self.txt_pattern_start.setInputMask('09:99') self.txt_pattern_start.setValidator(RegExValidators.get_time_hh_mm()) self.txt_report_timestep.setInputMask('009:99') self.txt_report_timestep.setValidator(RegExValidators.get_time_hs_mm()) self.txt_report_start.setInputMask('09:99') self.txt_report_start.setValidator(RegExValidators.get_time_hh_mm()) self.txt_clock_time_start.setInputMask('09:99') self.txt_clock_time_start.setValidator( RegExValidators.get_time_hh_mm()) for key, text in self.params.times.stats_text.iteritems(): self.cbo_statistic.addItem(text, key) def show(self): super(TimesDialog, self).show() self.cbo_units.setCurrentIndex( self.cbo_units.findData(self.params.times.units)) self.txt_duration.setText(self.params.times.duration.get_as_text(4)) self.txt_hydraulic_timestep.setText( self.params.times.hydraulic_timestep.get_as_text(3)) self.txt_quality_timestep.setText( self.params.times.quality_timestep.get_as_text(3)) self.txt_rule_timestep.setText( self.params.times.rule_timestep.get_as_text(3)) self.txt_pattern_timestep.setText( self.params.times.pattern_timestep.get_as_text(3)) self.txt_pattern_start.setText( self.params.times.pattern_start.get_as_text()) self.txt_report_timestep.setText( self.params.times.report_timestep.get_as_text(3)) self.txt_report_start.setText( self.params.times.report_start.get_as_text()) self.txt_clock_time_start.setText( self.params.times.clocktime_start.get_as_text()) self.cbo_statistic.setCurrentIndex( self.cbo_statistic.findData(self.params.times.statistic)) def btn_cancel_clicked(self): self.setVisible(False) def btn_ok_clicked(self): # Update parameters and options self.params.times.units = self.cbo_units.itemData( self.cbo_units.currentIndex()) self.params.times.duration = Hour.from_string(self.txt_duration.text()) self.params.times.hydraulic_timestep = Hour.from_string( self.txt_hydraulic_timestep.text()) self.params.times.quality_timestep = Hour.from_string( self.txt_quality_timestep.text()) self.params.times.rule_timestep = Hour.from_string( self.txt_rule_timestep.text()) self.params.times.pattern_timestep = Hour.from_string( self.txt_pattern_timestep.text()) self.params.times.pattern_start = Hour.from_string( self.txt_pattern_start.text()) self.params.times.report_timestep = Hour.from_string( self.txt_report_timestep.text()) self.params.times.report_start = Hour.from_string( self.txt_report_start.text()) self.params.times.clocktime_start = Hour.from_string( self.txt_clock_time_start.text()) self.params.times.statistic = self.cbo_statistic.currentIndex() self.setVisible(False)
class HydraulicsDialog(QDialog): def __init__(self, parent, params, new_proj=False): QDialog.__init__(self, parent) self.parent = parent self.params = params self.new_proj = new_proj self.setMinimumWidth(min_width) # self.setMinimumHeight(min_height) # Build dialog self.setWindowTitle('Options - Hydraulics') # TODO: softcode self.setWindowModality(QtCore.Qt.ApplicationModal) self.fra_form = QFrame(self) fra_form_lay = QFormLayout(self.fra_form) fra_form_lay.setContentsMargins(10, 10, 10, 10) self.lbl_units = QLabel('Units system:') # TODO: softocode self.cbo_units = QComboBox() fra_form_lay.addRow(self.lbl_units, self.cbo_units) self.lbl_flow_units = QLabel('Flow units:') # TODO: softocode self.cbo_flow_units = QComboBox() fra_form_lay.addRow(self.lbl_flow_units, self.cbo_flow_units) self.lbl_headloss = QLabel('Head loss:') # TODO: softocode self.cbo_headloss = QComboBox() fra_form_lay.addRow(self.lbl_headloss, self.cbo_headloss) self.chk_hydraulics = QCheckBox('Hydraulics:') # TODO: softcode self.cbo_hydraulics = QComboBox() fra_form_lay.addRow(self.chk_hydraulics, self.cbo_hydraulics) self.txt_hydraulics_file = QLineEdit() fra_form_lay.addRow(None, self.txt_hydraulics_file) self.btn_hydraulics_file = QPushButton('File...') # TODO: softcode fra_form_lay.addRow(None, self.btn_hydraulics_file) self.lbl_viscosity = QLabel('Viscosity:') # TODO: softocode self.txt_viscosity = QLineEdit() fra_form_lay.addRow(self.lbl_viscosity, self.txt_viscosity) self.lbl_diffusivity = QLabel('Diffusivity:') # TODO: softocode self.txt_diffusivity = QLineEdit() fra_form_lay.addRow(self.lbl_diffusivity, self.txt_diffusivity) self.lbl_spec_gravity = QLabel('Specific gravity:') # TODO: softocode self.txt_spec_gravity = QLineEdit() fra_form_lay.addRow(self.lbl_spec_gravity, self.txt_spec_gravity) self.lbl_max_trials = QLabel('Max trials:') # TODO: softocode self.txt_max_trials = QLineEdit() fra_form_lay.addRow(self.lbl_max_trials, self.txt_max_trials) self.lbl_accuracy = QLabel('Accuracy:') # TODO: softocode self.txt_accuracy = QLineEdit() fra_form_lay.addRow(self.lbl_accuracy, self.txt_accuracy) self.lbl_unbalanced = QLabel('Unbalanced:') # TODO: softcode self.fra_unbalanced = QFrame(self) fra_unbalanced_lay = QHBoxLayout(self.fra_unbalanced) fra_unbalanced_lay.setContentsMargins(0, 0, 0, 0) self.cbo_unbalanced = QComboBox() self.txt_unbalanced = QLineEdit() fra_unbalanced_lay.addWidget(self.cbo_unbalanced) fra_unbalanced_lay.addWidget(self.txt_unbalanced) fra_form_lay.addRow(self.lbl_unbalanced, self.fra_unbalanced) self.lbl_pattern = QLabel('Pattern:') # TODO: softocode self.cbo_pattern = QComboBox() fra_form_lay.addRow(self.lbl_pattern, self.cbo_pattern) self.lbl_demand_mult = QLabel('Demand multiplier:') # TODO: softocode self.txt_demand_mult = QLineEdit() fra_form_lay.addRow(self.lbl_demand_mult, self.txt_demand_mult) self.lbl_emitter_exp = QLabel('Emitter exponent:') # TODO: softocode self.txt_emitter_exp = QLineEdit() fra_form_lay.addRow(self.lbl_emitter_exp, self.txt_emitter_exp) self.lbl_tolerance = QLabel('Tolerance:') # TODO: softocode self.txt_tolerance = QLineEdit() fra_form_lay.addRow(self.lbl_tolerance, self.txt_tolerance) # Buttons self.fra_buttons = QFrame(self) fra_buttons_lay = QHBoxLayout(self.fra_buttons) self.btn_Cancel = QPushButton('Cancel') self.btn_Ok = QPushButton('OK') fra_buttons_lay.addWidget(self.btn_Ok) fra_buttons_lay.addWidget(self.btn_Cancel) # Add to main fra_main_lay = QVBoxLayout(self) fra_main_lay.setContentsMargins(0, 0, 0, 0) fra_main_lay.addWidget(self.fra_form) fra_main_lay.addWidget(self.fra_buttons) self.setup() def setup(self): # Fill units system combo box for unit in self.params.options.units_sys: self.cbo_units.addItem(self.params.options.units_sys_text[unit], unit) # Fill flow units combo box for fu in Options.units_flow[self.params.options.units]: self.cbo_flow_units.addItem(Options.units_flow_text[fu], fu) self.cbo_units.activated.connect(self.cbo_units_activated) # self.cbo_flow_units.activated.connect(self.cbo_flow_units_activated) for key, value in self.params.options.headlosses_text.iteritems(): self.cbo_headloss.addItem(value, key) self.cbo_headloss.activated.connect(self.cbo_headloss_activated) self.chk_hydraulics.stateChanged.connect(self.chk_hydraulics_changed) self.btn_hydraulics_file.clicked.connect(self.btn_hydraulics_clicked) self.cbo_hydraulics.addItem( self.params.options.hydraulics.action_names[ self.params.options.hydraulics.action_use], self.params.options.hydraulics.action_use) self.cbo_hydraulics.addItem( self.params.options.hydraulics.action_names[ self.params.options.hydraulics.action_save], self.params.options.hydraulics.action_save) self.txt_hydraulics_file.setReadOnly(True) # - Unbalanced for id, text in self.params.options.unbalanced.unb_text.iteritems(): self.cbo_unbalanced.addItem(text, id) self.cbo_unbalanced.activated.connect(self.cbo_unbalanced_changed) self.txt_unbalanced.setValidator(RegExValidators.get_pos_int_no_zero()) self.txt_unbalanced.setText('1') # - Pattern self.cbo_pattern.addItem('None (=1.0)', None) for pattern_id, pattern in self.params.patterns.iteritems(): self.cbo_pattern.addItem(pattern_id, pattern) # Buttons self.btn_Cancel.clicked.connect(self.btn_cancel_clicked) self.btn_Ok.clicked.connect(self.btn_ok_clicked) # Validators self.txt_viscosity.setValidator(RegExValidators.get_pos_decimals()) self.txt_diffusivity.setValidator(RegExValidators.get_pos_decimals()) self.txt_spec_gravity.setValidator(RegExValidators.get_pos_decimals()) self.txt_max_trials.setValidator(RegExValidators.get_pos_int_no_zero()) self.txt_accuracy.setValidator(RegExValidators.get_pos_decimals()) self.txt_demand_mult.setValidator(RegExValidators.get_pos_decimals()) self.txt_emitter_exp.setValidator(RegExValidators.get_pos_decimals()) self.txt_tolerance.setValidator(RegExValidators.get_pos_decimals()) def show(self): super(HydraulicsDialog, self).show() self.cbo_units.setCurrentIndex( self.cbo_units.findData(self.params.options.units)) self.cbo_flow_units.setCurrentIndex( self.cbo_flow_units.findData(self.params.options.flow_units)) self.cbo_headloss.setCurrentIndex( self.cbo_headloss.findData(self.params.options.headloss)) self.chk_hydraulics.setChecked( self.params.options.hydraulics.use_hydraulics) self.btn_hydraulics_file.setEnabled(self.chk_hydraulics.isChecked()) self.cbo_hydraulics.setEnabled(self.chk_hydraulics.isChecked()) self.txt_hydraulics_file.setEnabled(self.chk_hydraulics.isChecked()) if self.params.options.hydraulics.action is not None: self.cbo_hydraulics.setCurrentIndex( self.cbo_hydraulics.findData( self.params.options.hydraulics.action)) if self.params.options.hydraulics.file is not None: self.txt_hydraulics_file.setText( self.params.options.hydraulics.file) self.txt_viscosity.setText(str(self.params.options.viscosity)) self.txt_diffusivity.setText(str(self.params.options.diffusivity)) self.txt_spec_gravity.setText(str(self.params.options.spec_gravity)) self.txt_max_trials.setText(str(self.params.options.trials)) self.txt_accuracy.setText(str(self.params.options.accuracy)) self.cbo_unbalanced.setCurrentIndex( self.cbo_unbalanced.findData( self.params.options.unbalanced.unbalanced)) self.txt_unbalanced.setEnabled(self.cbo_unbalanced.currentIndex() != 0) self.txt_unbalanced.setText(str(self.params.options.unbalanced.trials)) # Patterns if self.params.options.pattern is not None: if self.params.options.pattern is None: self.cbo_pattern.setCurrentIndex(0) else: for i in range(self.cbo_pattern.count()): if self.params.options.pattern.id == self.cbo_pattern.itemText( i): self.cbo_pattern.setCurrentIndex(i) break self.txt_demand_mult.setText(str(self.params.options.demand_mult)) self.txt_emitter_exp.setText(str(self.params.options.emitter_exp)) self.txt_tolerance.setText(str(self.params.options.tolerance)) def cbo_units_activated(self): self.params.options.units = self.cbo_units.itemData( self.cbo_units.currentIndex()) # Parameters combo box self.cbo_flow_units.clear() for fu in Options.units_flow[self.params.options.units]: self.cbo_flow_units.addItem(Options.units_flow_text[fu], fu) def cbo_headloss_activated(self): # Warning if not self.new_proj: QMessageBox.warning( self, Parameters.plug_in_name, u'Head loss units changed: the head loss values already present might need to be reviewed.', QMessageBox.Ok) def chk_hydraulics_changed(self): self.btn_hydraulics_file.setEnabled(self.chk_hydraulics.isChecked()) self.cbo_hydraulics.setEnabled(self.chk_hydraulics.isChecked()) self.txt_hydraulics_file.setEnabled(self.chk_hydraulics.isChecked()) def btn_hydraulics_clicked(self): file_dialog = QFileDialog(self, 'Select hydraulics file') file_dialog.setLabelText(QFileDialog.Accept, 'Select') file_dialog.setLabelText(QFileDialog.Reject, 'Cancel') file_dialog.setFileMode(QFileDialog.AnyFile) file_dialog.exec_() hydraulics_file_path = file_dialog.selectedFiles() if not hydraulics_file_path or hydraulics_file_path[ 0] is None or hydraulics_file_path[0] == '': return self.txt_hydraulics_file.setText(hydraulics_file_path[0]) def cbo_unbalanced_changed(self): self.txt_unbalanced.setEnabled( self.cbo_unbalanced.itemData(self.cbo_unbalanced.currentIndex()) == self.params.options.unbalanced.unb_continue) def btn_cancel_clicked(self): self.setVisible(False) def btn_ok_clicked(self): if not self.check_params(): return # Update parameters and options self.params.options.units = self.cbo_units.itemData( self.cbo_units.currentIndex()) self.params.options.flow_units = self.cbo_flow_units.itemData( self.cbo_flow_units.currentIndex()) self.params.options.headloss = self.cbo_headloss.itemData( self.cbo_headloss.currentIndex()) self.params.options.hydraulics.use_hydraulics = self.chk_hydraulics.isChecked( ) if self.params.options.hydraulics.action is not None: self.params.options.hydraulics.action = self.cbo_hydraulics.itemData( self.cbo_hydraulics.currentIndex()) self.params.options.hydraulics.file = self.txt_hydraulics_file.text( ) self.params.options.viscosity = float(self.txt_viscosity.text()) self.params.options.diffusivity = float(self.txt_diffusivity.text()) self.params.options.spec_gravity = float(self.txt_spec_gravity.text()) self.params.options.trials = float(self.txt_max_trials.text()) self.params.options.accuracy = float(self.txt_accuracy.text()) self.params.options.unbalanced.unbalanced = self.cbo_unbalanced.itemData( self.cbo_unbalanced.currentIndex()) self.params.options.unbalanced.trials = int(self.txt_unbalanced.text()) self.params.options.pattern = self.cbo_pattern.itemData( self.cbo_pattern.currentIndex()) self.params.options.demand_mult = float(self.txt_demand_mult.text()) self.params.options.emitter_exp = float(self.txt_emitter_exp.text()) self.params.options.tolerance = float(self.txt_tolerance.text()) # Junctions self.parent.lbl_junction_demand.setText( pre_l('Demand', Options.units_flow[self.params.options.units] [0])) # TODO: softcode self.parent.lbl_junction_deltaz.setText( pre_l('Delta Z', Options.units_deltaz[ self.params.options.units])) # TODO: softcode # Reservoirs self.parent.lbl_reservoir_deltaz.setText( pre_l('Delta Z', Options.units_deltaz[ self.params.options.units])) # TODO: softcode self.parent.lbl_reservoir_pressure_head.setText( pre_l('Pressure head', Options.units_deltaz[ self.params.options.units])) # TODO: softcode # Tanks self.parent.lbl_tank_deltaz.setText( pre_l('Delta Z', Options.units_deltaz[ self.params.options.units])) # TODO: softcode self.parent.lbl_tank_level_init.setText( pre_l('Level init.', Options.units_deltaz[ self.params.options.units])) # TODO: softcode self.parent.lbl_tank_level_min.setText( pre_l('Level min', Options.units_deltaz[ self.params.options.units])) # TODO: softcode self.parent.lbl_tank_level_max.setText( pre_l('Level max', Options.units_deltaz[ self.params.options.units])) # TODO: softcode self.parent.lbl_tank_diameter.setText( pre_l('Diameter', Options.units_diameter_tanks[ self.params.options.units])) # TODO: softcode self.parent.lbl_tank_vol_min.setText( pre_l('Volume min', Options.units_volume[ self.params.options.units])) # TODO: softcode # Pipes self.parent.lbl_pipe_demand.setText( pre_l('Demand', Options.units_flow[self.params.options.units] [0])) # TODO: softcode self.parent.lbl_pipe_diameter.setText( pre_l('Diameter', Options.units_diameter_pipes[ self.params.options.units])) # TODO: softcode self.parent.lbl_pipe_roughness_val.setText( pre_l( 'Value', Options.units_roughness[self.params.options.units][ self.params.options.headloss])) # TODO: softcode self.params.options.headloss_units = self.cbo_headloss.itemData( self.cbo_headloss.currentIndex()) self.parent.update_roughness_params( self.parent.cbo_pipe_roughness.itemData( self.parent.cbo_pipe_roughness.currentIndex())[ self.params.options.headloss]) # self.parent.lbl_pipe_roughness.setText( # pre_l( # 'Roughness', # self.params.options.units_roughness[self.params.options.units][self.params.options.headloss_units])) # Pumps self.parent.lbl_pump_head.setText( pre_l('Head', self.params.options.units_deltaz[self.params.options.units])) self.parent.lbl_pump_power.setText( pre_l('Power', self.params.options.units_power[self.params.options.units])) # Valves valve_type = self.parent.cbo_valve_type.itemData( self.parent.cbo_valve_type.currentIndex()) # Pressure valves if valve_type == Valve.type_psv or valve_type == Valve.type_prv or valve_type == Valve.type_pbv: self.parent.lbl_valve_setting.setText( pre_l( 'Pressure', self.params.options.units_pressure[ self.params.options.units])) # FCV valve: Flow if valve_type == Valve.type_fcv: self.parent.lbl_valve_setting.setText( pre_l('Flow', self.params.options.flow_units)) # Throttle control valve elif valve_type == Valve.type_tcv: self.parent.lbl_valve_setting.setText(pre_l('Loss coeff.', '-')) # self.parent.lbl_valve_diameter.setText(pre_l('Pressure', self.params.options.units_diameter_pipes[self.params.options.units])) # Flow units units = self.cbo_flow_units.itemData( self.cbo_flow_units.currentIndex()) self.parent.lbl_junction_demand.setText(pre_l('Demand', units)) # TODO: softcode self.parent.lbl_pipe_demand.setText(pre_l('Demand', units)) # TODO: softcode self.setVisible(False) def check_params(self): if self.chk_hydraulics.isChecked(): if not os.path.isfile(self.txt_hydraulics_file.text()): QMessageBox.warning( self, Parameters.plug_in_name, u'Hydraulics option slected, but no valid file specified.', QMessageBox.Ok) return False return True
class SchemeSelector(QWidget): currentChanged = pyqtSignal() changed = pyqtSignal() def __init__(self, parent=None): super(SchemeSelector, self).__init__(parent) layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.label = QLabel() self.scheme = QComboBox() self.menuButton = QPushButton(flat=True) menu = QMenu(self.menuButton) self.menuButton.setMenu(menu) layout.addWidget(self.label) layout.addWidget(self.scheme) layout.addWidget(self.menuButton) layout.addStretch(1) # action generator def act(slot, icon=None): a = QAction(self, triggered=slot) self.addAction(a) icon and a.setIcon(icons.get(icon)) return a # add action a = self.addAction_ = act(self.slotAdd, 'list-add') menu.addAction(a) # remove action a = self.removeAction = act(self.slotRemove, 'list-remove') menu.addAction(a) # rename action a = self.renameAction = act(self.slotRename, 'document-edit') menu.addAction(a) menu.addSeparator() # import action a = self.importAction = act(self.slotImport, 'document-open') menu.addAction(a) # export action a = self.exportAction = act(self.slotExport, 'document-save-as') menu.addAction(a) self.scheme.currentIndexChanged.connect(self.slotSchemeChanged) app.translateUI(self) def translateUI(self): self.label.setText(_("Scheme:")) self.menuButton.setText(_("&Menu")) self.addAction_.setText(_("&Add...")) self.removeAction.setText(_("&Remove")) self.renameAction.setText(_("Re&name...")) self.importAction.setText(_("&Import...")) self.exportAction.setText(_("&Export...")) def slotSchemeChanged(self, index): """Called when the Scheme combobox is changed by the user.""" self.disableDefault(self.scheme.itemData(index) == 'default') self.currentChanged.emit() self.changed.emit() def disableDefault(self, val): self.removeAction.setDisabled(val) self.renameAction.setDisabled(val) def schemes(self): """Returns the list with internal names of currently available schemes.""" return [self.scheme.itemData(i) for i in range(self.scheme.count())] def currentScheme(self): """Returns the internal name of the currently selected scheme""" return self.scheme.itemData(self.scheme.currentIndex()) def insertSchemeItem(self, name, scheme): for i in range(1, self.scheme.count()): n = self.scheme.itemText(i) if n.lower() > name.lower(): self.scheme.insertItem(i, name, scheme) break else: self.scheme.addItem(name, scheme) def addScheme(self, name): num, key = 1, 'user1' while key in self.schemes() or key in self._schemesToRemove: num += 1 key = 'user{0}'.format(num) self.insertSchemeItem(name, key) self.scheme.setCurrentIndex(self.scheme.findData(key)) return key def slotAdd(self): name, ok = QInputDialog.getText( self, app.caption(_("Add Scheme")), _("Please enter a name for the new scheme:")) if ok: self.addScheme(name) def slotRemove(self): index = self.scheme.currentIndex() scheme = self.scheme.itemData(index) if scheme == 'default': return # default can not be removed self._schemesToRemove.add(scheme) self.scheme.removeItem(index) def slotRename(self): index = self.scheme.currentIndex() name = self.scheme.itemText(index) scheme = self.scheme.itemData(index) newName, ok = QInputDialog.getText(self, _("Rename"), _("New name:"), text=name) if ok: self.scheme.blockSignals(True) self.scheme.removeItem(index) self.insertSchemeItem(newName, scheme) self.scheme.setCurrentIndex(self.scheme.findData(scheme)) self.scheme.blockSignals(False) self.changed.emit() def slotImport(self): filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files")) caption = app.caption(_("dialog title", "Import color theme")) filename = QFileDialog.getOpenFileName(self, caption, QDir.homePath(), filetypes) if filename: self.parent().import_(filename) def slotExport(self): name = self.scheme.currentText() filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files")) caption = app.caption( _("dialog title", "Export {name}").format(name=name)) path = os.path.join(QDir.homePath(), name + '.xml') filename = QFileDialog.getSaveFileName(self, caption, path, filetypes) if filename: if os.path.splitext(filename)[1] != '.xml': filename += '.xml' self.parent().export(name, filename) def loadSettings(self, currentKey, namesGroup): # don't mark schemes for removal anymore self._schemesToRemove = set() s = QSettings() cur = s.value(currentKey, "default", type("")) # load the names for the shortcut schemes s.beginGroup(namesGroup) block = self.scheme.blockSignals(True) self.scheme.clear() self.scheme.addItem(_("Default"), "default") lst = [(s.value(key, key, type("")), key) for key in s.childKeys()] for name, key in sorted(lst, key=lambda f: f[0].lower()): self.scheme.addItem(name, key) # find out index index = self.scheme.findData(cur) self.disableDefault(cur == 'default') self.scheme.setCurrentIndex(index) self.scheme.blockSignals(block) self.currentChanged.emit() def saveSettings(self, currentKey, namesGroup, removePrefix=None): # first save new scheme names s = QSettings() s.beginGroup(namesGroup) for i in range(self.scheme.count()): if self.scheme.itemData(i) != 'default': s.setValue(self.scheme.itemData(i), self.scheme.itemText(i)) for scheme in self._schemesToRemove: s.remove(scheme) s.endGroup() if removePrefix: for scheme in self._schemesToRemove: s.remove("{0}/{1}".format(removePrefix, scheme)) # then save current scheme = self.currentScheme() s.setValue(currentKey, scheme) # clean up self._schemesToRemove = set()
class UVLightV2(COMCUPluginBase): def __init__(self, *args): COMCUPluginBase.__init__(self, BrickletUVLightV2, *args) self.uv_light = self.device self.cbe_uva = CallbackEmulator(self.uv_light.get_uva, self.cb_uva, self.increase_error_count) self.cbe_uvb = CallbackEmulator(self.uv_light.get_uvb, self.cb_uvb, self.increase_error_count) self.cbe_uvi = CallbackEmulator(self.uv_light.get_uvi, self.cb_uvi, self.increase_error_count) self.index_label = IndexLabel(' UVI: ? ') self.index_label.setText('0.0') self.current_uva = None self.current_uvb = None self.current_uvi = None plots = [('UVA', Qt.red, lambda: self.current_uva, u'{} mW/m²'.format), ('UVB', Qt.darkGreen, lambda: self.current_uvb, u'{} mW/m²'.format)] self.plot_widget = PlotWidget(u'UV [mW/m²]', plots, extra_key_widgets=[self.index_label]) self.time_label = QLabel('Integration Time:') self.time_combo = QComboBox() self.time_combo.addItem("50 ms", BrickletUVLightV2.INTEGRATION_TIME_50MS) self.time_combo.addItem("100 ms", BrickletUVLightV2.INTEGRATION_TIME_100MS) self.time_combo.addItem("200 ms", BrickletUVLightV2.INTEGRATION_TIME_200MS) self.time_combo.addItem("400 ms", BrickletUVLightV2.INTEGRATION_TIME_400MS) self.time_combo.addItem("800 ms", BrickletUVLightV2.INTEGRATION_TIME_800MS) self.time_combo.currentIndexChanged.connect(self.new_config) self.saturation_label = QLabel( 'Sensor is saturated, choose a shorter integration time!') self.saturation_label.setStyleSheet('QLabel { color : red }') self.saturation_label.hide() hlayout = QHBoxLayout() hlayout.addWidget(self.time_label) hlayout.addWidget(self.time_combo) hlayout.addStretch() hlayout.addWidget(self.saturation_label) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout = QVBoxLayout(self) layout.addWidget(self.plot_widget) layout.addWidget(line) layout.addLayout(hlayout) def start(self): async_call(self.uv_light.get_configuration, None, self.get_configucation_async, self.increase_error_count) async_call(self.uv_light.get_uva, None, self.cb_uva, self.increase_error_count) self.cbe_uva.set_period(100) async_call(self.uv_light.get_uvb, None, self.cb_uvb, self.increase_error_count) self.cbe_uvb.set_period(100) async_call(self.uv_light.get_uvi, None, self.cb_uvi, self.increase_error_count) self.cbe_uvi.set_period(100) self.plot_widget.stop = False def stop(self): self.cbe_uva.set_period(0) self.cbe_uvb.set_period(0) self.cbe_uvi.set_period(0) self.plot_widget.stop = True def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletUVLightV2.DEVICE_IDENTIFIER def get_configucation_async(self, integration_time): self.time_combo.setCurrentIndex( self.time_combo.findData(integration_time)) def new_config(self, value): try: self.uv_light.set_configuration( self.time_combo.itemData(self.time_combo.currentIndex())) except: pass def cb_uva(self, uva): self.saturation_label.setVisible(uva < 0) if uva < 0: # saturated return self.current_uva = uva / 10.0 def cb_uvb(self, uvb): self.saturation_label.setVisible(uvb < 0) if uvb < 0: # saturated return self.current_uvb = uvb / 10.0 def cb_uvi(self, uvi): self.saturation_label.setVisible(uvi < 0) if uvi < 0: # saturated return uvi = round(uvi / 10.0, 1) self.index_label.setText(unicode(uvi)) if uvi < 2.5: background = 'green' color = 'white' elif uvi < 5.5: background = 'yellow' color = 'black' elif uvi < 7.5: background = 'orange' color = 'black' elif uvi < 10.5: background = 'red' color = 'white' else: background = 'magenta' color = 'white' self.index_label.setStyleSheet( 'QLabel {{ background : {0}; color : {1} }}'.format( background, color))
class AmbientLightV3(COMCUPluginBase): def __init__(self, *args): COMCUPluginBase.__init__(self, BrickletAmbientLightV3, *args) self.al = self.device self.cbe_illuminance = CallbackEmulator(self.al.get_illuminance, self.cb_illuminance, self.increase_error_count) self.alf = AmbientLightFrame() self.out_of_range_label = QLabel('Illuminance is out-of-range') self.saturated_label = QLabel('Sensor is saturated') self.out_of_range_label.hide() self.out_of_range_label.setStyleSheet('QLabel { color: red }') self.saturated_label.hide() self.saturated_label.setStyleSheet('QLabel { color: magenta }') self.current_illuminance = None # float, lx plots = [('Illuminance', Qt.red, lambda: self.current_illuminance, '{:.2f} lx (Lux)'.format)] self.plot_widget = PlotWidget('Illuminance [lx]', plots, extra_key_widgets=[self.out_of_range_label, self.saturated_label, self.alf]) self.range_label = QLabel('Illuminance Range:') self.range_combo = QComboBox() self.range_combo.addItem("Unlimited", BrickletAmbientLightV3.ILLUMINANCE_RANGE_UNLIMITED) self.range_combo.addItem("0 - 64000 lx", BrickletAmbientLightV3.ILLUMINANCE_RANGE_64000LUX) self.range_combo.addItem("0 - 32000 lx", BrickletAmbientLightV3.ILLUMINANCE_RANGE_32000LUX) self.range_combo.addItem("0 - 16000 lx", BrickletAmbientLightV3.ILLUMINANCE_RANGE_16000LUX) self.range_combo.addItem("0 - 8000 lx", BrickletAmbientLightV3.ILLUMINANCE_RANGE_8000LUX) self.range_combo.addItem("0 - 1300 lx", BrickletAmbientLightV3.ILLUMINANCE_RANGE_1300LUX) self.range_combo.addItem("0 - 600 lx", BrickletAmbientLightV3.ILLUMINANCE_RANGE_600LUX) self.range_combo.currentIndexChanged.connect(self.new_config) self.time_label = QLabel('Integration Time:') self.time_combo = QComboBox() self.time_combo.addItem("50 ms", BrickletAmbientLightV3.INTEGRATION_TIME_50MS) self.time_combo.addItem("100 ms", BrickletAmbientLightV3.INTEGRATION_TIME_100MS) self.time_combo.addItem("150 ms", BrickletAmbientLightV3.INTEGRATION_TIME_150MS) self.time_combo.addItem("200 ms", BrickletAmbientLightV3.INTEGRATION_TIME_200MS) self.time_combo.addItem("250 ms", BrickletAmbientLightV3.INTEGRATION_TIME_250MS) self.time_combo.addItem("300 ms", BrickletAmbientLightV3.INTEGRATION_TIME_300MS) self.time_combo.addItem("350 ms", BrickletAmbientLightV3.INTEGRATION_TIME_350MS) self.time_combo.addItem("400 ms", BrickletAmbientLightV3.INTEGRATION_TIME_400MS) self.time_combo.currentIndexChanged.connect(self.new_config) hlayout = QHBoxLayout() hlayout.addWidget(self.range_label) hlayout.addWidget(self.range_combo) hlayout.addStretch() hlayout.addWidget(self.time_label) hlayout.addWidget(self.time_combo) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout = QVBoxLayout(self) layout.addWidget(self.plot_widget) layout.addWidget(line) layout.addLayout(hlayout) def start(self): async_call(self.al.get_configuration, None, self.get_configucation_async, self.increase_error_count) async_call(self.al.get_illuminance, None, self.cb_illuminance, self.increase_error_count) self.cbe_illuminance.set_period(100) self.plot_widget.stop = False def stop(self): self.cbe_illuminance.set_period(0) self.plot_widget.stop = True def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletAmbientLightV3.DEVICE_IDENTIFIER def get_configucation_async(self, conf): self.range_combo.setCurrentIndex(self.range_combo.findData(conf.illuminance_range)) self.time_combo.setCurrentIndex(self.time_combo.findData(conf.integration_time)) def new_config(self, value): try: self.al.set_configuration(self.range_combo.itemData(self.range_combo.currentIndex()), self.time_combo.itemData(self.time_combo.currentIndex())) except: pass def cb_illuminance(self, illuminance): self.current_illuminance = illuminance / 100.0 max_illuminance = 12000000 # Approximation for unlimited range current_range = self.range_combo.itemData(self.range_combo.currentIndex()) if current_range == BrickletAmbientLightV3.ILLUMINANCE_RANGE_64000LUX: max_illuminance = 6400001 elif current_range == BrickletAmbientLightV3.ILLUMINANCE_RANGE_32000LUX: max_illuminance = 3200001 elif current_range == BrickletAmbientLightV3.ILLUMINANCE_RANGE_16000LUX: max_illuminance = 1600001 elif current_range == BrickletAmbientLightV3.ILLUMINANCE_RANGE_8000LUX: max_illuminance = 800001 elif current_range == BrickletAmbientLightV3.ILLUMINANCE_RANGE_1300LUX: max_illuminance = 130001 elif current_range == BrickletAmbientLightV3.ILLUMINANCE_RANGE_600LUX: max_illuminance = 60001 if illuminance == 0: self.plot_widget.get_key_item(0).setStyleSheet('QLabel { color: magenta }') self.out_of_range_label.hide() self.saturated_label.show() elif illuminance >= max_illuminance: self.plot_widget.get_key_item(0).setStyleSheet('QLabel { color: red }') self.out_of_range_label.show() self.saturated_label.hide() else: self.plot_widget.get_key_item(0).setStyleSheet('') self.out_of_range_label.hide() self.saturated_label.hide() value = min(max(illuminance * 255 / max_illuminance, 0), 255) self.alf.set_color(value, value, value)
class Thermocouple(PluginBase): qtcb_error_state = pyqtSignal(bool, bool) def __init__(self, *args): PluginBase.__init__(self, BrickletThermocouple, *args) self.thermo = self.device self.qtcb_error_state.connect(self.cb_error_state) self.thermo.register_callback(self.thermo.CALLBACK_ERROR_STATE, self.qtcb_error_state.emit) self.cbe_temperature = CallbackEmulator(self.thermo.get_temperature, self.cb_temperature, self.increase_error_count) self.current_temperature = None # float, °C self.error_label = QLabel('Current Errors: None') self.error_label.setAlignment(Qt.AlignVCenter | Qt.AlignRight) plots = [('Temperature', Qt.red, lambda: self.current_temperature, u'{:.2f} °C'.format)] self.plot_widget = PlotWidget(u'Temperature [°C]', plots, extra_key_widgets=[self.error_label]) self.averaging_label = QLabel('Averaging:') self.averaging_combo = QComboBox() self.averaging_combo.addItem('1', BrickletThermocouple.AVERAGING_1) self.averaging_combo.addItem('2', BrickletThermocouple.AVERAGING_2) self.averaging_combo.addItem('4', BrickletThermocouple.AVERAGING_4) self.averaging_combo.addItem('8', BrickletThermocouple.AVERAGING_8) self.averaging_combo.addItem('16', BrickletThermocouple.AVERAGING_16) self.type_label = QLabel('Thermocouple Type:') self.type_combo = QComboBox() self.type_combo.addItem('B', BrickletThermocouple.TYPE_B) self.type_combo.addItem('E', BrickletThermocouple.TYPE_E) self.type_combo.addItem('J', BrickletThermocouple.TYPE_J) self.type_combo.addItem('K', BrickletThermocouple.TYPE_K) self.type_combo.addItem('N', BrickletThermocouple.TYPE_N) self.type_combo.addItem('R', BrickletThermocouple.TYPE_R) self.type_combo.addItem('S', BrickletThermocouple.TYPE_S) self.type_combo.addItem('T', BrickletThermocouple.TYPE_T) self.type_combo.addItem('Gain 8', BrickletThermocouple.TYPE_G8) self.type_combo.addItem('Gain 32', BrickletThermocouple.TYPE_G32) self.filter_label = QLabel('Noise Rejection Filter:') self.filter_combo = QComboBox() self.filter_combo.addItem('50 Hz', BrickletThermocouple.FILTER_OPTION_50HZ) self.filter_combo.addItem('60 Hz', BrickletThermocouple.FILTER_OPTION_60HZ) hlayout = QHBoxLayout() hlayout.addWidget(self.averaging_label) hlayout.addWidget(self.averaging_combo) hlayout.addStretch() hlayout.addWidget(self.type_label) hlayout.addWidget(self.type_combo) hlayout.addStretch() hlayout.addWidget(self.filter_label) hlayout.addWidget(self.filter_combo) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout = QVBoxLayout(self) layout.addWidget(self.plot_widget) layout.addWidget(line) layout.addLayout(hlayout) self.averaging_combo.currentIndexChanged.connect(self.configuration_changed) self.type_combo.currentIndexChanged.connect(self.configuration_changed) self.filter_combo.currentIndexChanged.connect(self.configuration_changed) def start(self): async_call(self.thermo.get_temperature, None, self.cb_temperature, self.increase_error_count) async_call(self.thermo.get_configuration, None, self.cb_configuration, self.increase_error_count) async_call(self.thermo.get_error_state, None, lambda e: self.cb_error_state(e.over_under, e.open_circuit)) self.cbe_temperature.set_period(100) self.plot_widget.stop = False def stop(self): self.cbe_temperature.set_period(0) self.plot_widget.stop = True def destroy(self): pass def get_url_part(self): return 'thermocouple' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletThermocouple.DEVICE_IDENTIFIER def get_current_value(self): return self.current_value def configuration_changed(self, _): conf_averaging = self.averaging_combo.itemData(self.averaging_combo.currentIndex()) conf_type = self.type_combo.itemData(self.type_combo.currentIndex()) conf_filter = self.filter_combo.itemData(self.filter_combo.currentIndex()) self.thermo.set_configuration(conf_averaging, conf_type, conf_filter) def cb_temperature(self, temperature): self.current_temperature = temperature / 100.0 def cb_configuration(self, conf): self.averaging_combo.blockSignals(True) self.averaging_combo.setCurrentIndex(self.averaging_combo.findData(conf.averaging)) self.averaging_combo.blockSignals(False) self.type_combo.blockSignals(True) self.type_combo.setCurrentIndex(self.type_combo.findData(conf.thermocouple_type)) self.type_combo.blockSignals(False) self.filter_combo.blockSignals(True) self.filter_combo.setCurrentIndex(self.filter_combo.findData(conf.filter)) self.filter_combo.blockSignals(False) def cb_error_state(self, over_under, open_circuit): if over_under or open_circuit: text = 'Current Errors: ' if over_under: text += 'Over/Under Voltage' if over_under and open_circuit: text += ' and ' if open_circuit: text += 'Open Circuit\n(defective thermocouple or nothing connected)' self.error_label.setStyleSheet('QLabel { color : red }') self.error_label.setText(text) else: self.error_label.setStyleSheet('') self.error_label.setText('Current Errors: None')
class ScoringDialog(QWidget): """a dialog for entering the scores""" # pylint: disable=R0902 # pylint we need more than 10 instance attributes scoringClosed = pyqtSignal() def __init__(self, game): QWidget.__init__(self, None) self.game = None self.setWindowTitle(m18n('Scoring for this Hand') + ' - Kajongg') self.nameLabels = [None] * 4 self.spValues = [None] * 4 self.windLabels = [None] * 4 self.wonBoxes = [None] * 4 self.detailsLayout = [None] * 4 self.details = [None] * 4 self.__tilePixMaps = [] self.__meldPixMaps = [] grid = QGridLayout(self) pGrid = QGridLayout() grid.addLayout(pGrid, 0, 0, 2, 1) pGrid.addWidget(QLabel(m18nc('kajongg', "Player")), 0, 0) pGrid.addWidget(QLabel(m18nc('kajongg', "Wind")), 0, 1) pGrid.addWidget(QLabel(m18nc('kajongg', 'Score')), 0, 2) pGrid.addWidget(QLabel(m18n("Winner")), 0, 3) self.detailTabs = QTabWidget() self.detailTabs.setDocumentMode(True) pGrid.addWidget(self.detailTabs, 0, 4, 8, 1) for idx in range(4): self.setupUiForPlayer(pGrid, idx) self.draw = QCheckBox(m18nc('kajongg','Draw')) self.draw.clicked.connect(self.wonChanged) btnPenalties = QPushButton(m18n("&Penalties")) btnPenalties.clicked.connect(self.penalty) self.btnSave = QPushButton(m18n('&Save Hand')) self.btnSave.setEnabled(False) self.setupUILastTileMeld(pGrid) pGrid.setRowStretch(87, 10) pGrid.addWidget(self.draw, 7, 3) self.cbLastTile.currentIndexChanged.connect(self.slotLastTile) self.cbLastMeld.currentIndexChanged.connect(self.slotInputChanged) btnBox = QHBoxLayout() btnBox.addWidget(btnPenalties) btnBox.addWidget(self.btnSave) pGrid.addLayout(btnBox, 8, 4) StateSaver(self) self.refresh(game) def setupUILastTileMeld(self, pGrid): """setup UI elements for last tile and last meld""" self.lblLastTile = QLabel(m18n('&Last Tile:')) self.cbLastTile = QComboBox() self.cbLastTile.setMinimumContentsLength(1) vpol = QSizePolicy() vpol.setHorizontalPolicy(QSizePolicy.Fixed) self.cbLastTile.setSizePolicy(vpol) self.cbLastTile.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon) self.lblLastTile.setBuddy(self.cbLastTile) self.lblLastMeld = QLabel(m18n('L&ast Meld:')) self.prevLastTile = None self.cbLastMeld = QComboBox() self.cbLastMeld.setMinimumContentsLength(1) self.cbLastMeld.setSizePolicy(vpol) self.cbLastMeld.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon) self.lblLastMeld.setBuddy(self.cbLastMeld) self.comboTilePairs = set() pGrid.setRowStretch(6, 5) pGrid.addWidget(self.lblLastTile, 7, 0, 1, 2) pGrid.addWidget(self.cbLastTile, 7, 2, 1, 1) pGrid.addWidget(self.lblLastMeld, 8, 0, 1, 2) pGrid.addWidget(self.cbLastMeld, 8, 2, 1, 2) def setupUiForPlayer(self, pGrid, idx): """setup UI elements for a player""" self.spValues[idx] = QSpinBox() self.nameLabels[idx] = QLabel() self.nameLabels[idx].setBuddy(self.spValues[idx]) self.windLabels[idx] = WindLabel() pGrid.addWidget(self.nameLabels[idx], idx+2, 0) pGrid.addWidget(self.windLabels[idx], idx+2, 1) pGrid.addWidget(self.spValues[idx], idx+2, 2) self.wonBoxes[idx] = QCheckBox("") pGrid.addWidget(self.wonBoxes[idx], idx+2, 3) self.wonBoxes[idx].clicked.connect(self.wonChanged) self.spValues[idx].valueChanged.connect(self.slotInputChanged) detailTab = QWidget() self.detailTabs.addTab(detailTab,'') self.details[idx] = QWidget() detailTabLayout = QVBoxLayout(detailTab) detailTabLayout.addWidget(self.details[idx]) detailTabLayout.addStretch() self.detailsLayout[idx] = QVBoxLayout(self.details[idx]) def refresh(self, game): """reload game""" if game and not game.isScoringGame(): return self.game = game self.clear() self.setVisible(game is not None and not game.finished()) if game: for idx, player in enumerate(game.players): for child in self.details[idx].children(): if isinstance(child, RuleBox): child.hide() self.detailsLayout[idx].removeWidget(child) del child if game: self.spValues[idx].setRange(0, game.ruleset.limit or 99999) self.nameLabels[idx].setText(player.localName) self.windLabels[idx].wind = player.wind self.windLabels[idx].roundsFinished = game.roundsFinished self.detailTabs.setTabText(idx, player.localName) player.manualRuleBoxes = [RuleBox(x) for x in game.ruleset.allRules if x.hasSelectable] for ruleBox in player.manualRuleBoxes: self.detailsLayout[idx].addWidget(ruleBox) ruleBox.clicked.connect(self.slotInputChanged) player.refreshManualRules() def show(self): """only now compute content""" if self.game and not self.game.finished(): self.slotInputChanged() QWidget.show(self) def penalty(self): """penalty button clicked""" dlg = PenaltyDialog(self.game) dlg.exec_() def slotLastTile(self): """called when the last tile changes""" newLastTile = self.computeLastTile() if not newLastTile: return prevLower, newLower = self.prevLastTile.islower(), newLastTile.islower() if prevLower != newLower: # state of last tile (concealed/exposed) changed: # for all checked boxes check if they still are applicable winner = self.game.winner if winner: for box in winner.manualRuleBoxes: if box.isChecked(): box.setChecked(False) if winner.hand.manualRuleMayApply(box.rule): box.setChecked(True) self.prevLastTile = newLastTile self.fillLastMeldCombo() self.slotInputChanged() def computeLastTile(self): """returns the currently selected last tile""" idx = self.cbLastTile.currentIndex() if idx >= 0: return str(self.cbLastTile.itemData(idx).toString()) def closeEvent(self, event): """the user pressed ALT-F4""" self.hide() event.ignore() self.scoringClosed.emit() def clickedPlayerIdx(self, checkbox): """the player whose box has been clicked""" for idx in range(4): if checkbox == self.wonBoxes[idx]: return idx assert False def wonChanged(self): """if a new winner has been defined, uncheck any previous winner""" newWinner = None if self.sender() != self.draw: clicked = self.clickedPlayerIdx(self.sender()) if self.wonBoxes[clicked].isChecked(): newWinner = self.game.players[clicked] else: newWinner = None self.game.winner = newWinner for idx in range(4): if newWinner != self.game.players[idx]: self.wonBoxes[idx].setChecked(False) if newWinner: self.draw.setChecked(False) self.fillLastTileCombo() self.slotInputChanged() def updateManualRules(self): """enable/disable them""" # if an exclusive rule has been activated, deactivate it for # all other players if isinstance(self.sender(), RuleBox): ruleBox = self.sender() if ruleBox.isChecked() and ruleBox.rule.exclusive(): for idx, player in enumerate(self.game.players): if ruleBox.parentWidget() != self.details[idx]: for pBox in player.manualRuleBoxes: if pBox.rule.name == ruleBox.rule.name: pBox.setChecked(False) try: newState = bool(self.game.winner.handBoard.tiles) except AttributeError: newState = False self.lblLastTile.setEnabled(newState) self.cbLastTile.setEnabled(newState) self.lblLastMeld.setEnabled(newState) self.cbLastMeld.setEnabled(newState) if self.game: for player in self.game.players: player.refreshManualRules(self.sender()) def clear(self): """prepare for next hand""" if self.game: for idx, player in enumerate(self.game.players): self.spValues[idx].clear() self.spValues[idx].setValue(0) self.wonBoxes[idx].setChecked(False) player.payment = 0 player.invalidateHand() for box in self.wonBoxes: box.setVisible(False) self.draw.setChecked(False) self.updateManualRules() if self.game is None: self.hide() else: for idx, player in enumerate(self.game.players): self.windLabels[idx].setPixmap(WINDPIXMAPS[(player.wind, player.wind == WINDS[self.game.roundsFinished % 4])]) self.computeScores() self.spValues[0].setFocus() self.spValues[0].selectAll() def computeScores(self): """if tiles have been selected, compute their value""" # pylint: disable=R0912 # too many branches if not self.game: return if self.game.finished(): self.hide() return for idx, player in enumerate(self.game.players): self.spValues[idx].blockSignals(True) # we do not want that change to call computeScores again self.wonBoxes[idx].blockSignals(True) # we do not want that change to call computeScores again if player.handBoard and player.handBoard.tiles: self.spValues[idx].setEnabled(False) self.nameLabels[idx].setBuddy(self.wonBoxes[idx]) for loop in range(10): prevTotal = player.handTotal handContent = player.computeHand(asWinner=True) self.wonBoxes[idx].setVisible(handContent.won) if not self.wonBoxes[idx].isVisibleTo(self) and self.wonBoxes[idx].isChecked(): self.wonBoxes[idx].setChecked(False) self.game.winner = None elif prevTotal == player.handTotal: break player.refreshManualRules() self.spValues[idx].setValue(player.handTotal) else: if not self.spValues[idx].isEnabled(): self.spValues[idx].clear() self.spValues[idx].setValue(0) self.spValues[idx].setEnabled(True) self.nameLabels[idx].setBuddy(self.spValues[idx]) self.wonBoxes[idx].setVisible(player.handTotal >= self.game.ruleset.minMJTotal()) if not self.wonBoxes[idx].isVisibleTo(self) and self.wonBoxes[idx].isChecked(): self.wonBoxes[idx].setChecked(False) if not self.wonBoxes[idx].isVisibleTo(self) and player is self.game.winner: self.game.winner = None self.spValues[idx].blockSignals(False) self.wonBoxes[idx].blockSignals(False) if Internal.field.explainView: Internal.field.explainView.refresh(self.game) def __lastMeldContent(self): """prepare content for lastmeld combo""" lastTiles = set() winnerTiles = [] if self.game.winner and self.game.winner.handBoard: winnerTiles = self.game.winner.handBoard.tiles pairs = [] for meld in self.game.winner.hand.melds: if len(meld) < 4: pairs.extend(meld.pairs) for tile in winnerTiles: if tile.element in pairs and not tile.isBonus(): lastTiles.add(tile.element) return lastTiles, winnerTiles def __fillLastTileComboWith(self, lastTiles, winnerTiles): """fill last meld combo with prepared content""" self.comboTilePairs = lastTiles idx = self.cbLastTile.currentIndex() if idx < 0: idx = 0 indexedTile = str(self.cbLastTile.itemData(idx).toPyObject()) restoredIdx = None self.cbLastTile.clear() if not winnerTiles: return pmSize = winnerTiles[0].board.tileset.faceSize pmSize = QSize(pmSize.width() * 0.5, pmSize.height() * 0.5) self.cbLastTile.setIconSize(pmSize) QPixmapCache.clear() self.__tilePixMaps = [] shownTiles = set() for tile in winnerTiles: if tile.element in lastTiles and tile.element not in shownTiles: shownTiles.add(tile.element) self.cbLastTile.addItem(QIcon(tile.graphics.pixmapFromSvg(pmSize, withBorders=False)), '', QVariant(tile.element)) if indexedTile == tile.element: restoredIdx = self.cbLastTile.count() - 1 if not restoredIdx and indexedTile: # try again, maybe the tile changed between concealed and exposed indexedTile = indexedTile.lower() for idx in range(self.cbLastTile.count()): if indexedTile == str(self.cbLastTile.itemData(idx).toPyObject()).lower(): restoredIdx = idx break if not restoredIdx: restoredIdx = 0 self.cbLastTile.setCurrentIndex(restoredIdx) self.prevLastTile = self.computeLastTile() def clearLastTileCombo(self): """as the name says""" self.comboTilePairs = None self.cbLastTile.clear() def fillLastTileCombo(self): """fill the drop down list with all possible tiles. If the drop down had content before try to preserve the current index. Even if the tile changed state meanwhile.""" if self.game is None: return lastTiles, winnerTiles = self.__lastMeldContent() if self.comboTilePairs == lastTiles: return self.cbLastTile.blockSignals(True) # we only want to emit the changed signal once try: self.__fillLastTileComboWith(lastTiles, winnerTiles) finally: self.cbLastTile.blockSignals(False) self.cbLastTile.currentIndexChanged.emit(0) def __fillLastMeldComboWith(self, winnerMelds, indexedMeld, lastTile): """fill last meld combo with prepared content""" winner = self.game.winner faceWidth = winner.handBoard.tileset.faceSize.width() * 0.5 faceHeight = winner.handBoard.tileset.faceSize.height() * 0.5 restoredIdx = None for meld in winnerMelds: pixMap = QPixmap(faceWidth * len(meld), faceHeight) pixMap.fill(Qt.transparent) self.__meldPixMaps.append(pixMap) painter = QPainter(pixMap) for element in meld.pairs: painter.drawPixmap(0, 0, winner.handBoard.tilesByElement(element) \ [0].graphics.pixmapFromSvg(QSize(faceWidth, faceHeight), withBorders=False)) painter.translate(QPointF(faceWidth, 0.0)) self.cbLastMeld.addItem(QIcon(pixMap), '', QVariant(meld.joined)) if indexedMeld == meld.joined: restoredIdx = self.cbLastMeld.count() - 1 if not restoredIdx and indexedMeld: # try again, maybe the meld changed between concealed and exposed indexedMeld = indexedMeld.lower() for idx in range(self.cbLastMeld.count()): meldContent = str(self.cbLastMeld.itemData(idx).toPyObject()) if indexedMeld == meldContent.lower(): restoredIdx = idx if lastTile not in meldContent: if lastTile.lower() == lastTile: lastTile = lastTile.capitalize() else: lastTile = lastTile.lower() assert lastTile in meldContent self.cbLastTile.blockSignals(True) # we want to continue right here idx = self.cbLastTile.findData(QVariant(lastTile)) self.cbLastTile.setCurrentIndex(idx) self.cbLastTile.blockSignals(False) break if not restoredIdx: restoredIdx = 0 self.cbLastMeld.setCurrentIndex(restoredIdx) self.cbLastMeld.setIconSize(QSize(faceWidth * 3, faceHeight)) def fillLastMeldCombo(self): """fill the drop down list with all possible melds. If the drop down had content before try to preserve the current index. Even if the meld changed state meanwhile.""" self.cbLastMeld.blockSignals(True) # we only want to emit the changed signal once try: showCombo = False idx = self.cbLastMeld.currentIndex() if idx < 0: idx = 0 indexedMeld = str(self.cbLastMeld.itemData(idx).toPyObject()) self.cbLastMeld.clear() self.__meldPixMaps = [] if not self.game.winner: return if self.cbLastTile.count() == 0: return lastTile = Internal.field.computeLastTile() winnerMelds = [m for m in self.game.winner.hand.melds if len(m) < 4 \ and lastTile in m.pairs] assert len(winnerMelds) if len(winnerMelds) == 1: self.cbLastMeld.addItem(QIcon(), '', QVariant(winnerMelds[0].joined)) self.cbLastMeld.setCurrentIndex(0) return showCombo = True self.__fillLastMeldComboWith(winnerMelds, indexedMeld, lastTile) finally: self.lblLastMeld.setVisible(showCombo) self.cbLastMeld.setVisible(showCombo) self.cbLastMeld.blockSignals(False) self.cbLastMeld.currentIndexChanged.emit(0) def slotInputChanged(self): """some input fields changed: update""" for player in self.game.players: player.invalidateHand() self.updateManualRules() self.computeScores() self.validate() def validate(self): """update the status of the OK button""" game = self.game if game: valid = True if game.winner and game.winner.handTotal < game.ruleset.minMJTotal(): valid = False elif not game.winner and not self.draw.isChecked(): valid = False self.btnSave.setEnabled(valid)
class UpdateBox(QWidget): def __init__(self, base): QWidget.__init__(self) self.base = base self.showed = False self.setFixedSize(500, 120) self.text_edit = CompletionTextEdit() self.upload_button = ImageButton(base, 'action-upload.png', i18n.get('upload_image')) self.short_button = ImageButton(base, 'action-shorten.png', i18n.get('short_urls')) font = QFont() font.setPointSize(18) font.setBold(True) self.char_count = QLabel('140') self.char_count.setFont(font) self.update_button = QPushButton(i18n.get('update')) self.update_button.setToolTip(self.base.get_shortcut_string('Enter')) self.queue_button = QPushButton(i18n.get('add_to_queue')) self.queue_button.setToolTip(self.base.get_shortcut_string('P')) self.accounts_combo = QComboBox() buttons = QHBoxLayout() buttons.setSpacing(4) buttons.addWidget(self.accounts_combo) buttons.addWidget(self.upload_button) buttons.addWidget(self.short_button) buttons.addStretch(0) buttons.addWidget(self.char_count) buttons.addWidget(self.queue_button) buttons.addWidget(self.update_button) self.loader = BarLoadIndicator() self.error_message = ErrorLabel() self.update_button.clicked.connect(self.__update_status) self.queue_button.clicked.connect(self.__queue_status) self.short_button.clicked.connect(self.__short_urls) self.upload_button.clicked.connect(self.__upload_image) self.text_edit.textChanged.connect(self.__update_count) self.text_edit.quit.connect(self.closeEvent) self.text_edit.activated.connect(self.__update_status) self.text_edit.enqueued.connect(self.__queue_status) layout = QVBoxLayout() layout.setSpacing(0) layout.addWidget(self.text_edit) layout.addWidget(self.loader) layout.addSpacing(5) layout.addWidget(self.error_message) layout.addLayout(buttons) layout.setContentsMargins(5, 5, 5, 5) self.setLayout(layout) self.__clear() def __count_chars(self): message = self.text_edit.toPlainText() urls = [str(url) for url in get_urls(message) if len(url) > 23] for url in urls: message = message.replace(url, '0' * 23) return MAX_CHAR - len(message) def __update_count(self): remaining_chars = self.__count_chars() if remaining_chars <= 10: self.char_count.setStyleSheet("QLabel { color: #D40D12 }") elif remaining_chars > 10 and remaining_chars <= 20: self.char_count.setStyleSheet("QLabel { color: #D4790D }") else: self.char_count.setStyleSheet("QLabel { color: #000000 }") self.char_count.setText(str(remaining_chars)) def __validate(self, message, accounts, index): if len(message) == 0: self.error(i18n.get('you_can_not_submit_an_empty_message')) return False if index == 0 and len(accounts) > 1: self.error(i18n.get('select_an_account_before_post')) return False if self.__count_chars() < 0: self.error(i18n.get('message_too_long')) return False return True def __short_urls(self): self.enable(False) message = unicode(self.text_edit.toPlainText()) self.base.short_urls(message) def __upload_image(self): index = self.accounts_combo.currentIndex() accounts = self.base.core.get_registered_accounts() if index == 0 and len(accounts) > 1: self.error(i18n.get('select_an_account_before_post')) return False account_id = str(self.accounts_combo.itemData(index).toPyObject()) filename = str(QFileDialog.getOpenFileName(self, i18n.get('upload_image'), self.base.home_path)) if filename != '': self.enable(False) self.base.upload_media(account_id, filename) def __update_status(self): index = self.accounts_combo.currentIndex() accounts = self.base.core.get_registered_accounts() message = unicode(self.text_edit.toPlainText()) if not self.__validate(message, accounts, index): self.enable(True) return self.enable(False) account_id = str(self.accounts_combo.itemData(index).toPyObject()) if self.direct_message_to: self.base.send_direct_message(account_id, self.direct_message_to, message) else: if account_id == 'broadcast': self.base.broadcast_status(message) else: self.base.update_status(account_id, message, self.in_reply_to_id) def __queue_status(self): index = self.accounts_combo.currentIndex() accounts = self.base.core.get_registered_accounts() account_id = str(self.accounts_combo.itemData(index).toPyObject()) message = unicode(self.text_edit.toPlainText()) if not self.__validate(message, accounts, index): self.enable(True) return self.enable(False) self.base.push_status_to_queue(account_id, message) def __clear(self): self.account_id = None self.in_reply_to_id = None self.in_reply_to_user = None self.direct_message_to = None self.quoting = False self.message = None self.cursor_position = None self.text_edit.setText('') self.accounts_combo.setCurrentIndex(0) self.queue_button.setEnabled(True) self.loader.setVisible(False) self.error_message.setVisible(False) self.error_message.setText('') self.enable(True) self.showed = False def __show(self): self.update_friends_list() short_service = self.base.get_shorten_url_service() short_tooltip = "%s (%s)" % (i18n.get('short_url'), short_service) self.short_button.setToolTip(short_tooltip) upload_service = self.base.get_upload_media_service() upload_tooltip = "%s (%s)" % (i18n.get('upload_image'), upload_service) self.upload_button.setToolTip(upload_tooltip) self.accounts_combo.clear() accounts = self.base.core.get_registered_accounts() if len(accounts) > 1: self.accounts_combo.addItem('--', '') for account in accounts: protocol = get_protocol_from(account.id_) icon = QIcon(self.base.get_image_path('%s.png' % protocol)) self.accounts_combo.addItem(icon, get_username_from(account.id_), account.id_) if len(accounts) > 1: icon = QIcon(self.base.get_image_path('action-conversation.png')) self.accounts_combo.addItem(icon, i18n.get('broadcast'), 'broadcast') if self.account_id: index = self.accounts_combo.findData(self.account_id) if index > 0: self.accounts_combo.setCurrentIndex(index) self.accounts_combo.setEnabled(False) if self.message: self.text_edit.setText(self.message) cursor = self.text_edit.textCursor() cursor.movePosition(self.cursor_position, QTextCursor.MoveAnchor) self.text_edit.setTextCursor(cursor) QWidget.show(self) self.showed = True def __on_timeout(self): self.error_message.setText('') self.error_message.setVisible(False) def show(self): if self.showed: return self.raise_() self.setWindowTitle(i18n.get('whats_happening')) self.__show() def show_for_reply(self, account_id, status): if self.showed: return self.raise_() title = "%s @%s" % (i18n.get('reply_to'), status.username) self.setWindowTitle(title) self.account_id = account_id self.in_reply_to_id = status.id_ self.in_reply_to_user = status.username mentions = ' '.join(["@%s" % user for user in status.get_mentions()]) self.message = "%s " % mentions self.cursor_position = QTextCursor.End self.__show() def show_for_send_direct(self, account_id, username): if self.showed: return self.raise_() title = "%s @%s" % (i18n.get('send_message_to'), username) self.setWindowTitle(title) self.account_id = account_id self.direct_message_to = username self.__show() self.queue_button.setEnabled(False) def show_for_reply_direct(self, account_id, status): if self.showed: return self.raise_() title = "%s @%s" % (i18n.get('send_message_to'), status.username) self.setWindowTitle(title) self.account_id = account_id self.direct_message_to = status.username self.__show() self.queue_button.setEnabled(False) def show_for_quote(self, account_id, status): if self.showed: return self.raise_() self.setWindowTitle(i18n.get('quoting')) self.account_id = account_id self.message = " RT @%s %s" % (status.username, status.text) self.cursor_position = QTextCursor.Start self.quoting = True self.__show() self.queue_button.setEnabled(False) def closeEvent(self, event=None): message = unicode(self.text_edit.toPlainText()) if len(message) > 0: confirmation = self.base.show_confirmation_message(i18n.get('confirm_discard'), i18n.get('do_you_want_to_discard_message')) if not confirmation: return if event: event.ignore() self.__clear() self.hide() def enable(self, value): self.text_edit.setEnabled(value) if not self.account_id: self.accounts_combo.setEnabled(value) if self.in_reply_to_id or self.direct_message_to or self.quoting: self.queue_button.setEnabled(False) else: self.queue_button.setEnabled(value) self.upload_button.setEnabled(value) self.short_button.setEnabled(value) self.update_button.setEnabled(value) self.loader.setVisible(not value) def done(self): self.__clear() self.hide() def error(self, message): self.enable(True) self.error_message.setText(message) self.error_message.setVisible(True) self.timer = QTimer() self.timer.timeout.connect(self.__on_timeout) self.timer.start(5000) def after_short_url(self, message): if self.base.is_exception(message): self.error(i18n.get('error_shorting_url')) else: self.text_edit.setText(message) self.enable(True) def after_upload_media(self, media_url): if self.base.is_exception(media_url): self.error(i18n.get('error_uploading_image')) else: text_cursor = self.text_edit.textCursor() text_cursor.select(QTextCursor.WordUnderCursor) if text_cursor.selectedText() != '': media_url = " %s" % media_url text_cursor.clearSelection() text_cursor.insertText(media_url) self.text_edit.setTextCursor(text_cursor) self.enable(True) def update_friends_list(self): completer = QCompleter(self.base.load_friends_list_with_extras()) self.text_edit.setCompleter(completer)
class Thermocouple(PluginBase): qtcb_error_state = pyqtSignal(bool, bool) def __init__(self, *args): PluginBase.__init__(self, BrickletThermocouple, *args) self.thermo = self.device self.qtcb_error_state.connect(self.cb_error_state) self.thermo.register_callback(self.thermo.CALLBACK_ERROR_STATE, self.qtcb_error_state.emit) self.cbe_temperature = CallbackEmulator(self.thermo.get_temperature, self.cb_temperature, self.increase_error_count) self.current_temperature = None # float, °C self.error_label = QLabel('Current Errors: None') self.error_label.setAlignment(Qt.AlignVCenter | Qt.AlignRight) plots = [('Temperature', Qt.red, lambda: self.current_temperature, u'{:.2f} °C'.format)] self.plot_widget = PlotWidget(u'Temperature [°C]', plots, extra_key_widgets=[self.error_label]) self.averaging_label = QLabel('Averaging:') self.averaging_combo = QComboBox() self.averaging_combo.addItem('1', BrickletThermocouple.AVERAGING_1) self.averaging_combo.addItem('2', BrickletThermocouple.AVERAGING_2) self.averaging_combo.addItem('4', BrickletThermocouple.AVERAGING_4) self.averaging_combo.addItem('8', BrickletThermocouple.AVERAGING_8) self.averaging_combo.addItem('16', BrickletThermocouple.AVERAGING_16) self.type_label = QLabel('Thermocouple Type:') self.type_combo = QComboBox() self.type_combo.addItem('B', BrickletThermocouple.TYPE_B) self.type_combo.addItem('E', BrickletThermocouple.TYPE_E) self.type_combo.addItem('J', BrickletThermocouple.TYPE_J) self.type_combo.addItem('K', BrickletThermocouple.TYPE_K) self.type_combo.addItem('N', BrickletThermocouple.TYPE_N) self.type_combo.addItem('R', BrickletThermocouple.TYPE_R) self.type_combo.addItem('S', BrickletThermocouple.TYPE_S) self.type_combo.addItem('T', BrickletThermocouple.TYPE_T) self.type_combo.addItem('Gain 8', BrickletThermocouple.TYPE_G8) self.type_combo.addItem('Gain 32', BrickletThermocouple.TYPE_G32) self.filter_label = QLabel('Noise Rejection Filter:') self.filter_combo = QComboBox() self.filter_combo.addItem('50 Hz', BrickletThermocouple.FILTER_OPTION_50HZ) self.filter_combo.addItem('60 Hz', BrickletThermocouple.FILTER_OPTION_60HZ) hlayout = QHBoxLayout() hlayout.addWidget(self.averaging_label) hlayout.addWidget(self.averaging_combo) hlayout.addStretch() hlayout.addWidget(self.type_label) hlayout.addWidget(self.type_combo) hlayout.addStretch() hlayout.addWidget(self.filter_label) hlayout.addWidget(self.filter_combo) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout = QVBoxLayout(self) layout.addWidget(self.plot_widget) layout.addWidget(line) layout.addLayout(hlayout) self.averaging_combo.currentIndexChanged.connect( self.configuration_changed) self.type_combo.currentIndexChanged.connect(self.configuration_changed) self.filter_combo.currentIndexChanged.connect( self.configuration_changed) def start(self): async_call(self.thermo.get_temperature, None, self.cb_temperature, self.increase_error_count) async_call(self.thermo.get_configuration, None, self.cb_configuration, self.increase_error_count) async_call(self.thermo.get_error_state, None, lambda e: self.cb_error_state(e.over_under, e.open_circuit)) self.cbe_temperature.set_period(100) self.plot_widget.stop = False def stop(self): self.cbe_temperature.set_period(0) self.plot_widget.stop = True def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletThermocouple.DEVICE_IDENTIFIER def get_current_value(self): return self.current_value def configuration_changed(self, _): conf_averaging = self.averaging_combo.itemData( self.averaging_combo.currentIndex()) conf_type = self.type_combo.itemData(self.type_combo.currentIndex()) conf_filter = self.filter_combo.itemData( self.filter_combo.currentIndex()) self.thermo.set_configuration(conf_averaging, conf_type, conf_filter) def cb_temperature(self, temperature): self.current_temperature = temperature / 100.0 def cb_configuration(self, conf): self.averaging_combo.blockSignals(True) self.averaging_combo.setCurrentIndex( self.averaging_combo.findData(conf.averaging)) self.averaging_combo.blockSignals(False) self.type_combo.blockSignals(True) self.type_combo.setCurrentIndex( self.type_combo.findData(conf.thermocouple_type)) self.type_combo.blockSignals(False) self.filter_combo.blockSignals(True) self.filter_combo.setCurrentIndex( self.filter_combo.findData(conf.filter)) self.filter_combo.blockSignals(False) def cb_error_state(self, over_under, open_circuit): if over_under or open_circuit: text = 'Current Errors: ' if over_under: text += 'Over/Under Voltage' if over_under and open_circuit: text += ' and ' if open_circuit: text += 'Open Circuit\n(defective thermocouple or nothing connected)' self.error_label.setStyleSheet('QLabel { color : red }') self.error_label.setText(text) else: self.error_label.setStyleSheet('') self.error_label.setText('Current Errors: None')
class ActionBar(QFrame): """ SIGNALS: @changeCurrent(PyQt_PyObject) @runFile(QString) @reopenTab(QString) @recentTabsModified() """ def __init__(self, main_combo=False): super(ActionBar, self).__init__() self.setObjectName("actionbar") hbox = QHBoxLayout(self) hbox.setContentsMargins(1, 1, 1, 1) hbox.setSpacing(1) self.lbl_checks = QLabel('') self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.lbl_checks.setFixedWidth(48) self.lbl_checks.setVisible(False) hbox.addWidget(self.lbl_checks) self.combo = QComboBox() #model = QStandardItemModel() #self.combo.setModel(model) #self.combo.view().setDragDropMode(QAbstractItemView.InternalMove) self.combo.setMaximumWidth(300) self.combo.setObjectName("combotab") self.connect(self.combo, SIGNAL("currentIndexChanged(int)"), self.current_changed) self.combo.setToolTip(translations.TR_COMBO_FILE_TOOLTIP) self.combo.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self.combo, SIGNAL("customContextMenuRequested(const QPoint &)"), self._context_menu_requested) hbox.addWidget(self.combo) self.symbols_combo = QComboBox() self.symbols_combo.setObjectName("combo_symbols") self.connect(self.symbols_combo, SIGNAL("activated(int)"), self.current_symbol_changed) hbox.addWidget(self.symbols_combo) self.code_navigator = CodeNavigator() hbox.addWidget(self.code_navigator) self._pos_text = "Line: %d, Col: %d" self.lbl_position = QLabel(self._pos_text % (0, 0)) self.lbl_position.setObjectName("position") self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.lbl_position) self.btn_close = QPushButton( self.style().standardIcon(QStyle.SP_DialogCloseButton), '') if main_combo: self.btn_close.setObjectName('navigation_button') self.btn_close.setToolTip(translations.TR_CLOSE_FILE) self.connect(self.btn_close, SIGNAL("clicked()"), self.about_to_close_file) else: self.btn_close.setObjectName('close_split') self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT) self.connect(self.btn_close, SIGNAL("clicked()"), self.close_split) self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.btn_close) def resizeEvent(self, event): super(ActionBar, self).resizeEvent(event) if event.size().width() < 350: self.symbols_combo.hide() self.code_navigator.hide() self.lbl_position.hide() else: self.symbols_combo.show() self.code_navigator.show() self.lbl_position.show() def add_item(self, text, neditable): """Add a new item to the combo and add the neditable data.""" self.combo.addItem(text, neditable) self.combo.setCurrentIndex(self.combo.count() - 1) def get_editables(self): editables = [] for index in range(self.combo.count()): neditable = self.combo.itemData(index) editables.append(neditable) return editables def add_symbols(self, symbols): """Add the symbols to the symbols's combo.""" self.symbols_combo.clear() for symbol in symbols: data = symbol[1] if data[1] == 'f': icon = QIcon(":img/function") else: icon = QIcon(":img/class") self.symbols_combo.addItem(icon, data[0]) def set_current_symbol(self, index): self.symbols_combo.setCurrentIndex(index) def update_item_icon(self, neditable, icon): index = self.combo.findData(neditable) self.combo.setItemIcon(index, icon) def update_item_text(self, neditable, text): index = self.combo.findData(neditable) self.combo.setItemText(index, text) def current_changed(self, index): """Change the current item in the combo.""" neditable = self.combo.itemData(index) self.emit(SIGNAL("changeCurrent(PyQt_PyObject, int)"), neditable, index) def current_symbol_changed(self, index): """Change the current symbol in the combo.""" self.emit(SIGNAL("goToSymbol(int)"), index) def update_line_col(self, line, col): """Update the line and column position.""" self.lbl_position.setText(self._pos_text % (line, col)) def _context_menu_requested(self, point): """Display context menu for the combo file.""" if self.combo.count() == 0: # If there is not an Editor opened, don't show the menu return menu = QMenu() actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT) actionRun = menu.addAction(translations.TR_RUN_FILE) menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX) self._create_menu_syntax(menuSyntax) menu.addSeparator() actionClose = menu.addAction(translations.TR_CLOSE_FILE) actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES) actionCloseAllNotThis = menu.addAction( translations.TR_CLOSE_OTHER_FILES) menu.addSeparator() actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY) actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY) menu.addSeparator() actionCopyPath = menu.addAction( translations.TR_COPY_FILE_PATH_TO_CLIPBOARD) actionReopen = menu.addAction(translations.TR_REOPEN_FILE) actionUndock = menu.addAction(translations.TR_UNDOCK_EDITOR) if len(settings.LAST_OPENED_FILES) == 0: actionReopen.setEnabled(False) #Connect actions self.connect(actionSplitH, SIGNAL("triggered()"), lambda: self._split(False)) self.connect(actionSplitV, SIGNAL("triggered()"), lambda: self._split(True)) self.connect(actionRun, SIGNAL("triggered()"), self._run_this_file) self.connect(actionAdd, SIGNAL("triggered()"), self._add_to_project) self.connect(actionClose, SIGNAL("triggered()"), self.about_to_close_file) self.connect(actionCloseAllNotThis, SIGNAL("triggered()"), self._close_all_files_except_this) self.connect(actionCloseAll, SIGNAL("triggered()"), self._close_all_files) self.connect(actionCopyPath, SIGNAL("triggered()"), self._copy_file_location) self.connect(actionReopen, SIGNAL("triggered()"), self._reopen_last_tab) self.connect(actionUndock, SIGNAL("triggered()"), self._undock_editor) menu.exec_(QCursor.pos()) def _create_menu_syntax(self, menuSyntax): """Create Menu with the list of syntax supported.""" syntax = list(settings.SYNTAX.keys()) syntax.sort() for syn in syntax: menuSyntax.addAction(syn) self.connect(menuSyntax, SIGNAL("triggered(QAction*)"), self._reapply_syntax) def _reapply_syntax(self, syntaxAction): #TODO if [self.currentIndex(), syntaxAction] != self._resyntax: self._resyntax = [self.currentIndex(), syntaxAction] self.emit(SIGNAL("syntaxChanged(QWidget, QString)"), self.currentWidget(), syntaxAction.text()) def set_current_file(self, neditable): index = self.combo.findData(neditable) self.combo.setCurrentIndex(index) def set_current_by_index(self, index): self.combo.setCurrentIndex(index) def about_to_close_file(self, index=None): """Close the NFile object.""" if index is None: index = self.combo.currentIndex() neditable = self.combo.itemData(index) if neditable: neditable.nfile.close() def close_split(self): self.emit(SIGNAL("closeSplit()")) def close_file(self, neditable): """Receive the confirmation to close the file.""" index = self.combo.findData(neditable) self.combo.removeItem(index) return index def _run_this_file(self): """Execute the current file.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("runFile(QString)"), neditable.file_path) def _add_to_project(self): """Emit a signal to let someone handle the inclusion of the file inside a project.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("addToProject(QString)"), neditable.file_path) def _reopen_last_tab(self): self.emit(SIGNAL("reopenTab(QString)"), settings.LAST_OPENED_FILES.pop()) self.emit(SIGNAL("recentTabsModified()")) def _undock_editor(self): self.emit(SIGNAL("undockEditor()")) def _split(self, orientation): self.emit(SIGNAL("splitEditor(bool)"), orientation) def _copy_file_location(self): """Copy the path of the current opened file to the clipboard.""" neditable = self.combo.itemData(self.combo.currentIndex()) QApplication.clipboard().setText(neditable.file_path, QClipboard.Clipboard) def _close_all_files(self): """Close all the files opened.""" for i in range(self.combo.count()): self.about_to_close_file(0) def _close_all_files_except_this(self): """Close all the files except the current one.""" neditable = self.combo.itemData(self.combo.currentIndex()) for i in reversed(list(range(self.combo.count()))): ne = self.combo.itemData(i) if ne is not neditable: self.about_to_close_file(i)
class AmbientLightV2(PluginBase): def __init__(self, *args): PluginBase.__init__(self, BrickletAmbientLightV2, *args) self.al = self.device self.has_clamped_output = self.firmware_version >= (2, 0, 2) self.cbe_illuminance = CallbackEmulator(self.al.get_illuminance, self.cb_illuminance, self.increase_error_count) self.illuminance_label = IlluminanceLabel('Illuminance: ') self.alf = AmbientLightFrame() self.out_of_range_label = QLabel('out-of-range') self.saturated_label = QLabel('sensor saturated') self.out_of_range_label.hide() self.out_of_range_label.setStyleSheet('QLabel { color: red }') self.saturated_label.hide() self.saturated_label.setStyleSheet('QLabel { color: magenta }') self.current_value = None plot_list = [['', Qt.red, self.get_current_value]] self.plot_widget = PlotWidget('Illuminance [lx]', plot_list) layout_h = QHBoxLayout() layout_h.addStretch() layout_h.addWidget(self.illuminance_label) layout_h.addWidget(self.out_of_range_label) layout_h.addWidget(self.saturated_label) layout_h.addWidget(self.alf) layout_h.addStretch() self.range_label = QLabel('Illuminance Range: ') self.range_combo = QComboBox() if self.has_clamped_output: # Also means that the unlimited range is available self.range_combo.addItem("Unlimited", BrickletAmbientLightV2.ILLUMINANCE_RANGE_UNLIMITED) self.range_combo.addItem("0 - 64000 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_64000LUX) self.range_combo.addItem("0 - 32000 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_32000LUX) self.range_combo.addItem("0 - 16000 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_16000LUX) self.range_combo.addItem("0 - 8000 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_8000LUX) self.range_combo.addItem("0 - 1300 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_1300LUX) self.range_combo.addItem("0 - 600 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_600LUX) self.range_combo.currentIndexChanged.connect(self.new_config) self.time_label = QLabel('Integration Time: ') self.time_combo = QComboBox() self.time_combo.addItem("50ms", BrickletAmbientLightV2.INTEGRATION_TIME_50MS) self.time_combo.addItem("100ms", BrickletAmbientLightV2.INTEGRATION_TIME_100MS) self.time_combo.addItem("150ms", BrickletAmbientLightV2.INTEGRATION_TIME_150MS) self.time_combo.addItem("200ms", BrickletAmbientLightV2.INTEGRATION_TIME_200MS) self.time_combo.addItem("250ms", BrickletAmbientLightV2.INTEGRATION_TIME_250MS) self.time_combo.addItem("300ms", BrickletAmbientLightV2.INTEGRATION_TIME_300MS) self.time_combo.addItem("350ms", BrickletAmbientLightV2.INTEGRATION_TIME_350MS) self.time_combo.addItem("400ms", BrickletAmbientLightV2.INTEGRATION_TIME_400MS) self.time_combo.currentIndexChanged.connect(self.new_config) layout_hc = QHBoxLayout() layout_hc.addStretch() layout_hc.addWidget(self.range_label) layout_hc.addWidget(self.range_combo) layout_hc.addStretch() layout_hc.addWidget(self.time_label) layout_hc.addWidget(self.time_combo) layout_hc.addStretch() layout = QVBoxLayout(self) layout.addLayout(layout_h) layout.addWidget(self.plot_widget) layout.addLayout(layout_hc) def start(self): async_call(self.al.get_configuration, None, self.get_configucation_async, self.increase_error_count) async_call(self.al.get_illuminance, None, self.cb_illuminance, self.increase_error_count) self.cbe_illuminance.set_period(100) self.plot_widget.stop = False def stop(self): self.cbe_illuminance.set_period(0) self.plot_widget.stop = True def destroy(self): pass def get_url_part(self): return 'ambient_light_v2' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletAmbientLightV2.DEVICE_IDENTIFIER def get_configucation_async(self, conf): self.range_combo.setCurrentIndex(self.range_combo.findData(conf.illuminance_range)) self.time_combo.setCurrentIndex(self.time_combo.findData(conf.integration_time)) def new_config(self, value): try: self.al.set_configuration(self.range_combo.itemData(self.range_combo.currentIndex()), self.time_combo.itemData(self.time_combo.currentIndex())) except: pass def get_current_value(self): return self.current_value def cb_illuminance(self, illuminance): self.current_value = illuminance/100.0 self.illuminance_label.setText(illuminance) max_illuminance = 12000000 # Approximation for unlimited range current_range = self.range_combo.itemData(self.range_combo.currentIndex()) if current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_64000LUX: max_illuminance = 6400001 elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_32000LUX: max_illuminance = 3200001 elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_16000LUX: max_illuminance = 1600001 elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_8000LUX: max_illuminance = 800001 elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_1300LUX: max_illuminance = 130001 elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_600LUX: max_illuminance = 60001 if self.has_clamped_output: # Also means that the unlimited range is available if illuminance == 0: self.illuminance_label.setStyleSheet('QLabel { color: magenta }') self.out_of_range_label.hide() self.saturated_label.show() elif illuminance >= max_illuminance: self.illuminance_label.setStyleSheet('QLabel { color: red }') self.out_of_range_label.show() self.saturated_label.hide() else: self.illuminance_label.setStyleSheet('') self.out_of_range_label.hide() self.saturated_label.hide() value = min(max(illuminance*255/max_illuminance, 0), 255) self.alf.set_color(value, value, value)
class UpdateIntervalDialog(QDialog): def __init__(self, parent, updater): QDialog.__init__(self, parent) self.updater = updater self.prop = MaeMoneyProperties.instance() self.setupUi() def setupUi(self): self.setWindowModality(Qt.WindowModal) self.layout = QVBoxLayout() self.setLayout(self.layout) self.btnPauseUpdate = QPushButton() self.setPauseUpdateButtonStatus() self.layout.addWidget(self.btnPauseUpdate) self.comboBoxUpdInterval = QComboBox() self.comboBoxUpdInterval.addItem(self.tr("Pause update"), 0) self.comboBoxUpdInterval.addItem( self.tr("Update interval - %1s").arg(Properties.DEFAULT_UPDATE_INTERVAL), Properties.DEFAULT_UPDATE_INTERVAL) self.comboBoxUpdInterval.addItem(self.tr("Update interval - 25s"), 25) self.comboBoxUpdInterval.addItem(self.tr("Update interval - 1 min"), 60) self.comboBoxUpdInterval.addItem(self.tr("Update interval - 5 min"), 5 * 60) self.comboBoxUpdInterval.addItem(self.tr("Update interval - 15 min"), 15 * 60) self.comboBoxUpdInterval.addItem(self.tr("Update interval - 30 min"), 30 * 60) self.comboBoxUpdInterval.addItem(self.tr("Update interval - 45 min"), 45 * 60) self.comboBoxUpdInterval.addItem(self.tr("Update interval - 1 hr"), 1 * 60 * 60) self.comboBoxUpdInterval.addItem(self.tr("Update interval - 2 hr"), 2 * 60 * 60) self.setCurrentComboBoxUpdInterval() self.setComboBoxStatus() self.layout.addWidget(self.comboBoxUpdInterval) self.btnBackToMainApp = QPushButton(self.tr("Back to Main Application")) self.layout.addWidget(self.btnBackToMainApp) self.setWindowTitle(self.tr("Update Interval")) self.connect(self.btnPauseUpdate, SIGNAL("clicked()"), self.pauseUpdate) self.connect(self.comboBoxUpdInterval, SIGNAL("activated(int)"), self.updateIntervalSelected) self.connect(self.btnBackToMainApp, SIGNAL("clicked()"), self.accept) def setCurrentComboBoxUpdInterval(self): curInterval = self.prop.getUpdateInterval() index = self.comboBoxUpdInterval.findData(curInterval) if index >= 0: self.comboBoxUpdInterval.setCurrentIndex(index) else: qWarning("Update interval of %ds is not available." %(curInterval)) qWarning("Resetting to default of %ds" %(Properties.DEFAULT_UPDATE_INTERVAL)) self.prop.setUpdateInterval(Properties.DEFAULT_UPDATE_INTERVAL) self.setCurrentComboBoxUpdInterval() def updateIntervalSelected(self, index): if self.updater is not None: intervalSelected = self.comboBoxUpdInterval.itemData(index).toInt()[0] self.prop.setUpdateInterval(intervalSelected) if intervalSelected == 0: self.pauseUpdate() else: self.updater.terminate() self.updater.start() self.updater.setUpdateInterval(intervalSelected) self.setPauseUpdateButtonStatus() def pauseUpdate(self): if self.updater is not None: self.updater.terminate() self.setPauseUpdateButtonStatus() pauseInterval = 0 index = self.comboBoxUpdInterval.findData(pauseInterval) self.comboBoxUpdInterval.setCurrentIndex(index) self.prop.setUpdateInterval(pauseInterval) def setPauseUpdateButtonStatus(self): if self.btnPauseUpdate is not None: if self.updater is not None and self.updater.isRunning(): self.btnPauseUpdate.setText(self.tr("Timer currently active. Click to pause update")) self.btnPauseUpdate.setEnabled(True) else: self.btnPauseUpdate.setText(self.tr("Update not running")) self.btnPauseUpdate.setEnabled(False) def setComboBoxStatus(self): if self.comboBoxUpdInterval is not None: if self.updater is None: self.comboBoxUpdInterval.setEnabled(False) else: self.comboBoxUpdInterval.setEnabled(True)
class BarometerV2(COMCUPluginBase): def __init__(self, *args): COMCUPluginBase.__init__(self, BrickletBarometerV2, *args) self.barometer = self.device self.cbe_air_pressure = CallbackEmulator( self.barometer.get_air_pressure, self.cb_get_air_pressure, self.increase_error_count) self.cbe_altitude = CallbackEmulator(self.barometer.get_altitude, self.cb_get_altitude, self.increase_error_count) self.cbe_temperature = CallbackEmulator(self.barometer.get_temperature, self.cb_get_temperature, self.increase_error_count) self.current_altitude = None self.current_temperature = None self.current_air_pressure = None self.calibration = None self.btn_clear_graphs = QPushButton('Clear Graphs') self.btn_calibration = QPushButton('Calibration...') self.btn_calibration.clicked.connect(self.btn_calibration_clicked) self.lbl_temperature_value = QLabel('-') self.sbox_reference_air_pressure = QDoubleSpinBox() self.sbox_reference_air_pressure.setMinimum(260) self.sbox_reference_air_pressure.setMaximum(1260) self.sbox_reference_air_pressure.setDecimals(3) self.sbox_reference_air_pressure.setValue(1013.25) self.sbox_reference_air_pressure.setSingleStep(1) self.btn_use_current = QPushButton('Use Current') self.btn_use_current.clicked.connect(self.btn_use_current_clicked) self.sbox_reference_air_pressure.editingFinished.connect( self.sbox_reference_air_pressure_editing_finished) self.sbox_moving_avg_len_air_pressure = QSpinBox() self.sbox_moving_avg_len_air_pressure.setMinimum(1) self.sbox_moving_avg_len_air_pressure.setMaximum(1000) self.sbox_moving_avg_len_air_pressure.setSingleStep(1) self.sbox_moving_avg_len_air_pressure.setValue(100) self.sbox_moving_avg_len_air_pressure.editingFinished.connect( self.sbox_moving_avg_len_editing_finished) self.sbox_moving_avg_len_temperature = QSpinBox() self.sbox_moving_avg_len_temperature.setMinimum(1) self.sbox_moving_avg_len_temperature.setMaximum(1000) self.sbox_moving_avg_len_temperature.setSingleStep(1) self.sbox_moving_avg_len_temperature.setValue(100) self.sbox_moving_avg_len_temperature.editingFinished.connect( self.sbox_moving_avg_len_editing_finished) plot_config_air_pressure = [ ('Air Pressure', Qt.red, lambda: self.current_air_pressure, '{:.3f} mbar (QFE)'.format) ] plot_config_altitude = [( 'Altitude', Qt.darkGreen, lambda: self.current_altitude, lambda value: '{:.3f} m ({:.3f} ft)'.format(value, value / 0.3048)) ] self.plot_widget_air_pressure = PlotWidget('Air Pressure [mbar]', plot_config_air_pressure, self.btn_clear_graphs) self.plot_widget_altitude = PlotWidget('Altitude [m]', plot_config_altitude, self.btn_clear_graphs) self.combo_data_rate = QComboBox() self.combo_data_rate.addItem('Off', BrickletBarometerV2.DATA_RATE_OFF) self.combo_data_rate.addItem('1 Hz', BrickletBarometerV2.DATA_RATE_1HZ) self.combo_data_rate.addItem('10 Hz', BrickletBarometerV2.DATA_RATE_10HZ) self.combo_data_rate.addItem('25 Hz', BrickletBarometerV2.DATA_RATE_25HZ) self.combo_data_rate.addItem('50 Hz', BrickletBarometerV2.DATA_RATE_50HZ) self.combo_data_rate.addItem('75 Hz', BrickletBarometerV2.DATA_RATE_75HZ) self.combo_data_rate.currentIndexChanged.connect( self.new_sensor_config) self.combo_air_pressure_low_pass_filter = QComboBox() self.combo_air_pressure_low_pass_filter.addItem( 'Off', BrickletBarometerV2.LOW_PASS_FILTER_OFF) self.combo_air_pressure_low_pass_filter.addItem( '1/9th', BrickletBarometerV2.LOW_PASS_FILTER_1_9TH) self.combo_air_pressure_low_pass_filter.addItem( '1/20th', BrickletBarometerV2.LOW_PASS_FILTER_1_20TH) self.combo_air_pressure_low_pass_filter.currentIndexChanged.connect( self.new_sensor_config) # Layout layout_h1 = QHBoxLayout() layout_h1.addWidget(self.plot_widget_air_pressure) layout_h1.addWidget(self.plot_widget_altitude) layout = QVBoxLayout(self) layout.addLayout(layout_h1) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout.addWidget(line) layout_h2 = QHBoxLayout() layout_h2.addWidget(QLabel('Reference Air Pressure [mbar]:')) layout_h2.addWidget(self.sbox_reference_air_pressure) layout_h2.addWidget(self.btn_use_current) layout_h2.addStretch() layout_h2.addWidget(QLabel('Temperature:')) layout_h2.addWidget(self.lbl_temperature_value) layout_h2.addStretch() layout_h2.addWidget(self.btn_clear_graphs) layout.addLayout(layout_h2) layout_h3 = QHBoxLayout() layout_h3.addWidget(QLabel('Air Pressure Moving Average Length:')) layout_h3.addWidget(self.sbox_moving_avg_len_air_pressure) layout_h3.addStretch() layout_h3.addWidget(QLabel('Temperature Moving Average Length:')) layout_h3.addWidget(self.sbox_moving_avg_len_temperature) layout.addLayout(layout_h3) layout_h4 = QHBoxLayout() layout_h4.addWidget(QLabel('Data Rate:')) layout_h4.addWidget(self.combo_data_rate) layout_h4.addStretch() layout_h4.addWidget(QLabel('Air Pressure Low Pass Filter:')) layout_h4.addWidget(self.combo_air_pressure_low_pass_filter) layout_h4.addStretch() layout_h4.addWidget(self.btn_calibration) layout.addLayout(layout_h4) def start(self): async_call(self.barometer.get_air_pressure, None, self.cb_get_air_pressure, self.increase_error_count) async_call(self.barometer.get_altitude, None, self.cb_get_altitude, self.increase_error_count) async_call(self.barometer.get_temperature, None, self.cb_get_temperature, self.increase_error_count) async_call(self.barometer.get_reference_air_pressure, None, self.get_reference_air_pressure_async, self.increase_error_count) async_call(self.barometer.get_moving_average_configuration, None, self.get_moving_average_configuration_async, self.increase_error_count) async_call(self.barometer.get_sensor_configuration, None, self.get_sensor_configuration_async, self.increase_error_count) self.cbe_air_pressure.set_period(50) self.cbe_altitude.set_period(50) self.cbe_temperature.set_period(100) self.plot_widget_air_pressure.stop = False self.plot_widget_altitude.stop = False def stop(self): self.cbe_air_pressure.set_period(0) self.cbe_altitude.set_period(0) self.cbe_temperature.set_period(0) self.plot_widget_air_pressure.stop = True self.plot_widget_altitude.stop = True def destroy(self): if self.calibration != None: self.calibration.close() @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletBarometerV2.DEVICE_IDENTIFIER def cb_get_air_pressure(self, air_pressure): self.current_air_pressure = air_pressure / 1000.0 def cb_get_altitude(self, altitude): self.current_altitude = altitude / 1000.0 def cb_get_temperature(self, temperature): self.current_temperature = temperature / 100.0 self.lbl_temperature_value.setText(u'{:.2f} °C'.format( self.current_temperature)) def get_reference_air_pressure_async(self, air_pressure): self.sbox_reference_air_pressure.setValue(air_pressure / 1000.0) def btn_use_current_clicked(self): self.barometer.set_reference_air_pressure(0) async_call(self.barometer.get_reference_air_pressure, None, self.get_reference_air_pressure_async, self.increase_error_count) def sbox_reference_air_pressure_editing_finished(self): self.barometer.set_reference_air_pressure( self.sbox_reference_air_pressure.value() * 1000.0) def get_moving_average_configuration_async(self, avg): m_avg_air_pressure, m_avg_temperature = avg self.sbox_moving_avg_len_air_pressure.setValue(m_avg_air_pressure) self.sbox_moving_avg_len_temperature.setValue(m_avg_temperature) def sbox_moving_avg_len_editing_finished(self): self.barometer.set_moving_average_configuration( self.sbox_moving_avg_len_air_pressure.value(), self.sbox_moving_avg_len_temperature.value()) def get_sensor_configuration_async(self, config): data_rate, air_pressure_low_pass_filter = config self.combo_data_rate.setCurrentIndex( self.combo_data_rate.findData(data_rate)) self.combo_air_pressure_low_pass_filter.setCurrentIndex( self.combo_air_pressure_low_pass_filter.findData( air_pressure_low_pass_filter)) def new_sensor_config(self): data_rate = self.combo_data_rate.itemData( self.combo_data_rate.currentIndex()) air_pressure_low_pass_filter = self.combo_air_pressure_low_pass_filter.itemData( self.combo_air_pressure_low_pass_filter.currentIndex()) self.barometer.set_sensor_configuration(data_rate, air_pressure_low_pass_filter) def btn_calibration_clicked(self): if self.calibration == None: self.calibration = Calibration(self) self.btn_calibration.setEnabled(False) self.calibration.show()
class AnalogIn(PluginBase): def __init__(self, *args): PluginBase.__init__(self, BrickletAnalogIn, *args) self.ai = self.device self.cbe_voltage = CallbackEmulator(self.ai.get_voltage, self.cb_voltage, self.increase_error_count) self.current_voltage = None # float, V plots = [('Voltage', Qt.red, lambda: self.current_voltage, format_voltage)] self.plot_widget = PlotWidget('Voltage [V]', plots) layout = QVBoxLayout(self) layout.addWidget(self.plot_widget) if self.firmware_version >= (2, 0, 1): self.combo_range = QComboBox() self.combo_range.addItem('Automatic', BrickletAnalogIn.RANGE_AUTOMATIC) if self.firmware_version >= (2, 0, 3): self.combo_range.addItem('0 - 3.30 V', BrickletAnalogIn.RANGE_UP_TO_3V) self.combo_range.addItem('0 - 6.05 V', BrickletAnalogIn.RANGE_UP_TO_6V) self.combo_range.addItem('0 - 10.32 V', BrickletAnalogIn.RANGE_UP_TO_10V) self.combo_range.addItem('0 - 36.30 V', BrickletAnalogIn.RANGE_UP_TO_36V) self.combo_range.addItem('0 - 45.00 V', BrickletAnalogIn.RANGE_UP_TO_45V) self.combo_range.currentIndexChanged.connect(self.range_changed) hlayout = QHBoxLayout() hlayout.addWidget(QLabel('Range:')) hlayout.addWidget(self.combo_range) hlayout.addStretch() if self.firmware_version >= (2, 0, 3): self.spin_average = QSpinBox() self.spin_average.setMinimum(0) self.spin_average.setMaximum(255) self.spin_average.setSingleStep(1) self.spin_average.setValue(50) self.spin_average.editingFinished.connect( self.spin_average_finished) hlayout.addWidget(QLabel('Average Length:')) hlayout.addWidget(self.spin_average) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout.addWidget(line) layout.addLayout(hlayout) def get_range_async(self, range_): self.combo_range.setCurrentIndex(self.combo_range.findData(range_)) def get_averaging_async(self, average): self.spin_average.setValue(average) def start(self): if self.firmware_version >= (2, 0, 1): async_call(self.ai.get_range, None, self.get_range_async, self.increase_error_count) if self.firmware_version >= (2, 0, 3): async_call(self.ai.get_averaging, None, self.get_averaging_async, self.increase_error_count) async_call(self.ai.get_voltage, None, self.cb_voltage, self.increase_error_count) self.cbe_voltage.set_period(100) self.plot_widget.stop = False def stop(self): self.cbe_voltage.set_period(0) self.plot_widget.stop = True def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletAnalogIn.DEVICE_IDENTIFIER def cb_voltage(self, voltage): self.current_voltage = voltage / 1000.0 def range_changed(self, index): if index >= 0 and self.firmware_version >= (2, 0, 1): range_ = self.combo_range.itemData(index) async_call(self.ai.set_range, range_, None, self.increase_error_count) def spin_average_finished(self): self.ai.set_averaging(self.spin_average.value())
class AnalogIn(PluginBase): def __init__(self, *args): PluginBase.__init__(self, BrickletAnalogIn, *args) self.ai = self.device self.cbe_voltage = CallbackEmulator(self.ai.get_voltage, self.cb_voltage, self.increase_error_count) self.voltage_label = VoltageLabel('Voltage: ') self.current_value = None plot_list = [['', Qt.red, self.get_current_value]] self.plot_widget = PlotWidget('Voltage [mV]', plot_list) layout_h2 = QHBoxLayout() layout_h2.addStretch() layout_h2.addWidget(self.voltage_label) layout_h2.addStretch() layout = QVBoxLayout(self) layout.addLayout(layout_h2) layout.addWidget(self.plot_widget) if self.firmware_version >= (2, 0, 1): self.combo_range = QComboBox() self.combo_range.addItem('Automatic', BrickletAnalogIn.RANGE_AUTOMATIC) if self.firmware_version >= (2, 0, 3): self.combo_range.addItem('0V - 3.30V', BrickletAnalogIn.RANGE_UP_TO_3V) self.combo_range.addItem('0V - 6.05V', BrickletAnalogIn.RANGE_UP_TO_6V) self.combo_range.addItem('0V - 10.32V', BrickletAnalogIn.RANGE_UP_TO_10V) self.combo_range.addItem('0V - 36.30V', BrickletAnalogIn.RANGE_UP_TO_36V) self.combo_range.addItem('0V - 45.00V', BrickletAnalogIn.RANGE_UP_TO_45V) self.combo_range.currentIndexChanged.connect(self.range_changed) layout_h1 = QHBoxLayout() layout_h1.addStretch() layout_h1.addWidget(QLabel('Range:')) layout_h1.addWidget(self.combo_range) if self.firmware_version >= (2, 0, 3): self.spin_average = QSpinBox() self.spin_average.setMinimum(0) self.spin_average.setMaximum(255) self.spin_average.setSingleStep(1) self.spin_average.setValue(50) self.spin_average.editingFinished.connect( self.spin_average_finished) layout_h1.addStretch() layout_h1.addWidget(QLabel('Average Length:')) layout_h1.addWidget(self.spin_average) layout_h1.addStretch() layout.addLayout(layout_h1) def get_range_async(self, range_): self.combo_range.setCurrentIndex(self.combo_range.findData(range_)) def get_averaging_async(self, average): self.spin_average.setValue(average) def start(self): if self.firmware_version >= (2, 0, 1): async_call(self.ai.get_range, None, self.get_range_async, self.increase_error_count) if self.firmware_version >= (2, 0, 3): async_call(self.ai.get_averaging, None, self.get_averaging_async, self.increase_error_count) async_call(self.ai.get_voltage, None, self.cb_voltage, self.increase_error_count) self.cbe_voltage.set_period(100) self.plot_widget.stop = False def stop(self): self.cbe_voltage.set_period(0) self.plot_widget.stop = True def destroy(self): pass def get_url_part(self): return 'analog_in' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletAnalogIn.DEVICE_IDENTIFIER def get_current_value(self): return self.current_value def cb_voltage(self, voltage): self.current_value = voltage self.voltage_label.setText(str(voltage / 1000.0)) def range_changed(self, index): if index >= 0 and self.firmware_version >= (2, 0, 1): range_ = self.combo_range.itemData(index) async_call(self.ai.set_range, range_, None, self.increase_error_count) def spin_average_finished(self): self.ai.set_averaging(self.spin_average.value())
class QualityDialog(QDialog): def __init__(self, parent, params): QDialog.__init__(self, parent) self.parent = parent self.params = params self.setMinimumWidth(min_width) # self.setMinimumHeight(min_height) # Build dialog self.setWindowTitle('Options - Quality') # TODO: softcode self.setWindowModality(QtCore.Qt.ApplicationModal) self.fra_form = QFrame(self) fra_form_lay = QFormLayout(self.fra_form) fra_form_lay.setContentsMargins(10, 10, 10, 10) self.lbl_parameter = QLabel('Parameter:') # TODO: softocode self.cbo_parameter = QComboBox() fra_form_lay.addRow(self.lbl_parameter, self.cbo_parameter) self.lbl_mass_units = QLabel('Mass units:') # TODO: softocode self.cbo_mass_units = QComboBox() fra_form_lay.addRow(self.lbl_mass_units, self.cbo_mass_units) self.lbl_rel_diff = QLabel('Relative diffusivity:') # TODO: softocode self.txt_rel_diff = QLineEdit() fra_form_lay.addRow(self.lbl_rel_diff, self.txt_rel_diff) self.lbl_trace_node = QLabel('Trace node:') # TODO: softocode self.txt_trace_node = QLineEdit() fra_form_lay.addRow(self.lbl_trace_node, self.txt_trace_node) self.lbl_quality_tol = QLabel('Quality tolerance:') # TODO: softocode self.txt_quality_tol = QLineEdit() fra_form_lay.addRow(self.lbl_quality_tol, self.txt_quality_tol) # Buttons self.fra_buttons = QFrame(self) fra_buttons_lay = QHBoxLayout(self.fra_buttons) self.btn_Ok = QPushButton('OK') self.btn_Cancel = QPushButton('Cancel') fra_buttons_lay.addWidget(self.btn_Ok) fra_buttons_lay.addWidget(self.btn_Cancel) # Add to main fra_main_lay = QVBoxLayout(self) fra_main_lay.setContentsMargins(0, 0, 0, 0) fra_main_lay.addWidget(self.fra_form) fra_main_lay.addWidget(self.fra_buttons) self.setup() def setup(self): for key, value in self.params.options.quality.quality_text.iteritems(): self.cbo_parameter.addItem(value, key) for key, value in self.params.options.quality.quality_units_text.iteritems( ): self.cbo_mass_units.addItem(value, key) # Buttons self.btn_Cancel.clicked.connect(self.btn_cancel_clicked) self.btn_Ok.clicked.connect(self.btn_ok_clicked) # Validators self.txt_rel_diff.setValidator(RegExValidators.get_pos_decimals()) self.txt_quality_tol.setValidator(RegExValidators.get_pos_decimals()) def show(self): super(QualityDialog, self).show() self.cbo_parameter.setCurrentIndex( self.cbo_parameter.findData(self.params.options.quality.parameter)) self.cbo_mass_units.setCurrentIndex( self.cbo_mass_units.findData( self.params.options.quality.mass_units)) self.txt_rel_diff.setText( str(self.params.options.quality.relative_diff)) self.txt_trace_node.setText( str(self.params.options.quality.trace_junction_id)) self.txt_quality_tol.setText( str(self.params.options.quality.quality_tol)) def btn_cancel_clicked(self): self.setVisible(False) def btn_ok_clicked(self): # Update parameters and options self.params.options.quality.parameter = self.cbo_parameter.itemData( self.cbo_parameter.currentIndex()) self.params.options.quality.mass_units = self.cbo_mass_units.itemData( self.cbo_mass_units.currentIndex()) self.params.options.quality.relative_diff = float( self.txt_rel_diff.text()) self.params.options.quality.trace_junction_id = self.txt_trace_node.text( ) self.params.options.quality.quality_tol = float( self.txt_quality_tol.text()) self.setVisible(False)
class ConfigPage(QWizardPage): def __init__(self, parent): QWizardPage.__init__(self, parent) layout = QFormLayout(self) config = QHAObject.getInstance().hacfg self.setTitle(tr("High Availability Configuration")) self.ha_type = QComboBox() # primary / secondary self.ha_type.addItem(tr('Disabled'), QVariant(ENOHA)) self.ha_type.addItem(tr('Primary'), QVariant(PENDING_PRIMARY)) self.ha_type.addItem(tr('Secondary'), QVariant(PENDING_SECONDARY)) index = self.ha_type.findData(QVariant(config.ha_type)) self.ha_type.setCurrentIndex(index) layout.addRow(tr('Status of this cluster member:'), self.ha_type) self.registerField('type', self.ha_type) self.interface = InterfaceChoice(self.selectInterface, self) self.label_interface = QLabel(tr('Interface')) layout.addRow(self.label_interface, self.interface) self.registerField('interface', self.interface) self.connect(self.ha_type, SIGNAL('currentIndexChanged(int)'), self.toggleType) self.toggleType(index) if config.ha_type != ENOHA: message = tr("'%s' already configured as '%s'.") % (config.interface_id, config.ha_type) message += '<br />' message += tr("The configuration for this interface will be cleared.") warning_message = MessageArea() warning_message.setMessage(tr("Warning"), message, status=MessageArea.WARNING) layout.addRow(warning_message) def selectInterface(self, interface): return interface.canReserve() or interface.hasHA() def toggleType(self, index): selected_type = self.ha_type.itemData(index) self.interface.setVisible(selected_type.toString() != ENOHA) self.label_interface.setVisible(selected_type.toString() != ENOHA) def validatePage(self): type_index, is_ok = self.field('type').toInt() ha_type = unicode(self.ha_type.itemData(type_index).toString()) if QHAObject.getInstance().cfg.ha_type == SECONDARY and ha_type == ENOHA: #SECONDARY -> ENOHA is forbidden #when PRIMARY, this wizard is not even displayed QMessageBox.warning(self, tr('Invalid configuration'), tr( "In order to fully deconfigure high availability, you " "need to restore this appliance to factory defaults." ) ) return False if ha_type != ENOHA: net_cfg = QNetObject.getInstance().netcfg iface = self.interface.getInterface() iface_id = net_cfg.getHardLabel(iface) iface_name = iface.system_name else: iface_id = None iface_name = None config = HAConf(ha_type=ha_type, interface_id=iface_id, interface_name=iface_name) msg = config.isValidWithMsg() if msg is None: self.config = config else: QMessageBox.warning(self, tr('Invalid configuration'), msg[0] % msg[1:]) if msg is not None: return False if ha_type != PENDING_PRIMARY: return True user_valid = QMessageBox.question( self, tr("Configuring primary appliance. Are you sure?"), "<div>%s<br/>%s<br/>%s<br/>%s</div>" % ( tr( "After this configuration step, <b>you will not be able to " "change the hostname anymore.</b>" ), tr( "Abort now, or reject the saved configuration if you " "need to change the hostname." ), tr("The hostname is currently <i><b>'%(HOSTNAME)s'</b></i>" ) % {'HOSTNAME': QHostnameObject.getInstance().cfg.hostname}, tr("Do you want to continue?"), ), QMessageBox.Yes | QMessageBox.Abort ) return user_valid == QMessageBox.Yes def getData(self): return self.config
class ReportDialog(QDialog): def __init__(self, parent, params): QDialog.__init__(self, parent) self.parent = parent self.params = params self.setMinimumWidth(min_width) # self.setMinimumHeight(min_height) # Build dialog self.setWindowTitle('Options - Report') # TODO: softcode self.setWindowModality(QtCore.Qt.ApplicationModal) self.fra_form = QFrame(self) fra_form_lay = QFormLayout(self.fra_form) fra_form_lay.setContentsMargins(10, 10, 10, 10) self.lbl_status = QLabel('Hydraulic status:') # TODO: softocode self.cbo_status = QComboBox() fra_form_lay.addRow(self.lbl_status, self.cbo_status) self.lbl_summary = QLabel('Summary') # TODO: softocode self.cbo_summary = QComboBox() fra_form_lay.addRow(self.lbl_summary, self.cbo_summary) self.lbl_energy = QLabel('Energy') # TODO: softocode self.cbo_energy = QComboBox() fra_form_lay.addRow(self.lbl_energy, self.cbo_energy) self.lbl_nodes = QLabel('Nodes') # TODO: softocode self.cbo_nodes = QComboBox() fra_form_lay.addRow(self.lbl_nodes, self.cbo_nodes) self.lbl_links = QLabel('Links') # TODO: softocode self.cbo_links = QComboBox() fra_form_lay.addRow(self.lbl_links, self.cbo_links) # Buttons self.fra_buttons = QFrame(self) fra_buttons_lay = QHBoxLayout(self.fra_buttons) self.btn_Ok = QPushButton('OK') self.btn_Cancel = QPushButton('Cancel') fra_buttons_lay.addWidget(self.btn_Ok) fra_buttons_lay.addWidget(self.btn_Cancel) # Add to main fra_main_lay = QVBoxLayout(self) fra_main_lay.setContentsMargins(0, 0, 0, 0) fra_main_lay.addWidget(self.fra_form) fra_main_lay.addWidget(self.fra_buttons) self.setup() def setup(self): # Combos for key, value in Report.status_names.iteritems(): self.cbo_status.addItem(value, key) for key, value in Report.summary_names.iteritems(): self.cbo_summary.addItem(value, key) for key, value in Report.energy_names.iteritems(): self.cbo_energy.addItem(value, key) for key, value in Report.nodes_names.iteritems(): self.cbo_nodes.addItem(value, key) for key, value in Report.links_names.iteritems(): self.cbo_links.addItem(value, key) # Buttons self.btn_Cancel.clicked.connect(self.btn_cancel_clicked) self.btn_Ok.clicked.connect(self.btn_ok_clicked) def show(self): super(ReportDialog, self).show() self.cbo_status.setCurrentIndex( self.cbo_status.findData(self.params.report.status)) self.cbo_summary.setCurrentIndex( self.cbo_summary.findData(self.params.report.summary)) self.cbo_energy.setCurrentIndex( self.cbo_energy.findData(self.params.report.energy)) self.cbo_nodes.setCurrentIndex( self.cbo_nodes.findData(self.params.report.nodes)) self.cbo_links.setCurrentIndex( self.cbo_links.findData(self.params.report.links)) def btn_cancel_clicked(self): self.setVisible(False) def btn_ok_clicked(self): self.params.report.status = self.cbo_status.itemData( self.cbo_status.currentIndex()) self.params.report.summary = self.cbo_summary.itemData( self.cbo_summary.currentIndex()) self.params.report.energy = self.cbo_energy.itemData( self.cbo_energy.currentIndex()) self.params.report.nodes = self.cbo_nodes.itemData( self.cbo_nodes.currentIndex()) self.params.report.links = self.cbo_links.itemData( self.cbo_links.currentIndex()) self.setVisible(False)
class AmbientLightV2(PluginBase): def __init__(self, *args): PluginBase.__init__(self, BrickletAmbientLightV2, *args) self.al = self.device self.has_clamped_output = self.firmware_version >= (2, 0, 2) self.cbe_illuminance = CallbackEmulator(self.al.get_illuminance, self.cb_illuminance, self.increase_error_count) self.alf = AmbientLightFrame() self.out_of_range_label = QLabel("Illuminance is out-of-range") self.saturated_label = QLabel("Sensor is saturated") self.out_of_range_label.hide() self.out_of_range_label.setStyleSheet("QLabel { color: red }") self.saturated_label.hide() self.saturated_label.setStyleSheet("QLabel { color: magenta }") self.current_illuminance = None # float, lx plots = [("Illuminance", Qt.red, lambda: self.current_illuminance, "{:.2f} lx (Lux)".format)] self.plot_widget = PlotWidget( "Illuminance [lx]", plots, extra_key_widgets=[self.out_of_range_label, self.saturated_label, self.alf] ) self.range_label = QLabel("Illuminance Range: ") self.range_combo = QComboBox() if self.has_clamped_output: # Also means that the unlimited range is available self.range_combo.addItem("Unlimited", BrickletAmbientLightV2.ILLUMINANCE_RANGE_UNLIMITED) self.range_combo.addItem("0 - 64000 lx", BrickletAmbientLightV2.ILLUMINANCE_RANGE_64000LUX) self.range_combo.addItem("0 - 32000 lx", BrickletAmbientLightV2.ILLUMINANCE_RANGE_32000LUX) self.range_combo.addItem("0 - 16000 lx", BrickletAmbientLightV2.ILLUMINANCE_RANGE_16000LUX) self.range_combo.addItem("0 - 8000 lx", BrickletAmbientLightV2.ILLUMINANCE_RANGE_8000LUX) self.range_combo.addItem("0 - 1300 lx", BrickletAmbientLightV2.ILLUMINANCE_RANGE_1300LUX) self.range_combo.addItem("0 - 600 lx", BrickletAmbientLightV2.ILLUMINANCE_RANGE_600LUX) self.range_combo.currentIndexChanged.connect(self.new_config) self.time_label = QLabel("Integration Time: ") self.time_combo = QComboBox() self.time_combo.addItem("50 ms", BrickletAmbientLightV2.INTEGRATION_TIME_50MS) self.time_combo.addItem("100 ms", BrickletAmbientLightV2.INTEGRATION_TIME_100MS) self.time_combo.addItem("150 ms", BrickletAmbientLightV2.INTEGRATION_TIME_150MS) self.time_combo.addItem("200 ms", BrickletAmbientLightV2.INTEGRATION_TIME_200MS) self.time_combo.addItem("250 ms", BrickletAmbientLightV2.INTEGRATION_TIME_250MS) self.time_combo.addItem("300 ms", BrickletAmbientLightV2.INTEGRATION_TIME_300MS) self.time_combo.addItem("350 ms", BrickletAmbientLightV2.INTEGRATION_TIME_350MS) self.time_combo.addItem("400 ms", BrickletAmbientLightV2.INTEGRATION_TIME_400MS) self.time_combo.currentIndexChanged.connect(self.new_config) hlayout = QHBoxLayout() hlayout.addWidget(self.range_label) hlayout.addWidget(self.range_combo) hlayout.addStretch() hlayout.addWidget(self.time_label) hlayout.addWidget(self.time_combo) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout = QVBoxLayout(self) layout.addWidget(self.plot_widget) layout.addWidget(line) layout.addLayout(hlayout) def start(self): async_call(self.al.get_configuration, None, self.get_configucation_async, self.increase_error_count) async_call(self.al.get_illuminance, None, self.cb_illuminance, self.increase_error_count) self.cbe_illuminance.set_period(100) self.plot_widget.stop = False def stop(self): self.cbe_illuminance.set_period(0) self.plot_widget.stop = True def destroy(self): pass def get_url_part(self): return "ambient_light_v2" @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletAmbientLightV2.DEVICE_IDENTIFIER def get_configucation_async(self, conf): self.range_combo.setCurrentIndex(self.range_combo.findData(conf.illuminance_range)) self.time_combo.setCurrentIndex(self.time_combo.findData(conf.integration_time)) def new_config(self, value): try: self.al.set_configuration( self.range_combo.itemData(self.range_combo.currentIndex()), self.time_combo.itemData(self.time_combo.currentIndex()), ) except: pass def cb_illuminance(self, illuminance): self.current_illuminance = illuminance / 100.0 max_illuminance = 12000000 # Approximation for unlimited range current_range = self.range_combo.itemData(self.range_combo.currentIndex()) if current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_64000LUX: max_illuminance = 6400001 elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_32000LUX: max_illuminance = 3200001 elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_16000LUX: max_illuminance = 1600001 elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_8000LUX: max_illuminance = 800001 elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_1300LUX: max_illuminance = 130001 elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_600LUX: max_illuminance = 60001 if self.has_clamped_output: # Also means that the unlimited range is available if illuminance == 0: self.plot_widget.get_key_item(0).setStyleSheet("QLabel { color: magenta }") self.out_of_range_label.hide() self.saturated_label.show() elif illuminance >= max_illuminance: self.plot_widget.get_key_item(0).setStyleSheet("QLabel { color: red }") self.out_of_range_label.show() self.saturated_label.hide() else: self.plot_widget.get_key_item(0).setStyleSheet("") self.out_of_range_label.hide() self.saturated_label.hide() value = min(max(illuminance * 255 / max_illuminance, 0), 255) self.alf.set_color(value, value, value)
class ActionBar(QFrame): """ SIGNALS: @changeCurrent(PyQt_PyObject) @runFile(QString) @reopenTab(QString) @recentTabsModified() """ def __init__(self, main_combo=False): super(ActionBar, self).__init__() self.setObjectName("actionbar") hbox = QHBoxLayout(self) hbox.setContentsMargins(1, 1, 1, 1) hbox.setSpacing(1) self.lbl_checks = QLabel('') self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.lbl_checks.setFixedWidth(48) self.lbl_checks.setVisible(False) hbox.addWidget(self.lbl_checks) self.combo = QComboBox() self.combo.setIconSize(QSize(16, 16)) #model = QStandardItemModel() #self.combo.setModel(model) #self.combo.view().setDragDropMode(QAbstractItemView.InternalMove) self.combo.setMaximumWidth(300) self.combo.setObjectName("combotab") self.connect(self.combo, SIGNAL("currentIndexChanged(int)"), self.current_changed) self.combo.setToolTip(translations.TR_COMBO_FILE_TOOLTIP) self.combo.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self.combo, SIGNAL( "customContextMenuRequested(const QPoint &)"), self._context_menu_requested) hbox.addWidget(self.combo) self.symbols_combo = QComboBox() self.symbols_combo.setIconSize(QSize(16, 16)) self.symbols_combo.setObjectName("combo_symbols") self.connect(self.symbols_combo, SIGNAL("activated(int)"), self.current_symbol_changed) hbox.addWidget(self.symbols_combo) self.code_navigator = CodeNavigator() hbox.addWidget(self.code_navigator) self._pos_text = "Line: %d, Col: %d" self.lbl_position = QLabel(self._pos_text % (0, 0)) self.lbl_position.setObjectName("position") self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.lbl_position) self.btn_close = QPushButton( self.style().standardIcon(QStyle.SP_DialogCloseButton), '') self.btn_close.setIconSize(QSize(16, 16)) if main_combo: self.btn_close.setObjectName('navigation_button') self.btn_close.setToolTip(translations.TR_CLOSE_FILE) self.connect(self.btn_close, SIGNAL("clicked()"), self.about_to_close_file) else: self.btn_close.setObjectName('close_split') self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT) self.connect(self.btn_close, SIGNAL("clicked()"), self.close_split) self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.btn_close) def resizeEvent(self, event): super(ActionBar, self).resizeEvent(event) if event.size().width() < 350: self.symbols_combo.hide() self.code_navigator.hide() self.lbl_position.hide() else: self.symbols_combo.show() self.code_navigator.show() self.lbl_position.show() def add_item(self, text, neditable): """Add a new item to the combo and add the neditable data.""" self.combo.addItem(text, neditable) self.combo.setCurrentIndex(self.combo.count() - 1) def get_editables(self): editables = [] for index in range(self.combo.count()): neditable = self.combo.itemData(index) editables.append(neditable) return editables def add_symbols(self, symbols): """Add the symbols to the symbols's combo.""" self.symbols_combo.clear() for symbol in symbols: data = symbol[1] if data[1] == 'f': icon = QIcon(":img/function") else: icon = QIcon(":img/class") self.symbols_combo.addItem(icon, data[0]) def set_current_symbol(self, index): self.symbols_combo.setCurrentIndex(index) def update_item_icon(self, neditable, icon): index = self.combo.findData(neditable) self.combo.setItemIcon(index, icon) def update_item_text(self, neditable, text): index = self.combo.findData(neditable) self.combo.setItemText(index, text) def current_changed(self, index): """Change the current item in the combo.""" neditable = self.combo.itemData(index) self.emit(SIGNAL("changeCurrent(PyQt_PyObject, int)"), neditable, index) def current_symbol_changed(self, index): """Change the current symbol in the combo.""" self.emit(SIGNAL("goToSymbol(int)"), index) def update_line_col(self, line, col): """Update the line and column position.""" self.lbl_position.setText(self._pos_text % (line, col)) def _context_menu_requested(self, point): """Display context menu for the combo file.""" if self.combo.count() == 0: # If there is not an Editor opened, don't show the menu return menu = QMenu() actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT) actionRun = menu.addAction(translations.TR_RUN_FILE) menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX) self._create_menu_syntax(menuSyntax) menu.addSeparator() actionClose = menu.addAction(translations.TR_CLOSE_FILE) actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES) actionCloseAllNotThis = menu.addAction( translations.TR_CLOSE_OTHER_FILES) menu.addSeparator() actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY) actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY) menu.addSeparator() actionCopyPath = menu.addAction( translations.TR_COPY_FILE_PATH_TO_CLIPBOARD) actionReopen = menu.addAction(translations.TR_REOPEN_FILE) actionUndock = menu.addAction(translations.TR_UNDOCK_EDITOR) if len(settings.LAST_OPENED_FILES) == 0: actionReopen.setEnabled(False) #Connect actions self.connect(actionSplitH, SIGNAL("triggered()"), lambda: self._split(False)) self.connect(actionSplitV, SIGNAL("triggered()"), lambda: self._split(True)) self.connect(actionRun, SIGNAL("triggered()"), self._run_this_file) self.connect(actionAdd, SIGNAL("triggered()"), self._add_to_project) self.connect(actionClose, SIGNAL("triggered()"), self.about_to_close_file) self.connect(actionCloseAllNotThis, SIGNAL("triggered()"), self._close_all_files_except_this) self.connect(actionCloseAll, SIGNAL("triggered()"), self._close_all_files) self.connect(actionCopyPath, SIGNAL("triggered()"), self._copy_file_location) self.connect(actionReopen, SIGNAL("triggered()"), self._reopen_last_tab) self.connect(actionUndock, SIGNAL("triggered()"), self._undock_editor) menu.exec_(QCursor.pos()) def _create_menu_syntax(self, menuSyntax): """Create Menu with the list of syntax supported.""" syntax = list(settings.SYNTAX.keys()) syntax.sort() for syn in syntax: menuSyntax.addAction(syn) self.connect(menuSyntax, SIGNAL("triggered(QAction*)"), self._reapply_syntax) def _reapply_syntax(self, syntaxAction): #TODO if [self.currentIndex(), syntaxAction] != self._resyntax: self._resyntax = [self.currentIndex(), syntaxAction] self.emit(SIGNAL("syntaxChanged(QWidget, QString)"), self.currentWidget(), syntaxAction.text()) def set_current_file(self, neditable): index = self.combo.findData(neditable) self.combo.setCurrentIndex(index) def set_current_by_index(self, index): self.combo.setCurrentIndex(index) def about_to_close_file(self, index=None): """Close the NFile object.""" if index is None: index = self.combo.currentIndex() neditable = self.combo.itemData(index) if neditable: neditable.nfile.close() def close_split(self): self.emit(SIGNAL("closeSplit()")) def close_file(self, neditable): """Receive the confirmation to close the file.""" index = self.combo.findData(neditable) self.combo.removeItem(index) return index def _run_this_file(self): """Execute the current file.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("runFile(QString)"), neditable.file_path) def _add_to_project(self): """Emit a signal to let someone handle the inclusion of the file inside a project.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("addToProject(QString)"), neditable.file_path) def _reopen_last_tab(self): self.emit(SIGNAL("reopenTab(QString)"), settings.LAST_OPENED_FILES.pop()) self.emit(SIGNAL("recentTabsModified()")) def _undock_editor(self): self.emit(SIGNAL("undockEditor()")) def _split(self, orientation): self.emit(SIGNAL("splitEditor(bool)"), orientation) def _copy_file_location(self): """Copy the path of the current opened file to the clipboard.""" neditable = self.combo.itemData(self.combo.currentIndex()) QApplication.clipboard().setText(neditable.file_path, QClipboard.Clipboard) def _close_all_files(self): """Close all the files opened.""" for i in range(self.combo.count()): self.about_to_close_file(0) def _close_all_files_except_this(self): """Close all the files except the current one.""" neditable = self.combo.itemData(self.combo.currentIndex()) for i in reversed(list(range(self.combo.count()))): ne = self.combo.itemData(i) if ne is not neditable: self.about_to_close_file(i)
class HexColumnConfigurationWidget(QWidget, columnproviders.AbstractColumnConfigurationWidget): def __init__(self, parent, hex_widget, column): QWidget.__init__(self, parent) columnproviders.AbstractColumnConfigurationWidget.__init__(self) self.hexWidget = hex_widget self.column = column self.setLayout(QFormLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.cmbBinaryFormat = QComboBox(self) self.cmbBinaryFormat.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.layout().addRow(utils.tr('Binary format:'), self.cmbBinaryFormat) self.cmbBinaryFormat.currentIndexChanged[int].connect(self._onBinaryFormatChanged) self.chkSigned = QCheckBox() self.layout().addRow(utils.tr('Signed values:'), self.chkSigned) if column is not None: self.chkSigned.setChecked(column.valuecodec.signed) self.cmbEndianess = QComboBox(self) self.cmbEndianess.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.layout().addRow(utils.tr('Endianess:'), self.cmbEndianess) self.cmbEndianess.addItem(utils.tr('Little endian'), valuecodecs.LittleEndian) self.cmbEndianess.addItem(utils.tr('Big endian'), valuecodecs.BigEndian) if column is not None: self.cmbEndianess.setCurrentIndex(self.cmbEndianess.findData(column.valuecodec.endianess)) else: self.cmbEndianess.setCurrentIndex(0) icodec = valuecodecs.IntegerCodec for fmt in (icodec.Format8Bit, icodec.Format16Bit, icodec.Format32Bit, icodec.Format64Bit): self.cmbBinaryFormat.addItem(icodec.formatName(fmt), fmt) if column is not None and column.valuecodec.binaryFormat == fmt: self.cmbBinaryFormat.setCurrentIndex(self.cmbBinaryFormat.count() - 1) if column is None: self.cmbBinaryFormat.setCurrentIndex(0) self.cmbBase = QComboBox(self) self.cmbBase.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.layout().addRow(utils.tr('Base:'), self.cmbBase) for base in ((utils.tr('Hex'), 16), (utils.tr('Dec'), 10), (utils.tr('Oct'), 8), (utils.tr('Bin'), 2)): self.cmbBase.addItem(base[0], base[1]) if column is not None: self.cmbBase.setCurrentIndex(self.cmbBase.findData(column.formatter.base)) self.spnColumnsOnRow = QSpinBox(self) self.spnColumnsOnRow.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.spnColumnsOnRow.setMinimum(1) self.spnColumnsOnRow.setMaximum(32) self.layout().addRow(utils.tr('Columns on row:'), self.spnColumnsOnRow) if column is not None: self.spnColumnsOnRow.setValue(column.columnsOnRow) else: self.spnColumnsOnRow.setValue(16) def _onBinaryFormatChanged(self, index): self.cmbEndianess.setEnabled(self.cmbBinaryFormat.itemData(index) != valuecodecs.IntegerCodec.Format8Bit) @property def _valueCodec(self): valuecodec = valuecodecs.IntegerCodec() valuecodec.binaryFormat = self.cmbBinaryFormat.itemData(self.cmbBinaryFormat.currentIndex()) valuecodec.signed = self.chkSigned.isChecked() valuecodec.endianess = self.cmbEndianess.itemData(self.cmbEndianess.currentIndex()) return valuecodec @property def _formatter(self): valuecodec = self._valueCodec formatter = formatters.IntegerFormatter() formatter.base = self.cmbBase.itemData(self.cmbBase.currentIndex()) maximal = formatter.format(valuecodec.maximal) minimal = formatter.format(valuecodec.minimal) if minimal.startswith('-'): minimal = minimal[1:] formatter.padding = max(len(maximal), len(minimal)) return formatter def createColumnModel(self, hex_widget): return HexColumnModel(hex_widget.document, self._valueCodec, self._formatter, self.spnColumnsOnRow.value()) def saveToColumn(self, column): column.valuecodec = self._valueCodec column.formatter = self._formatter column.columnsOnRow = self.spnColumnsOnRow.value() column.reset()