class SpinBoxPySlot(UsesQApplication, BasicPySlotCase): """Tests the connection of python slots to QSpinBox signals""" def setUp(self): super(SpinBoxPySlot, self).setUp() self.spin = QSpinBox() def tearDown(self): del self.spin super(SpinBoxPySlot, self).tearDown() def testSpinBoxValueChanged(self): """Connection of a python slot to QSpinBox.valueChanged(int)""" QObject.connect(self.spin, SIGNAL('valueChanged(int)'), self.cb) self.args = [3] self.spin.emit(SIGNAL('valueChanged(int)'), *self.args) self.assert_(self.called) def testSpinBoxValueChangedImplicit(self): """Indirect qt signal emission using QSpinBox.setValue(int)""" QObject.connect(self.spin, SIGNAL('valueChanged(int)'), self.cb) self.args = [42] self.spin.setValue(self.args[0]) self.assert_(self.called) def atestSpinBoxValueChangedFewArgs(self): """Emission of signals with fewer arguments than needed""" # XXX: PyQt4 crashes on the assertRaises QObject.connect(self.spin, SIGNAL('valueChanged(int)'), self.cb) self.args = (554,) self.assertRaises(TypeError, self.spin.emit, SIGNAL('valueChanged(int)'))
def testSpinButton(self): #Connecting a lambda to a QPushButton.clicked() obj = QSpinBox() ctr = Control() arg = 444 func = lambda x: setattr(ctr, 'arg', 444) QObject.connect(obj, SIGNAL('valueChanged(int)'), func) obj.setValue(444) self.assertEqual(ctr.arg, arg) QObject.disconnect(obj, SIGNAL('valueChanged(int)'), func)
def testSetValueIndirect(self): """Indirect signal emission: QSpinBox using valueChanged(int)/setValue(int)""" spinSend = QSpinBox() spinRec = QSpinBox() spinRec.setValue(5) QObject.connect(spinSend, SIGNAL('valueChanged(int)'), spinRec, SLOT('setValue(int)')) self.assertEqual(spinRec.value(), 5) spinSend.setValue(3) self.assertEqual(spinRec.value(), 3) self.assertEqual(spinSend.value(), 3)
class SpinBoxPySignal(UsesQApplication): """Tests the connection of python signals to QSpinBox qt slots.""" def setUp(self): super(SpinBoxPySignal, self).setUp() self.obj = Dummy() self.spin = QSpinBox() self.spin.setValue(0) def tearDown(self): super(SpinBoxPySignal, self).tearDown() del self.obj del self.spin def testValueChanged(self): """Emission of a python signal to QSpinBox setValue(int)""" QObject.connect(self.obj, SIGNAL("dummy(int)"), self.spin, SLOT("setValue(int)")) self.assertEqual(self.spin.value(), 0) self.obj.emit(SIGNAL("dummy(int)"), 4) self.assertEqual(self.spin.value(), 4) def testValueChangedMultiple(self): """Multiple emissions of a python signal to QSpinBox setValue(int)""" QObject.connect(self.obj, SIGNAL("dummy(int)"), self.spin, SLOT("setValue(int)")) self.assertEqual(self.spin.value(), 0) self.obj.emit(SIGNAL("dummy(int)"), 4) self.assertEqual(self.spin.value(), 4) self.obj.emit(SIGNAL("dummy(int)"), 77) self.assertEqual(self.spin.value(), 77)
class EventPropertiesDialog(QDialog): def __init__(self): super().__init__(GlobalAccess().get_main_window()) def exec_(self): self.init_ui() return super().exec_() def init_ui(self): self.setFixedWidth(500) self.setWindowTitle(_('Event properties')) self.setWindowIcon(QIcon(config.ICON)) self.setSizeGripEnabled(False) self.setModal(True) self.layout = QFormLayout(self) self.label_main_title = QLabel(_('Main title')) self.item_main_title = QLineEdit() self.layout.addRow(self.label_main_title, self.item_main_title) self.label_sub_title = QLabel(_('Sub title')) self.item_sub_title = QTextEdit() self.item_sub_title.setMaximumHeight(100) self.layout.addRow(self.label_sub_title, self.item_sub_title) self.label_start_date = QLabel(_('Start date')) self.item_start_date = QDateTimeEdit() self.item_start_date.setDisplayFormat('yyyy.MM.dd HH:mm:ss') self.layout.addRow(self.label_start_date, self.item_start_date) self.label_end_date = QLabel(_('End date')) # self.item_end_date = QCalendarWidget() self.item_end_date = QDateTimeEdit() self.item_end_date.setDisplayFormat('yyyy.MM.dd HH:mm:ss') self.layout.addRow(self.label_end_date, self.item_end_date) self.label_location = QLabel(_('Location')) self.item_location = QLineEdit() self.layout.addRow(self.label_location, self.item_location) self.label_type = QLabel(_('Event type')) self.item_type = AdvComboBox() self.item_type.addItems(RaceType.get_titles()) self.layout.addRow(self.label_type, self.item_type) self.label_relay_legs = QLabel(_('Relay legs')) self.item_relay_legs = QSpinBox() self.item_relay_legs.setMinimum(1) self.item_relay_legs.setMaximum(20) self.item_relay_legs.setValue(3) self.layout.addRow(self.label_relay_legs, self.item_relay_legs) self.item_type.currentTextChanged.connect(self.change_type) self.label_refery = QLabel(_('Chief referee')) self.item_refery = QLineEdit() self.layout.addRow(self.label_refery, self.item_refery) self.label_secretary = QLabel(_('Secretary')) self.item_secretary = QLineEdit() self.layout.addRow(self.label_secretary, self.item_secretary) self.label_url = QLabel(_('URL')) self.item_url = QLineEdit() self.layout.addRow(self.label_url, self.item_url) def cancel_changes(): self.close() def apply_changes(): try: self.apply_changes_impl() except Exception as e: logging.error(str(e)) self.close() button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_ok = button_box.button(QDialogButtonBox.Ok) self.button_ok.setText(_('OK')) self.button_ok.clicked.connect(apply_changes) self.button_cancel = button_box.button(QDialogButtonBox.Cancel) self.button_cancel.setText(_('Cancel')) self.button_cancel.clicked.connect(cancel_changes) self.layout.addRow(button_box) self.set_values_from_model() self.show() def change_type(self): flag = self.item_type.currentText() == RaceType.RELAY.get_title() self.label_relay_legs.setVisible(flag) self.item_relay_legs.setVisible(flag) def set_values_from_model(self): obj = race() self.item_main_title.setText(str(obj.data.title)) self.item_sub_title.setText(str(obj.data.description)) self.item_location.setText(str(obj.data.location)) self.item_url.setText(str(obj.data.url)) self.item_refery.setText(str(obj.data.chief_referee)) self.item_secretary.setText(str(obj.data.secretary)) self.item_start_date.setDateTime(obj.data.get_start_datetime()) self.item_end_date.setDateTime(obj.data.get_end_datetime()) self.item_type.setCurrentText(obj.data.race_type.get_title()) self.item_relay_legs.setValue(obj.data.relay_leg_count) self.change_type() def apply_changes_impl(self): obj = race() start_date = self.item_start_date.dateTime().toPython() end_date = self.item_end_date.dateTime().toPython() obj.data.title = self.item_main_title.text() obj.data.description = self.item_sub_title.toPlainText() obj.data.description = obj.data.description.replace('\n', '<br>\n') obj.data.location = self.item_location.text() obj.data.url = self.item_url.text() obj.data.chief_referee = self.item_refery.text() obj.data.secretary = self.item_secretary.text() obj.data.start_datetime = start_date obj.data.end_datetime = end_date t = RaceType.get_by_name(self.item_type.currentText()) if t is not None: obj.data.race_type = t obj.data.relay_leg_count = self.item_relay_legs.value() obj.set_setting('system_zero_time', (start_date.hour, start_date.minute, 0)) ResultCalculation(race()).process_results() GlobalAccess().get_main_window().set_title()
class PresetItemPool(PresetTab, Ui_PresetItemPool): _boxes_for_category: Dict[ItemCategory, Tuple[QGroupBox, QGridLayout, Dict[MajorItem, ItemConfigurationWidget]]] _default_items: Dict[ItemCategory, QtWidgets.QComboBox] _ammo_maximum_spinboxes: Dict[int, List[QSpinBox]] _ammo_pickup_widgets: Dict[Ammo, AmmoPickupWidgets] _progressive_widgets: List[ProgressiveItemWidget] _split_ammo_widgets: List[SplitAmmoWidget] def __init__(self, editor: PresetEditor): super().__init__() self.setupUi(self) self._editor = editor size_policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self.item_pool_layout.setAlignment(Qt.AlignTop) # Relevant Items self.game = editor.game self.game_description = default_database.game_description_for( self.game) item_database = default_database.item_database_for_game(self.game) self._energy_tank_item = item_database.major_items["Energy Tank"] self._register_random_starting_events() self._create_categories_boxes(item_database, size_policy) self._create_customizable_default_items(item_database) self._create_progressive_widgets(item_database) self._create_major_item_boxes(item_database, self.game_description.resource_database) self._create_energy_tank_box() self._create_split_ammo_widgets(item_database) self._create_ammo_pickup_boxes(size_policy, item_database) @property def uses_patches_tab(self) -> bool: return False def on_preset_changed(self, preset: Preset): # Item alternatives layout = preset.configuration major_configuration = layout.major_items_configuration for progressive_widget in self._progressive_widgets: progressive_widget.on_preset_changed( preset, self._boxes_for_category[ progressive_widget.progressive_item.item_category][2], ) for split_ammo in self._split_ammo_widgets: split_ammo.on_preset_changed(preset, self._ammo_pickup_widgets) # Random Starting Items self.minimum_starting_spinbox.setValue( major_configuration.minimum_random_starting_items) self.maximum_starting_spinbox.setValue( major_configuration.maximum_random_starting_items) # Default Items for category, default_item in major_configuration.default_items.items( ): combo = self._default_items[category] combo.setCurrentIndex(combo.findData(default_item)) for item, widget in self._boxes_for_category[category][2].items(): widget.setEnabled(default_item != item) # Major Items for _, _, elements in self._boxes_for_category.values(): for major_item, widget in elements.items(): widget.state = major_configuration.items_state[major_item] # Energy Tank energy_tank_state = major_configuration.items_state[ self._energy_tank_item] self.energy_tank_starting_spinbox.setValue( energy_tank_state.num_included_in_starting_items) self.energy_tank_shuffled_spinbox.setValue( energy_tank_state.num_shuffled_pickups) # Ammo ammo_provided = major_configuration.calculate_provided_ammo() ammo_configuration = layout.ammo_configuration for ammo_item, maximum in ammo_configuration.maximum_ammo.items(): for spinbox in self._ammo_maximum_spinboxes[ammo_item]: spinbox.setValue(maximum) previous_pickup_for_item = {} resource_database = self.game_description.resource_database item_for_index: Dict[int, ItemResourceInfo] = { ammo_index: resource_database.get_item(ammo_index) for ammo_index in ammo_provided.keys() } for ammo, state in ammo_configuration.items_state.items(): widgets = self._ammo_pickup_widgets[ammo] widgets.pickup_spinbox.setValue(state.pickup_count) if widgets.require_major_item_check is not None: widgets.require_major_item_check.setChecked( state.requires_major_item) try: if state.pickup_count == 0: widgets.expected_count.setText( "No expansions will be created.") continue ammo_per_pickup = items_for_ammo( ammo, state, ammo_provided, previous_pickup_for_item, ammo_configuration.maximum_ammo) totals = functools.reduce( lambda a, b: [x + y for x, y in zip(a, b)], ammo_per_pickup, [0 for _ in ammo.items]) if {total % state.pickup_count for total in totals} == {0}: count_text_template = _EXPECTED_COUNT_TEXT_TEMPLATE_EXACT else: count_text_template = _EXPECTED_COUNT_TEXT_TEMPLATE widgets.expected_count.setText( count_text_template.format( per_expansion=" and ".join( "{:.3g} {}".format( total / state.pickup_count, item_for_index[ammo_index].long_name) for ammo_index, total in zip(ammo.items, totals)), total=" and ".join( "{} {}".format( total, item_for_index[ammo_index].long_name) for ammo_index, total in zip(ammo.items, totals)), from_items=" and ".join("{} {}".format( ammo_provided[ammo_index], item_for_index[ammo_index].long_name) for ammo_index in ammo.items), )) except InvalidConfiguration as invalid_config: widgets.expected_count.setText(str(invalid_config)) # Item pool count try: pool_items, maximum_size = pool_creator.calculate_pool_item_count( layout) self.item_pool_count_label.setText("Items in pool: {}/{}".format( pool_items, maximum_size)) common_qt_lib.set_error_border_stylesheet( self.item_pool_count_label, pool_items > maximum_size) except InvalidConfiguration as invalid_config: self.item_pool_count_label.setText( "Invalid Configuration: {}".format(invalid_config)) common_qt_lib.set_error_border_stylesheet( self.item_pool_count_label, True) # Item Alternatives def _persist_bool_layout_field(self, field_name: str): def bound(value: int): with self._editor as options: options.set_configuration_field(field_name, bool(value)) return bound def _persist_bool_major_configuration_field(self, field_name: str): def bound(value: int): with self._editor as options: kwargs = {field_name: bool(value)} options.major_items_configuration = dataclasses.replace( options.major_items_configuration, **kwargs) return bound # Random Starting def _register_random_starting_events(self): self.minimum_starting_spinbox.valueChanged.connect( self._on_update_minimum_starting) self.maximum_starting_spinbox.valueChanged.connect( self._on_update_maximum_starting) def _on_update_minimum_starting(self, value: int): with self._editor as options: options.major_items_configuration = dataclasses.replace( options.major_items_configuration, minimum_random_starting_items=value) def _on_update_maximum_starting(self, value: int): with self._editor as options: options.major_items_configuration = dataclasses.replace( options.major_items_configuration, maximum_random_starting_items=value) # Major Items def _create_progressive_widgets(self, item_database: ItemDatabase): self._progressive_widgets = [] all_progressive = [] if self.game == RandovaniaGame.PRIME2: all_progressive.append(( "Progressive Suit", ("Dark Suit", "Light Suit"), )) all_progressive.append(( "Progressive Grapple", ("Grapple Beam", "Screw Attack"), )) elif self.game == RandovaniaGame.PRIME3: all_progressive.append(( "Progressive Missile", ("Ice Missile", "Seeker Missile"), )) all_progressive.append(( "Progressive Beam", ("Plasma Beam", "Nova Beam"), )) for (progressive_item_name, non_progressive_items) in all_progressive: progressive_item = item_database.major_items[progressive_item_name] parent, layout, _ = self._boxes_for_category[ progressive_item.item_category] widget = ProgressiveItemWidget( parent, self._editor, progressive_item=progressive_item, non_progressive_items=[ item_database.major_items[it] for it in non_progressive_items ], ) widget.setText("Use progressive {}".format( " → ".join(non_progressive_items))) self._progressive_widgets.append(widget) layout.addWidget(widget) def _create_split_ammo_widgets(self, item_database: ItemDatabase): parent, layout, _ = self._boxes_for_category[ItemCategory.BEAM] self._split_ammo_widgets = [] if self.game == RandovaniaGame.PRIME2: beam_ammo = SplitAmmoWidget( parent, self._editor, unified_ammo=item_database.ammo["Beam Ammo Expansion"], split_ammo=[ item_database.ammo["Dark Ammo Expansion"], item_database.ammo["Light Ammo Expansion"], ], ) beam_ammo.setText("Split Beam Ammo Expansions") self._split_ammo_widgets.append(beam_ammo) if self._split_ammo_widgets: line = QtWidgets.QFrame(parent) line.setFrameShape(QtWidgets.QFrame.HLine) line.setFrameShadow(QtWidgets.QFrame.Sunken) layout.addWidget(line, layout.rowCount(), 0, 1, -1) for widget in self._split_ammo_widgets: layout.addWidget(widget, layout.rowCount(), 0, 1, -1) def _create_categories_boxes(self, item_database: ItemDatabase, size_policy): self._boxes_for_category = {} categories = set() for major_item in item_database.major_items.values(): if not major_item.required: categories.add(major_item.item_category) all_categories = list(iterate_enum(ItemCategory)) for major_item_category in sorted( categories, key=lambda it: all_categories.index(it)): category_box = QGroupBox(self.scroll_area_contents) category_box.setTitle(major_item_category.long_name) category_box.setSizePolicy(size_policy) category_box.setObjectName(f"category_box {major_item_category}") category_layout = QGridLayout(category_box) category_layout.setObjectName( f"category_layout {major_item_category}") self.item_pool_layout.addWidget(category_box) self._boxes_for_category[ major_item_category] = category_box, category_layout, {} def _create_customizable_default_items(self, item_database: ItemDatabase): self._default_items = {} for category, possibilities in item_database.default_items.items(): parent, layout, _ = self._boxes_for_category[category] label = QtWidgets.QLabel(parent) label.setText(f"Default {category.long_name}") layout.addWidget(label, 0, 0) combo = QtWidgets.QComboBox(parent) for item in possibilities: combo.addItem(item.name, item) combo.currentIndexChanged.connect( partial(self._on_default_item_updated, category, combo)) layout.addWidget(combo, 0, 1) self._default_items[category] = combo def _on_default_item_updated(self, category: ItemCategory, combo: QtWidgets.QComboBox, _): with self._editor as editor: new_config = editor.major_items_configuration new_config = new_config.replace_default_item( category, combo.currentData()) new_config = new_config.replace_state_for_item( combo.currentData(), MajorItemState(num_included_in_starting_items=1)) editor.major_items_configuration = new_config def _create_major_item_boxes(self, item_database: ItemDatabase, resource_database: ResourceDatabase): for major_item in item_database.major_items.values(): if major_item.required or major_item.item_category == ItemCategory.ENERGY_TANK: continue category_box, category_layout, elements = self._boxes_for_category[ major_item.item_category] widget = ItemConfigurationWidget(None, major_item, MajorItemState(), resource_database) widget.Changed.connect(partial(self._on_major_item_updated, widget)) row = category_layout.rowCount() category_layout.addWidget(widget, row, 0, 1, -1) elements[major_item] = widget def _on_major_item_updated(self, item_widget: ItemConfigurationWidget): with self._editor as editor: editor.major_items_configuration = editor.major_items_configuration.replace_state_for_item( item_widget.item, item_widget.state) # Energy Tank def _create_energy_tank_box(self): category_box, category_layout, _ = self._boxes_for_category[ ItemCategory.ENERGY_TANK] starting_label = QLabel(category_box) starting_label.setText("Starting Quantity") shuffled_label = QLabel(category_box) shuffled_label.setText("Shuffled Quantity") self.energy_tank_starting_spinbox = QSpinBox(category_box) self.energy_tank_starting_spinbox.setMaximum(ENERGY_TANK_MAXIMUM_COUNT) self.energy_tank_starting_spinbox.valueChanged.connect( self._on_update_starting_energy_tank) self.energy_tank_shuffled_spinbox = QSpinBox(category_box) self.energy_tank_shuffled_spinbox.setMaximum( DEFAULT_MAXIMUM_SHUFFLED[-1]) self.energy_tank_shuffled_spinbox.valueChanged.connect( self._on_update_shuffled_energy_tank) category_layout.addWidget(starting_label, 0, 0) category_layout.addWidget(self.energy_tank_starting_spinbox, 0, 1) category_layout.addWidget(shuffled_label, 1, 0) category_layout.addWidget(self.energy_tank_shuffled_spinbox, 1, 1) def _on_update_starting_energy_tank(self, value: int): with self._editor as options: major_configuration = options.major_items_configuration options.major_items_configuration = major_configuration.replace_state_for_item( self._energy_tank_item, dataclasses.replace( major_configuration.items_state[self._energy_tank_item], num_included_in_starting_items=value)) def _on_update_shuffled_energy_tank(self, value: int): with self._editor as options: major_configuration = options.major_items_configuration options.major_items_configuration = major_configuration.replace_state_for_item( self._energy_tank_item, dataclasses.replace( major_configuration.items_state[self._energy_tank_item], num_shuffled_pickups=value)) # Ammo def _create_ammo_pickup_boxes(self, size_policy, item_database: ItemDatabase): """ Creates the GroupBox with SpinBoxes for selecting the pickup count of all the ammo :param item_database: :return: """ self._ammo_maximum_spinboxes = collections.defaultdict(list) self._ammo_pickup_widgets = {} resource_database = default_database.resource_database_for(self.game) broad_to_category = { ItemCategory.BEAM_RELATED: ItemCategory.BEAM, ItemCategory.MORPH_BALL_RELATED: ItemCategory.MORPH_BALL, ItemCategory.MISSILE_RELATED: ItemCategory.MISSILE, } for ammo in item_database.ammo.values(): category_box, category_layout, _ = self._boxes_for_category[ broad_to_category[ammo.broad_category]] pickup_box = QGroupBox(category_box) pickup_box.setSizePolicy(size_policy) pickup_box.setTitle(ammo.name + "s") layout = QGridLayout(pickup_box) layout.setObjectName(f"{ammo.name} Box Layout") current_row = 0 for ammo_item in ammo.items: item = resource_database.get_by_type_and_index( ResourceType.ITEM, ammo_item) target_count_label = QLabel(pickup_box) target_count_label.setText(f"{item.long_name} Target" if len( ammo.items) > 1 else "Target count") maximum_spinbox = QSpinBox(pickup_box) maximum_spinbox.setMaximum(ammo.maximum) maximum_spinbox.valueChanged.connect( partial(self._on_update_ammo_maximum_spinbox, ammo_item)) self._ammo_maximum_spinboxes[ammo_item].append(maximum_spinbox) layout.addWidget(target_count_label, current_row, 0) layout.addWidget(maximum_spinbox, current_row, 1) current_row += 1 count_label = QLabel(pickup_box) count_label.setText("Pickup Count") count_label.setToolTip( "How many instances of this expansion should be placed.") pickup_spinbox = QSpinBox(pickup_box) pickup_spinbox.setMaximum(AmmoState.maximum_pickup_count()) pickup_spinbox.valueChanged.connect( partial(self._on_update_ammo_pickup_spinbox, ammo)) layout.addWidget(count_label, current_row, 0) layout.addWidget(pickup_spinbox, current_row, 1) current_row += 1 if ammo.temporaries: require_major_item_check = QCheckBox(pickup_box) require_major_item_check.setText( "Requires the major item to work?") require_major_item_check.stateChanged.connect( partial(self._on_update_ammo_require_major_item, ammo)) layout.addWidget(require_major_item_check, current_row, 0, 1, 2) current_row += 1 else: require_major_item_check = None expected_count = QLabel(pickup_box) expected_count.setWordWrap(True) expected_count.setText(_EXPECTED_COUNT_TEXT_TEMPLATE) expected_count.setToolTip( "Some expansions may provide 1 extra, even with no variance, if the total count " "is not divisible by the pickup count.") layout.addWidget(expected_count, current_row, 0, 1, 2) current_row += 1 self._ammo_pickup_widgets[ammo] = AmmoPickupWidgets( pickup_spinbox, expected_count, pickup_box, require_major_item_check) category_layout.addWidget(pickup_box) def _on_update_ammo_maximum_spinbox(self, ammo_int: int, value: int): with self._editor as options: options.ammo_configuration = options.ammo_configuration.replace_maximum_for_item( ammo_int, value) def _on_update_ammo_pickup_spinbox(self, ammo: Ammo, value: int): with self._editor as options: ammo_configuration = options.ammo_configuration options.ammo_configuration = ammo_configuration.replace_state_for_ammo( ammo, dataclasses.replace(ammo_configuration.items_state[ammo], pickup_count=value)) def _on_update_ammo_require_major_item(self, ammo: Ammo, value: int): with self._editor as options: ammo_configuration = options.ammo_configuration options.ammo_configuration = ammo_configuration.replace_state_for_ammo( ammo, dataclasses.replace(ammo_configuration.items_state[ammo], requires_major_item=bool(value)))
class HyperparametersConfigWidgetGui(QWidget, HyperparametersConfigWidget): def __init__(self, parent: "QWidget" = None): HyperparametersConfigWidget.__init__(self) QWidget.__init__(self, parent) # Widgets self._epoch_spinbox = QSpinBox(parent=self) self._epoch_spinbox.setMinimum(1) self._epoch_spinbox.setValue(self.get_epochs()) self._loss_function_combobox = QComboBox(parent=self) self._loss_function_combobox.addItems(self.get_available_loss_functions()) self._loss_function_combobox.setCurrentText(self.get_loss_function()) self._optimizer_combobox = QComboBox() self._optimizer_combobox.addItems(self.get_available_optimizers()) self._optimizer_combobox.setCurrentText(self.get_optimizer()) self._batch_size_spinbox = QSpinBox(parent=self) self._batch_size_spinbox.setValue(self.get_batch_size()) self._batch_size_spinbox.setMinimum(1) self._batch_size_spinbox.setMaximum(999999) # Layouts self._main_layout = QFormLayout() self._main_layout.addRow("Epochs", self._epoch_spinbox) self._main_layout.addRow("Optimizer", self._optimizer_combobox) self._main_layout.addRow("Loss function", self._loss_function_combobox) self._main_layout.addRow("Batch size", self._batch_size_spinbox) self.setLayout(self._main_layout) # Hyperparameters dictionary self._epoch_spinbox.valueChanged.connect(self.set_epochs) self._loss_function_combobox.currentTextChanged.connect(self.set_loss_function) self._optimizer_combobox.currentTextChanged.connect(self.set_optimizer) self._batch_size_spinbox.valueChanged.connect(self.set_batch_size) def set_epochs(self, epochs: int): super().set_epochs(epochs) self._epoch_spinbox.setValue(epochs) def set_loss_function(self, loss_function: str): super().set_loss_function(loss_function) self._loss_function_combobox.setCurrentText(loss_function) def set_optimizer(self, optimizer: str): super().set_optimizer(optimizer) self._optimizer_combobox.setCurrentText(optimizer) def set_batch_size(self, batch_size: int): super().set_batch_size(batch_size) self._batch_size_spinbox.setValue(batch_size) def sizeHint(self) -> "QSize": return QSize(350, 200) def __getstate__(self): return {"hyperparameters": self.get_hyperparameters()} def __setstate__(self, new_state): self._hyperparameters = new_state["hyperparameters"] self.set_hyperparameters(new_state["hyperparameters"]) def __reduce__(self): return (HyperparametersConfigWidgetGui, (), self.__getstate__())
def __init__(self, app, parent=None): super(MainWindow, self).__init__(parent) self.imagesDir = app.dir + '/images/' self.setWindowIcon(QIcon(self.imagesDir + 'icon.png')) self.path = '' self.settings = QSettings() self.lastDir = self.settings.value('lastDir', '') self.setMinimumWidth(540) self.supportedFormats = [] for f in QImageReader.supportedImageFormats(): self.supportedFormats.append(str(f.data(), encoding="utf-8")) self.fileWatcher = QFileSystemWatcher() self.fileWatcher.fileChanged.connect(self.fileChanged) # widgets self.showPixmapWidget = None self.tileWidthSpinBox = QSpinBox() self.tileWidthSpinBox.setValue(16) self.tileWidthSpinBox.setFixedWidth(50) self.tileWidthSpinBox.setMinimum(1) self.tileHeightSpinBox = QSpinBox() self.tileHeightSpinBox.setValue(16) self.tileHeightSpinBox.setFixedWidth(50) self.tileHeightSpinBox.setMinimum(1) self.paddingSpinBox = QSpinBox() self.paddingSpinBox.setFixedWidth(50) self.paddingSpinBox.setMinimum(1) self.transparentCheckbox = QCheckBox("Transparent") self.transparentCheckbox.setChecked(True) self.transparentCheckbox.stateChanged.connect(self.transparentChanged) self.backgroundColorEdit = ColorEdit() self.backgroundColorEdit.setEnabled(False) self.backgroundColorLabel = QLabel("Background color:") self.backgroundColorLabel.setEnabled(False) self.forcePotCheckBox = QCheckBox("Force PoT") self.forcePotCheckBox.setChecked(True) self.forcePotCheckBox.stateChanged.connect(self.forcePotChanged) self.reorderTilesCheckBox = QCheckBox("Reorder tiles") self.generateAndExportButton = QPushButton("Generate and export") self.generateAndExportButton.setFixedHeight(32) self.generateAndExportButton.clicked.connect(self.generateAndExportClicked) self.generateAndExportButton.setEnabled(False) self.pixmapWidget = PixmapWidget() self.pixmapWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.pixmapWidget.setPixmap(self.createDropTextPixmap()) self.pixmapWidget.dropSignal.connect(self.fileDropped) self.pixmapWidget.setMinimumHeight(300) # load settings self.tileWidthSpinBox.setValue(int(self.settings.value('tileWidth', 16))) self.tileHeightSpinBox.setValue(int(self.settings.value('tileHeight', 16))) self.paddingSpinBox.setValue(int(self.settings.value('padding', 1))) self.forcePotCheckBox.setChecked(True if self.settings.value('forcePot', 'true') == 'true' else False) self.reorderTilesCheckBox.setChecked(True if self.settings.value('reorderTiles', 'false') == 'true' else False) self.transparentCheckbox.setChecked(True if self.settings.value('transparent', 'false') == 'true' else False) self.backgroundColorEdit.setColorText(str(self.settings.value('backgroundColor', '#FF00FF'))) self.restoreGeometry(QByteArray(self.settings.value('MainWindow/geometry'))) self.restoreState(QByteArray(self.settings.value('MainWindow/windowState'))) # layout hl1 = QHBoxLayout() hl1.setContentsMargins(5, 5, 5, 5) hl1.addWidget(QLabel("Tile width:")) hl1.addSpacing(5) hl1.addWidget(self.tileWidthSpinBox) hl1.addSpacing(15) hl1.addWidget(QLabel("Tile height:")) hl1.addSpacing(5) hl1.addWidget(self.tileHeightSpinBox) hl1.addSpacing(15) hl1.addWidget(QLabel("Padding:")) hl1.addSpacing(5) hl1.addWidget(self.paddingSpinBox) hl1.addSpacing(15) hl1.addWidget(self.forcePotCheckBox) hl1.addSpacing(15) hl1.addWidget(self.reorderTilesCheckBox) hl1.addStretch() hl2 = QHBoxLayout() hl2.setContentsMargins(5, 5, 5, 5) hl2.addWidget(self.transparentCheckbox) hl2.addSpacing(15) hl2.addWidget(self.backgroundColorLabel) hl2.addSpacing(5) hl2.addWidget(self.backgroundColorEdit) hl2.addStretch() hl3 = QHBoxLayout() hl3.setContentsMargins(5, 5, 5, 5) hl3.addWidget(self.generateAndExportButton) vl = QVBoxLayout() vl.setContentsMargins(0, 0, 0, 0) vl.setSpacing(0) vl.addLayout(hl1) vl.addLayout(hl2) vl.addWidget(self.pixmapWidget) vl.addLayout(hl3) w = QWidget() w.setLayout(vl) self.setCentralWidget(w) self.setTitle()
class QFlightCreator(QDialog): def __init__(self, game: Game, from_cp:ControlPoint, possible_aircraft_type:List[UnitType], flight_view=None): super(QFlightCreator, self).__init__() self.game = game self.from_cp = from_cp self.flight_view = flight_view self.planner = self.game.planners[from_cp.id] self.available = self.planner.get_available_aircraft() self.setWindowFlags(Qt.WindowStaysOnTopHint) self.setModal(True) self.setWindowTitle("Create flight") self.setWindowIcon(EVENT_ICONS["strike"]) self.select_type_aircraft = QComboBox() for aircraft_type in self.planner.get_available_aircraft().keys(): print(aircraft_type) print(aircraft_type.name) self.select_type_aircraft.addItem(aircraft_type.id, userData=aircraft_type) self.select_type_aircraft.setCurrentIndex(0) self.select_flight_type = QComboBox() self.select_flight_type.addItem("CAP [Combat Air Patrol]", userData=FlightType.CAP) self.select_flight_type.addItem("BARCAP [Barrier Combat Air Patrol]", userData=FlightType.BARCAP) self.select_flight_type.addItem("TARCAP [Target Combat Air Patrol]", userData=FlightType.TARCAP) self.select_flight_type.addItem("INTERCEPT [Interception]", userData=FlightType.INTERCEPTION) self.select_flight_type.addItem("CAS [Close Air Support]", userData=FlightType.CAS) self.select_flight_type.addItem("BAI [Battlefield Interdiction]", userData=FlightType.BAI) self.select_flight_type.addItem("SEAD [Suppression of Enemy Air Defenses]", userData=FlightType.SEAD) self.select_flight_type.addItem("DEAD [Destruction of Enemy Air Defenses]", userData=FlightType.DEAD) self.select_flight_type.addItem("STRIKE [Strike]", userData=FlightType.STRIKE) self.select_flight_type.addItem("ANTISHIP [Antiship Attack]", userData=FlightType.ANTISHIP) self.select_flight_type.setCurrentIndex(0) self.select_count_of_aircraft = QSpinBox() self.select_count_of_aircraft.setMinimum(1) self.select_count_of_aircraft.setMaximum(4) self.select_count_of_aircraft.setValue(2) self.add_button = QPushButton("Add") self.add_button.clicked.connect(self.create_flight) self.init_ui() def init_ui(self): layout = QVBoxLayout() type_layout = QHBoxLayout() type_layout.addWidget(QLabel("Type of Aircraft : ")) type_layout.addStretch() type_layout.addWidget(self.select_type_aircraft, alignment=Qt.AlignRight) count_layout = QHBoxLayout() count_layout.addWidget(QLabel("Count : ")) count_layout.addStretch() count_layout.addWidget(self.select_count_of_aircraft, alignment=Qt.AlignRight) flight_type_layout = QHBoxLayout() flight_type_layout.addWidget(QLabel("Task : ")) flight_type_layout.addStretch() flight_type_layout.addWidget(self.select_flight_type, alignment=Qt.AlignRight) layout.addLayout(type_layout) layout.addLayout(count_layout) layout.addLayout(flight_type_layout) layout.addStretch() layout.addWidget(self.add_button, alignment=Qt.AlignRight) self.setLayout(layout) def create_flight(self): aircraft_type = self.select_type_aircraft.currentData() count = self.select_count_of_aircraft.value() if self.available[aircraft_type] < count: msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Not enough aircraft of this type are available. Only " + str(self.available[aircraft_type]) + " available.") msg.setWindowTitle("Not enough aircraft") msg.setStandardButtons(QMessageBox.Ok) msg.setWindowFlags(Qt.WindowStaysOnTopHint) msg.exec_() return else: flight = Flight(aircraft_type, count, self.from_cp, self.select_flight_type.currentData()) self.planner.flights.append(flight) self.planner.custom_flights.append(flight) if self.flight_view is not None: self.flight_view.set_flight_planner(self.planner, len(self.planner.flights)-1) self.close()
class main(QWidget): def __init__(self, parent=None): super(main, self).__init__(parent) self.setup() # connections, widgets, layouts, etc. self.blksize = 2**20 # 1 MB; must be divisible by 16 self.ext = '.enc' # extension is appended to encrypted files self.path = '' self.encrypted = [] # to highlight done files in list self.decrypted = [] self.clipboard = QApplication.clipboard() self.timeout = None # to clear message label, see setMessage # this program was just an excuse to play with QprogressBar if not hash(os.urandom(11)) % 11: QTimer().singleShot(50, self.windDown) # various random hints hints = [ 'Freshly encrypted files can be renamed in the table!', 'Clipboard is always cleared on program close!', 'Keys can contain emoji if you <em>really</em> want: \U0001f4e6', 'Keys can contain emoji if you <em>really</em> want: \U0001F511', 'This isn\'t a tip, I just wanted to say hello!', 'Keys can be anywhere from 8 to 4096 characters long!', 'This program was just an excuse to play with the progress bars!', 'Select \'Party\' in the hash button for progress bar fun!', ('Did you know you can donate one or all of your vital organs to ' 'the Aperture Science Self-Esteem Fund for Girls? It\'s true!'), ('It\'s been {:,} days since Half-Life 2: Episode ' 'Two'.format(int((time.time() - 1191988800) / 86400))), 'I\'m version {}!'.format(VERSION), 'I\'m version {}.whatever!'.format(VERSION.split('.')[0]), ('Brought to you by me, I\'m <a href="https://orthallelous.word' 'press.com/">Orthallelous!</a>'), #'Brought to you by me, I\'m Htom Sirveaux!', 'I wonder if there\'s beer on the sun', 'Raspberry World: For all your raspberry needs. Off the beltline', #'I\'ve plummented to my death and I can\'t get up', '<em>NOT</em> compatible with the older version!', ('Hello there, fellow space travellers! Until somebody gives me ' 'some new lines in KAS, that is all I can say. - Bentusi Exchange' ) ] if not hash(os.urandom(9)) % 4: self.extraLabel.setText(random.choice(hints)) def genKey(self): "generate a random key" n = self.keySizeSB.value() char = string.printable.rstrip() #map(chr, range(256)) while len(char) < n: char += char key = ''.join(random.sample(char, n)) self.keyInput.setText(key) def showKey(self, state=None): "hide/show key characters" if state is None: state = bool(self.showKeyCB.checkState()) else: state = bool(state) if state: self.keyInput.setEchoMode(QLineEdit.Normal) else: self.keyInput.setEchoMode(QLineEdit.PasswordEchoOnEdit) def getFolder(self): "open file dialog and fill file table" path = QFileDialog(directory=self.path).getExistingDirectory() if not path: return self.path = str(path) self.populateTable(self.path) self.encrypted, self.decrypted = [], [] return def resizeEvent(self, event): self.showFolder(self.path) # update how the folder is shown def splitterChanged(self, pos): self.showFolder(self.path) # likewise def showFolder(self, path): "displays current path, truncating as needed" if not path: return ell, sl = '\u2026', os.path.sep # ellipsis, slash chars lfg, rfg = Qt.ElideLeft, Qt.ElideRight lst, wdh = os.path.basename(path), self.folderLabel.width() path = path.replace(os.path.altsep or '\\', sl) self.folderLabel.setToolTip(path) # truncate folder location fnt = QFontMetrics(self.folderLabel.font()) txt = str(fnt.elidedText(path, lfg, wdh)) if len(txt) <= 1: # label is way too short self.folderLabel.setText('\u22ee' if txt != sl else txt) return # but when would this happen? # truncate some more (don't show part of a folder name) if len(txt) < len(path) and txt[1] != sl: txt = ell + sl + txt.split(sl, 1)[-1] # don't truncate remaining folder name from the left if txt[2:] != lst and len(txt[2:]) < len(lst) + 2: txt = str(fnt.elidedText(ell + sl + lst, rfg, wdh)) # you'd think len(txt) < len(lst) would work, but no; you'd be wrong self.folderLabel.setText(txt) def populateTable(self, path): "fill file table with file names" self.showFolder(path) names = [] for n in os.listdir(path): if os.path.isdir(os.path.join(path, n)): continue # folder names.append(n) self.folderTable.clearContents() self.folderTable.setRowCount(len(names)) self.folderTable.setColumnCount(1) if not names: # no files in this folder, inform user self.setMessage('This folder has no files') return self.folderTable.blockSignals(True) selEnab = Qt.ItemIsSelectable | Qt.ItemIsEnabled for i, n in enumerate(names): item = QTableWidgetItem() item.setText(n) item.setToolTip(n) item.setFlags(selEnab) # color code encrypted/decrypted files if n in self.encrypted: item.setTextColor(QColor(211, 70, 0)) # allowed encrypted filenames to be changed item.setFlags(selEnab | Qt.ItemIsEditable) if n in self.decrypted: item.setForeground(QColor(0, 170, 255)) self.folderTable.setItem(i, 0, item) if len(names) > 5: self.setMessage('{:,} files'.format(len(names)), 7) self.folderTable.blockSignals(False) return def editFileName(self, item): "change file name" new, old = str(item.text()), str(item.toolTip()) result = QMessageBox.question( self, 'Renaming?', ("<p align='center'>Do you wish to rename<br>" + '<span style="color:#d34600;">{}</span>'.format(old) + "<br>to<br>" + '<span style="color:#ef4b00;">{}</span>'.format(new) + '<br>?</p>')) self.folderTable.blockSignals(True) if any(i in new for i in '/?<>:*|"^'): self.setMessage('Invalid character in name', 7) item.setText(old) elif result == QMessageBox.Yes: oold = os.path.join(self.path, old) try: os.rename(oold, os.path.join(self.path, new)) self.encrypted.remove(old) self.encrypted.append(new) item.setToolTip(new) except Exception as err: self.setMessage(str(err), 9) item.setText(old) item.setToolTip(old) self.encrypted.remove(new) self.encrypted.append(old) else: item.setText(old) self.folderTable.blockSignals(False) def setMessage(self, message, secs=4, col=None): "show a message for a few seconds - col must be rgb triplet tuple" if self.timeout: # https://stackoverflow.com/a/21081371 self.timeout.stop() self.timeout.deleteLater() if col is None: color = 'rgb(255, 170, 127)' else: try: color = 'rgb({}, {}, {})'.format(*col) except: color = 'rgb(255, 170, 127)' self.messageLabel.setStyleSheet('background-color: {};'.format(color)) self.messageLabel.setText(message) self.messageLabel.setToolTip(message) self.timeout = QTimer() self.timeout.timeout.connect(self.clearMessage) self.timeout.setSingleShot(True) self.timeout.start(secs * 1000) def clearMessage(self): self.messageLabel.setStyleSheet('') self.messageLabel.setToolTip('') self.messageLabel.setText('') def getName(self): "return file name of selected" items = self.folderTable.selectedItems() names = [str(i.text()) for i in items] if names: return names[0] # only the first selected file else: return '' def showKeyLen(self, string): "displays a tooltip showing length of key" s = len(string) note = '{:,} character{}'.format(s, '' if s == 1 else 's') tip = QToolTip pos = self.genKeyButton.mapToGlobal(QPoint(0, 0)) if s < self.minKeyLen: note = '<span style="color:#c80000;">{}</span>'.format(note) else: note = '<span style="color:#258f22;">{}</span>'.format(note) tip.showText(pos, note) def lock(self, flag=True): "locks buttons if True" stuff = [ self.openButton, self.encryptButton, self.decryptButton, self.genKeyButton, self.hashButton, self.showKeyCB, self.copyButton, self.keyInput, self.keySizeSB, self.folderTable, ] for i in stuff: i.blockSignals(flag) i.setEnabled(not flag) return def _lerp(self, v1, v2, numPts=10): "linearly interpolate from v1 to v2\nFrom Orthallelous" if len(v1) != len(v2): raise ValueError("different dimensions") D, V, n = [], [], abs(numPts) for i, u in enumerate(v1): D.append(v2[i] - u) for i in range(n + 1): vn = [] for j, u in enumerate(v1): vn.append(u + D[j] / float(n + 2) * i) V.append(tuple(vn)) return V def weeeeeee(self): "party time" self.lock() self.setMessage('Party time!', 2.5) a, b, c = self.encryptPbar, self.decryptPbar, self.hashPbar process, sleep = app.processEvents, time.sleep am, bm, cm = a.minimum(), b.minimum(), c.minimum() ax, bx, cx = a.maximum(), b.maximum(), c.maximum() a.reset() b.reset() c.reset() loops = self._lerp((am, bm, cm), (ax, bx, cx), 100) ivops = loops[::-1] # up and up! for i in range(3): for j, k, l in loops: a.setValue(int(j)) b.setValue(int(k)) c.setValue(int(l)) process() sleep(0.01) a.setValue(ax) b.setValue(bx) c.setValue(cx) sleep(0.25) a.setValue(am) b.setValue(bm) c.setValue(cm) # snake! self.setMessage('Snake time!') self.messageLabel.setStyleSheet('background-color: rgb(127,170,255);') for i in range(2): for j, k, l in loops: a.setValue(int(j)) process() sleep(0.002) process() a.setInvertedAppearance(True) process() for j, k, l in ivops: a.setValue(int(j)) process() sleep(0.002) for j, k, l in loops: b.setValue(int(k)) process() sleep(0.002) process() b.setInvertedAppearance(False) process() for j, k, l in ivops: b.setValue(int(k)) process() sleep(0.002) for j, k, l in loops: c.setValue(int(l)) process() sleep(0.002) process() c.setInvertedAppearance(True) process() for j, k, l in ivops: c.setValue(int(l)) process() sleep(0.002) process() b.setInvertedAppearance(True) process() for j, k, l in loops: b.setValue(int(k)) process() sleep(0.002) process() b.setInvertedAppearance(False) process() for j, k, l in ivops: b.setValue(int(k)) process() sleep(0.002) process() a.setInvertedAppearance(False) b.setInvertedAppearance(True) c.setInvertedAppearance(False) for j, k, l in loops: a.setValue(int(j)) process() sleep(0.002) process() a.setInvertedAppearance(True) process() for j, k, l in ivops: a.setValue(int(j)) process() sleep(0.002) # bars sleep(0.5) self.setMessage('Bars!') process() self.messageLabel.setStyleSheet('background-color: rgb(127,255,170);') for i in range(2): a.setValue(ax) time.sleep(0.65) a.setValue(am) sleep(0.25) process() b.setValue(bx) time.sleep(0.65) b.setValue(bm) sleep(0.25) process() c.setValue(cx) time.sleep(0.65) c.setValue(cm) sleep(0.25) process() b.setValue(bx) time.sleep(0.65) b.setValue(bm) sleep(0.25) process() # okay, enough process() a.setValue(ax) b.setValue(bx) c.setValue(cx) #a.setValue(am); b.setValue(bm); c.setValue(cm) a.setInvertedAppearance(False) b.setInvertedAppearance(True) c.setInvertedAppearance(False) self.lock(False) return def windDown(self, note=None): "silly deload on load" if note is None: note = 'Loading...' self.lock() self.setMessage(note) self.messageLabel.setStyleSheet('background-color: rgb(9, 190, 130);') a, b, c = self.encryptPbar, self.decryptPbar, self.hashPbar am, bm, cm = a.minimum(), b.minimum(), c.minimum() ax, bx, cx = a.maximum(), b.maximum(), c.maximum() a.reset() b.reset() c.reset() loops = self._lerp((ax, bx, cx), (am, bm, cm), 100) for j, k, l in loops: a.setValue(int(j)) b.setValue(int(k)) c.setValue(int(l)) app.processEvents() time.sleep(0.02) a.reset() b.reset() c.reset() self.lock(False) self.clearMessage() def genHash(self, action): "generate hash of selected file and display it" name, t0 = self.getName(), time.perf_counter() # mark what hash was used in the drop-down menu for i in self.hashButton.menu().actions(): if i == action: i.setIconVisibleInMenu(True) else: i.setIconVisibleInMenu(False) if str(action.text()) == 'Party': self.weeeeeee() self.windDown('Winding down...') return if not name: self.setMessage('No file selected') return if not os.path.exists(os.path.join(self.path, name)): self.setMessage('File does not exist') return self.lock() hsh = self.hashFile(os.path.join(self.path, name), getattr(hashlib, str(action.text()))) self.lock(False) #hsh = str(action.text()) + ': ' + hsh self.hashLabel.setText(hsh) self.hashLabel.setToolTip(hsh) self.extraLabel.setText( str(action.text()) + ' hash took ' + self.secs_fmt(time.perf_counter() - t0)) def setCancel(self): "cancel operation" self._requestStop = True def showCancelButton(self, state=False): "show/hide cancel button" self.cancelButton.blockSignals(not state) self.cancelButton.setEnabled(state) if state: self.cancelButton.show() self.keyInput.hide() self.genKeyButton.hide() self.keySizeSB.hide() else: self.cancelButton.hide() self.keyInput.show() self.genKeyButton.show() self.keySizeSB.show() def hashFile(self, fn, hasher): "returns the hash value of a file" hsh, blksize = hasher(), self.blksize fsz, csz = os.path.getsize(fn), 0.0 self.hashPbar.reset() self.showCancelButton(True) prog, title = '(# {:.02%}) {}', self.windowTitle() with open(fn, 'rb') as f: while 1: blk = f.read(blksize) if not blk: break hsh.update(blk) csz += blksize self.hashPbar.setValue(int(round(csz * 100.0 / fsz))) app.processEvents() self.setWindowTitle(prog.format(csz / fsz, title)) if self._requestStop: break self.hashPbar.setValue(self.hashPbar.maximum()) self.setWindowTitle(title) self.showCancelButton(False) if self._requestStop: self.setMessage('Hashing canceled!') self.hashPbar.setValue(self.hashPbar.minimum()) self._requestStop = False return return hsh.hexdigest() def hashKey(self, key, salt=b''): "hashes a key for encrypting/decrypting file" salt = salt.encode() if type(salt) != bytes else salt key = key.encode() if type(key) != bytes else key p = app.processEvents self.setMessage('Key Hashing...', col=(226, 182, 249)) p() key = hashlib.pbkdf2_hmac('sha512', key, salt, 444401) p() self.clearMessage() p() return hashlib.sha3_256(key).digest() # AES requires a 32 char key def encrypt(self): "encrypt selected file with key" name, t0 = self.getName(), time.perf_counter() if not name: self.setMessage('No file selected') return if not os.path.exists(os.path.join(self.path, name)): self.setMessage('File does not exist') return key = str(self.keyInput.text()) if len(key) < self.minKeyLen: self.setMessage(('Key must be at least ' '{} characters long').format(self.minKeyLen)) return self.lock() gn = self.encryptFile(key, os.path.join(self.path, name)) if not gn: self.lock(False) return self.encrypted.append(os.path.basename(gn)) self.lock(False) self.populateTable(self.path) # repopulate folder list bn, tt = os.path.basename(gn), time.perf_counter() - t0 self.setMessage('Encrypted, saved "{}"'.format(bn, 13)) self.extraLabel.setText('Encrypting took ' + self.secs_fmt(tt)) def encryptFile(self, key, fn): "encrypts a file using AES (MODE_GCM)" chars = ''.join(map(chr, range(256))).encode() chk = AES.block_size sample = random.sample iv = bytes(sample(chars, chk * 2)) salt = bytes(sample(chars * 2, 256)) vault = AES.new(self.hashKey(key, salt), AES.MODE_GCM, iv) fsz = os.path.getsize(fn) del key blksize = self.blksize gn = fn + self.ext fne = os.path.basename(fn).encode() fnz = len(fne) if len(fne) % chk: fne += bytes(sample(chars, chk - len(fne) % chk)) csz = 0.0 # current processed value self.encryptPbar.reset() prog, title = '({:.02%}) {}', self.windowTitle() self.showCancelButton(True) with open(fn, 'rb') as src, open(gn, 'wb') as dst: dst.write(bytes([0] * 16)) # spacer for MAC written at end dst.write(iv) dst.write(salt) # store iv, salt # is it safe to store MAC, iv, salt plain right in file? # can't really store them encrypted, # or elsewhere in this model of single file encryption? # can't have another file for the file to lug around # store file size, file name length dst.write(vault.encrypt(struct.pack('<2Q', fsz, fnz))) dst.write(vault.encrypt(fne)) # store filename while 1: dat = src.read(blksize) if not dat: break elif len(dat) % chk: # add padding fil = chk - len(dat) % chk dat += bytes(sample(chars, fil)) dst.write(vault.encrypt(dat)) csz += blksize # show progress self.encryptPbar.setValue(int(round(csz * 100.0 / fsz))) self.setWindowTitle(prog.format(csz / fsz, title)) app.processEvents() if self._requestStop: break if not self._requestStop: stuf = random.randrange(23) # pack in more stuffing fing = b''.join(bytes(sample(chars, 16)) for i in range(stuf)) dst.write(vault.encrypt(fing)) # and for annoyance dst.seek(0) dst.write(vault.digest()) # write MAC self.hashLabel.setText('MAC: ' + vault.hexdigest()) self.encryptPbar.setValue(self.encryptPbar.maximum()) self.setWindowTitle(title) self.showCancelButton(False) if self._requestStop: self.setMessage('Encryption canceled!') self.encryptPbar.setValue(self.encryptPbar.minimum()) self._requestStop = False os.remove(gn) return return gn def decrypt(self): "encrypt selected file with key" name, t0 = self.getName(), time.perf_counter() if not name: self.setMessage('No file selected') return if not os.path.exists(os.path.join(self.path, name)): self.setMessage('File does not exist') return key = str(self.keyInput.text()) if len(key) < self.minKeyLen: self.setMessage(('Key must be at least ' '{} characters long').format(self.minKeyLen)) return self.lock() gn = self.decryptFile(key, os.path.join(self.path, name)) if not gn: self.lock(False) return self.decrypted.append(os.path.basename(gn)) self.lock(False) self.populateTable(self.path) # repopulate folder list bn, tt = os.path.basename(gn), time.perf_counter() - t0 self.setMessage('Decrypted, saved "{}"'.format(bn, 13)) self.extraLabel.setText('Decrypting took ' + self.secs_fmt(tt)) def decryptFile(self, key, fn): "decrypts a file using AES (MODE_GCM)" blksize = self.blksize gn = hashlib.md5(os.path.basename(fn).encode()).hexdigest() gn = os.path.join(self.path, gn) # temporary name if os.path.exists(gn): self.setMessage('file already exists') return self.decryptPbar.reset() csz = 0.0 # current processed value chk, fnsz = AES.block_size, os.path.getsize(fn) prog, title = '({:.02%}) {}', self.windowTitle() try: with open(fn, 'rb') as src, open(gn, 'wb') as dst: # extract iv, salt MAC = src.read(16) iv = src.read(AES.block_size * 2) salt = src.read(256) vault = AES.new(self.hashKey(key, salt), AES.MODE_GCM, iv) self.showCancelButton(True) # extract file size, file name length sizes = src.read(struct.calcsize('<2Q')) fsz, fnz = struct.unpack('<2Q', vault.decrypt(sizes)) # extract filename; round up fnz to nearest chk rnz = fnz if not fnz % chk else fnz + chk - fnz % chk rfn = vault.decrypt(src.read(rnz))[:fnz].decode() self.setMessage('Found "{}"'.format(rfn), 13, (255, 211, 127)) while 1: dat = src.read(blksize) if not dat: break dst.write(vault.decrypt(dat)) csz += blksize # show progress self.decryptPbar.setValue(int(round(csz * 100.0 / fnsz))) self.setWindowTitle(prog.format(1 - (csz / fnsz), title)) app.processEvents() if self._requestStop: break if not self._requestStop: dst.truncate(fsz) # remove padding if not self._requestStop: vault.verify(MAC) self.hashLabel.setText('') except (ValueError, KeyError) as err: os.remove(gn) self.setMessage('Invalid decryption!') self.setWindowTitle(title) self.showCancelButton(False) return except Exception as err: os.remove(gn) self.setMessage('Invalid key or file!') self.setWindowTitle(title) self.showCancelButton(False) return self.decryptPbar.setValue(self.decryptPbar.maximum()) self.setWindowTitle(title) self.showCancelButton(False) if self._requestStop: self.setMessage('Decryption canceled!') self.decryptPbar.setValue(self.decryptPbar.minimum()) self._requestStop = False os.remove(gn) return # restore original file name name, ext = os.path.splitext(rfn) count = 1 fn = os.path.join(self.path, name + ext) while os.path.exists(fn): fn = os.path.join(self.path, name + '_{}'.format(count) + ext) count += 1 os.rename(gn, fn) # restore original name return fn # saved name def copyKeyHash(self, action): "copies either the key or the hash to clipboard" act = str(action.text()).lower() if 'key' in act: txt = str(self.keyInput.text()) elif 'hash' in act: txt = str(self.hashLabel.text()) else: self.setMessage('Invalid copy selection') return if not txt: self.setMessage('Empty text; Nothing to copy') return if 'key' in act: self.setMessage('Key copied to clipboard') elif 'hash' in act: self.setMessage('Hash copied to clipboard') else: self.setMessage('Invalid copy selection') return self.clipboard.clear() self.clipboard.setText(txt) def secs_fmt(self, s): "6357 -> '1h 45m 57s'" Y, D, H, M = 31556952, 86400, 3600, 60 y = int(s // Y) s -= y * Y d = int(s // D) s -= d * D h = int(s // H) s -= h * H m = int(s // M) s -= m * M r = (str(int(s)) if int(s) == s else str(round(s, 3))) + 's' if m: r = str(m) + 'm ' + r if h: r = str(h) + 'h ' + r if d: r = str(d) + 'd ' + r if y: r = str(y) + 'y ' + r return r.strip() def closeEvent(self, event): self.clipboard.clear() def setup(self): "constructs the gui" Fixed = QSizePolicy() MinimumExpanding = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.minKeyLen = 8 self.maxKeyLen = 4096 self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Horizontal) self.splitter.splitterMoved.connect(self.splitterChanged) # left column self.leftColumn = QWidget() self.vl01 = QVBoxLayout() # left column - first item (0; horizonal layout 0) self.hl00 = QHBoxLayout() self.hl00.setSpacing(5) self.openButton = QPushButton('&Open') self.openButton.setToolTip('Open folder') self.openButton.setMinimumSize(60, 20) self.openButton.setMaximumSize(60, 20) self.openButton.setSizePolicy(Fixed) self.openButton.clicked.connect(self.getFolder) #ico = self.style().standardIcon(QStyle.SP_DirIcon) #self.openButton.setIcon(ico) self.folderLabel = QLabel() self.folderLabel.setMinimumSize(135, 20) self.folderLabel.setMaximumSize(16777215, 20) self.folderLabel.setSizePolicy(MinimumExpanding) self.hl00.insertWidget(0, self.openButton) self.hl00.insertWidget(1, self.folderLabel) # left column - second item (1) self.folderTable = QTableWidget() self.folderTable.setMinimumSize(200, 32) self.folderTable.horizontalHeader().setVisible(False) self.folderTable.horizontalHeader().setStretchLastSection(True) self.folderTable.verticalHeader().setVisible(False) self.folderTable.verticalHeader().setDefaultSectionSize(15) self.folderTable.itemChanged.connect(self.editFileName) # left column - third item (2) self.extraLabel = QLabel() self.extraLabel.setMinimumSize(200, 20) self.extraLabel.setMaximumSize(16777215, 20) self.extraLabel.setSizePolicy(MinimumExpanding) self.extraLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse) # finalize left column self.vl01.insertLayout(0, self.hl00) self.vl01.insertWidget(1, self.folderTable) self.vl01.insertWidget(2, self.extraLabel) self.leftColumn.setLayout(self.vl01) # right column self.rightColumn = QWidget() self.vl02 = QVBoxLayout() # right column - first item (0) self.messageLabel = QLabel() self.messageLabel.setMinimumSize(290, 20) self.messageLabel.setMaximumSize(16777215, 20) self.messageLabel.setSizePolicy(MinimumExpanding) self.messageLabel.setAlignment(Qt.AlignCenter) # right column - second item (2; horizontal layout 1) self.hl01 = QHBoxLayout() self.hl01.setSpacing(5) self.encryptButton = QPushButton('&Encrypt') #\U0001F512 self.encryptButton.setToolTip('Encrypt selected file') self.encryptButton.setMinimumSize(60, 20) self.encryptButton.setMaximumSize(60, 20) self.encryptButton.setSizePolicy(Fixed) self.encryptButton.clicked.connect(self.encrypt) self.encryptPbar = QProgressBar() self.encryptPbar.setMinimumSize(225, 20) self.encryptPbar.setMaximumSize(16777215, 20) self.encryptPbar.setSizePolicy(MinimumExpanding) self.encryptPbar.setTextVisible(False) palette = self.encryptPbar.palette() # color of progress bar color = QColor(211, 70, 0) palette.setColor(QPalette.Highlight, color) self.encryptPbar.setPalette(palette) self.hl01.insertWidget(0, self.encryptButton) self.hl01.insertWidget(1, self.encryptPbar) # right column - third item (3; horizontal layout 2) self.hl02 = QHBoxLayout() self.hl02.setSpacing(5) self.cancelButton = QPushButton('C&ANCEL') self.cancelButton.setToolTip('Cancels current operation') self.cancelButton.setMinimumSize(70, 24) self.cancelButton.setMaximumSize(70, 24) self.cancelButton.setSizePolicy(Fixed) self.cancelButton.clicked.connect(self.setCancel) font = self.cancelButton.font() font.setBold(True) self.cancelButton.setFont(font) self.cancelButton.blockSignals(True) self.cancelButton.setEnabled(False) self.cancelButton.hide() self._requestStop = False self.keyInput = QLineEdit() self.keyInput.setMinimumSize(225, 20) self.keyInput.setMaximumSize(16777215, 20) self.keyInput.setSizePolicy(MinimumExpanding) self.keyInput.setPlaceholderText('key') self.keyInput.setMaxLength(self.maxKeyLen) self.keyInput.setAlignment(Qt.AlignCenter) self.keyInput.textEdited.connect(self.showKeyLen) self.genKeyButton = QPushButton('&Gen Key') #\U0001F511 self.genKeyButton.setToolTip('Generate a random key') self.genKeyButton.setMinimumSize(60, 20) self.genKeyButton.setMaximumSize(60, 20) self.genKeyButton.setSizePolicy(Fixed) self.genKeyButton.clicked.connect(self.genKey) self.keySizeSB = QSpinBox() self.keySizeSB.setToolTip('Length of key to generate') self.keySizeSB.setRange(32, 1024) self.keySizeSB.setMinimumSize(40, 20) self.keySizeSB.setMaximumSize(40, 20) self.keySizeSB.setSizePolicy(Fixed) self.keySizeSB.setAlignment(Qt.AlignCenter) self.keySizeSB.setButtonSymbols(QSpinBox.NoButtons) self.keySizeSB.setWrapping(True) self.hl02.insertWidget(0, self.cancelButton) self.hl02.insertWidget(1, self.keyInput) self.hl02.insertWidget(2, self.genKeyButton) self.hl02.insertWidget(3, self.keySizeSB) # right column - fourth item (4; horizontal layout 3) self.hl03 = QHBoxLayout() self.hl03.setSpacing(5) self.decryptButton = QPushButton('&Decrypt') #\U0001F513 self.decryptButton.setToolTip('Decrypt selected file') self.decryptButton.setMinimumSize(60, 20) self.decryptButton.setMaximumSize(60, 20) self.decryptButton.setSizePolicy(Fixed) self.decryptButton.clicked.connect(self.decrypt) self.decryptPbar = QProgressBar() self.decryptPbar.setMinimumSize(225, 20) self.decryptPbar.setMaximumSize(16777215, 20) self.decryptPbar.setSizePolicy(MinimumExpanding) self.decryptPbar.setTextVisible(False) self.decryptPbar.setInvertedAppearance(True) palette = self.decryptPbar.palette() # color of progress bar color = QColor(0, 170, 255) palette.setColor(QPalette.Highlight, color) self.decryptPbar.setPalette(palette) self.hl03.insertWidget(0, self.decryptButton) self.hl03.insertWidget(1, self.decryptPbar) # right column - fifth item (7; horizontal layout 4) self.hl04 = QHBoxLayout() self.hl04.setSpacing(5) self.showKeyCB = QCheckBox('&Show Key') self.showKeyCB.setToolTip('Show/Hide key value') self.showKeyCB.setMinimumSize(75, 20) self.showKeyCB.setMaximumSize(75, 20) self.showKeyCB.setSizePolicy(Fixed) self.showKeyCB.clicked.connect(self.showKey) self.showKeyCB.setChecked(True) self.hashPbar = QProgressBar() self.hashPbar.setMinimumSize(150, 20) self.hashPbar.setMaximumSize(16777215, 20) self.hashPbar.setSizePolicy(MinimumExpanding) self.hashPbar.setTextVisible(False) palette = self.hashPbar.palette() # color of progress bar color = QColor(31, 120, 73) palette.setColor(QPalette.Highlight, color) self.hashPbar.setPalette(palette) self.hashButton = QPushButton('&Hash') self.hashButton.setToolTip('Determine file hash') self.hashButton.setMinimumSize(60, 20) self.hashButton.setMaximumSize(60, 20) self.hashButton.setSizePolicy(Fixed) menu = QMenu(self.hashButton) ico = self.style().standardIcon(QStyle.SP_DialogYesButton) for alg in sorted( filter(lambda x: 'shake' not in x, hashlib.algorithms_guaranteed), key=lambda n: (len(n), sorted(hashlib.algorithms_guaranteed).index(n))): menu.addAction( ico, alg ) # drop shake algs as their .hexdigest requires an argument - the rest don't menu.addAction(ico, 'Party') for i in menu.actions(): i.setIconVisibleInMenu(False) self.hashButton.setMenu(menu) menu.triggered.connect(self.genHash) self.hl04.insertWidget(0, self.showKeyCB) self.hl04.insertWidget(1, self.hashPbar) self.hl04.insertWidget(2, self.hashButton) # right column - sixth item (8; horizontal layout 5) self.hl05 = QHBoxLayout() self.hl05.setSpacing(5) self.copyButton = QPushButton('&Copy') #\U0001F4CB self.copyButton.setToolTip('Copy key or hash to clipboard') self.copyButton.setMinimumSize(60, 20) self.copyButton.setMaximumSize(60, 20) self.copyButton.setSizePolicy(Fixed) menu2 = QMenu(self.copyButton) menu2.addAction('Copy Key') menu2.addAction('Copy Hash') self.copyButton.setMenu(menu2) menu2.triggered.connect(self.copyKeyHash) self.hashLabel = QLabel() self.hashLabel.setMinimumSize(225, 20) self.hashLabel.setMaximumSize(16777215, 20) self.hashLabel.setSizePolicy(MinimumExpanding) self.hashLabel.setTextFormat(Qt.PlainText) self.hashLabel.setAlignment(Qt.AlignCenter) self.hashLabel.setTextInteractionFlags(Qt.TextSelectableByMouse) self.hl05.insertWidget(0, self.copyButton) self.hl05.insertWidget(1, self.hashLabel) # finalize right column self.vl02.insertWidget(0, self.messageLabel) self.vl02.insertSpacerItem(1, QSpacerItem(0, 0)) self.vl02.insertLayout(2, self.hl01) self.vl02.insertLayout(3, self.hl02) self.vl02.insertLayout(4, self.hl03) self.vl02.insertSpacerItem(5, QSpacerItem(0, 0)) self.vl02.insertWidget(6, QFrame()) self.vl02.insertLayout(7, self.hl04) self.vl02.insertLayout(8, self.hl05) self.rightColumn.setLayout(self.vl02) # finalize main window self.splitter.insertWidget(0, self.leftColumn) self.splitter.insertWidget(1, self.rightColumn) layout = QHBoxLayout(self) layout.addWidget(self.splitter) self.setLayout(layout) self.setWindowTitle('Simple File Encryptor/Decryptor') self.resize(self.sizeHint())
def __init__(self): super(Window, self).__init__() self.renderArea = RenderArea() self.shapeComboBox = QComboBox() self.shapeComboBox.addItem("Polygon", RenderArea.Polygon) self.shapeComboBox.addItem("Rectangle", RenderArea.Rect) self.shapeComboBox.addItem("Rounded Rectangle", RenderArea.RoundedRect) self.shapeComboBox.addItem("Ellipse", RenderArea.Ellipse) self.shapeComboBox.addItem("Pie", RenderArea.Pie) self.shapeComboBox.addItem("Chord", RenderArea.Chord) self.shapeComboBox.addItem("Path", RenderArea.Path) self.shapeComboBox.addItem("Line", RenderArea.Line) self.shapeComboBox.addItem("Polyline", RenderArea.Polyline) self.shapeComboBox.addItem("Arc", RenderArea.Arc) self.shapeComboBox.addItem("Points", RenderArea.Points) self.shapeComboBox.addItem("Text", RenderArea.Text) self.shapeComboBox.addItem("Pixmap", RenderArea.Pixmap) shapeLabel = QLabel("&Shape:") shapeLabel.setBuddy(self.shapeComboBox) self.penWidthSpinBox = QSpinBox() self.penWidthSpinBox.setRange(0, 20) self.penWidthSpinBox.setSpecialValueText("0 (cosmetic pen)") penWidthLabel = QLabel("Pen &Width:") penWidthLabel.setBuddy(self.penWidthSpinBox) self.penStyleComboBox = QComboBox() self.penStyleComboBox.addItem("Solid", Qt.SolidLine) self.penStyleComboBox.addItem("Dash", Qt.DashLine) self.penStyleComboBox.addItem("Dot", Qt.DotLine) self.penStyleComboBox.addItem("Dash Dot", Qt.DashDotLine) self.penStyleComboBox.addItem("Dash Dot Dot", Qt.DashDotDotLine) self.penStyleComboBox.addItem("None", Qt.NoPen) penStyleLabel = QLabel("&Pen Style:") penStyleLabel.setBuddy(self.penStyleComboBox) self.penCapComboBox = QComboBox() self.penCapComboBox.addItem("Flat", Qt.FlatCap) self.penCapComboBox.addItem("Square", Qt.SquareCap) self.penCapComboBox.addItem("Round", Qt.RoundCap) penCapLabel = QLabel("Pen &Cap:") penCapLabel.setBuddy(self.penCapComboBox) self.penJoinComboBox = QComboBox() self.penJoinComboBox.addItem("Miter", Qt.MiterJoin) self.penJoinComboBox.addItem("Bevel", Qt.BevelJoin) self.penJoinComboBox.addItem("Round", Qt.RoundJoin) penJoinLabel = QLabel("Pen &Join:") penJoinLabel.setBuddy(self.penJoinComboBox) self.brushStyleComboBox = QComboBox() self.brushStyleComboBox.addItem("Linear Gradient", Qt.LinearGradientPattern) self.brushStyleComboBox.addItem("Radial Gradient", Qt.RadialGradientPattern) self.brushStyleComboBox.addItem("Conical Gradient", Qt.ConicalGradientPattern) self.brushStyleComboBox.addItem("Texture", Qt.TexturePattern) self.brushStyleComboBox.addItem("Solid", Qt.SolidPattern) self.brushStyleComboBox.addItem("Horizontal", Qt.HorPattern) self.brushStyleComboBox.addItem("Vertical", Qt.VerPattern) self.brushStyleComboBox.addItem("Cross", Qt.CrossPattern) self.brushStyleComboBox.addItem("Backward Diagonal", Qt.BDiagPattern) self.brushStyleComboBox.addItem("Forward Diagonal", Qt.FDiagPattern) self.brushStyleComboBox.addItem("Diagonal Cross", Qt.DiagCrossPattern) self.brushStyleComboBox.addItem("Dense 1", Qt.Dense1Pattern) self.brushStyleComboBox.addItem("Dense 2", Qt.Dense2Pattern) self.brushStyleComboBox.addItem("Dense 3", Qt.Dense3Pattern) self.brushStyleComboBox.addItem("Dense 4", Qt.Dense4Pattern) self.brushStyleComboBox.addItem("Dense 5", Qt.Dense5Pattern) self.brushStyleComboBox.addItem("Dense 6", Qt.Dense6Pattern) self.brushStyleComboBox.addItem("Dense 7", Qt.Dense7Pattern) self.brushStyleComboBox.addItem("None", Qt.NoBrush) brushStyleLabel = QLabel("&Brush Style:") brushStyleLabel.setBuddy(self.brushStyleComboBox) otherOptionsLabel = QLabel("Other Options:") self.antialiasingCheckBox = QCheckBox("&Antialiasing") self.transformationsCheckBox = QCheckBox("&Transformations") self.shapeComboBox.activated.connect(self.shapeChanged) self.penWidthSpinBox.valueChanged.connect(self.penChanged) self.penStyleComboBox.activated.connect(self.penChanged) self.penCapComboBox.activated.connect(self.penChanged) self.penJoinComboBox.activated.connect(self.penChanged) self.brushStyleComboBox.activated.connect(self.brushChanged) self.antialiasingCheckBox.toggled.connect(self.renderArea.setAntialiased) self.transformationsCheckBox.toggled.connect(self.renderArea.setTransformed) mainLayout = QGridLayout() mainLayout.setColumnStretch(0, 1) mainLayout.setColumnStretch(3, 1) mainLayout.addWidget(self.renderArea, 0, 0, 1, 4) mainLayout.setRowMinimumHeight(1, 6) mainLayout.addWidget(shapeLabel, 2, 1, Qt.AlignRight) mainLayout.addWidget(self.shapeComboBox, 2, 2) mainLayout.addWidget(penWidthLabel, 3, 1, Qt.AlignRight) mainLayout.addWidget(self.penWidthSpinBox, 3, 2) mainLayout.addWidget(penStyleLabel, 4, 1, Qt.AlignRight) mainLayout.addWidget(self.penStyleComboBox, 4, 2) mainLayout.addWidget(penCapLabel, 5, 1, Qt.AlignRight) mainLayout.addWidget(self.penCapComboBox, 5, 2) mainLayout.addWidget(penJoinLabel, 6, 1, Qt.AlignRight) mainLayout.addWidget(self.penJoinComboBox, 6, 2) mainLayout.addWidget(brushStyleLabel, 7, 1, Qt.AlignRight) mainLayout.addWidget(self.brushStyleComboBox, 7, 2) mainLayout.setRowMinimumHeight(8, 6) mainLayout.addWidget(otherOptionsLabel, 9, 1, Qt.AlignRight) mainLayout.addWidget(self.antialiasingCheckBox, 9, 2) mainLayout.addWidget(self.transformationsCheckBox, 10, 2) self.setLayout(mainLayout) self.shapeChanged() self.penChanged() self.brushChanged() self.antialiasingCheckBox.setChecked(True) self.setWindowTitle("Basic Drawing")
class Window(QWidget): def __init__(self): super(Window, self).__init__() self.renderArea = RenderArea() self.shapeComboBox = QComboBox() self.shapeComboBox.addItem("Polygon", RenderArea.Polygon) self.shapeComboBox.addItem("Rectangle", RenderArea.Rect) self.shapeComboBox.addItem("Rounded Rectangle", RenderArea.RoundedRect) self.shapeComboBox.addItem("Ellipse", RenderArea.Ellipse) self.shapeComboBox.addItem("Pie", RenderArea.Pie) self.shapeComboBox.addItem("Chord", RenderArea.Chord) self.shapeComboBox.addItem("Path", RenderArea.Path) self.shapeComboBox.addItem("Line", RenderArea.Line) self.shapeComboBox.addItem("Polyline", RenderArea.Polyline) self.shapeComboBox.addItem("Arc", RenderArea.Arc) self.shapeComboBox.addItem("Points", RenderArea.Points) self.shapeComboBox.addItem("Text", RenderArea.Text) self.shapeComboBox.addItem("Pixmap", RenderArea.Pixmap) shapeLabel = QLabel("&Shape:") shapeLabel.setBuddy(self.shapeComboBox) self.penWidthSpinBox = QSpinBox() self.penWidthSpinBox.setRange(0, 20) self.penWidthSpinBox.setSpecialValueText("0 (cosmetic pen)") penWidthLabel = QLabel("Pen &Width:") penWidthLabel.setBuddy(self.penWidthSpinBox) self.penStyleComboBox = QComboBox() self.penStyleComboBox.addItem("Solid", Qt.SolidLine) self.penStyleComboBox.addItem("Dash", Qt.DashLine) self.penStyleComboBox.addItem("Dot", Qt.DotLine) self.penStyleComboBox.addItem("Dash Dot", Qt.DashDotLine) self.penStyleComboBox.addItem("Dash Dot Dot", Qt.DashDotDotLine) self.penStyleComboBox.addItem("None", Qt.NoPen) penStyleLabel = QLabel("&Pen Style:") penStyleLabel.setBuddy(self.penStyleComboBox) self.penCapComboBox = QComboBox() self.penCapComboBox.addItem("Flat", Qt.FlatCap) self.penCapComboBox.addItem("Square", Qt.SquareCap) self.penCapComboBox.addItem("Round", Qt.RoundCap) penCapLabel = QLabel("Pen &Cap:") penCapLabel.setBuddy(self.penCapComboBox) self.penJoinComboBox = QComboBox() self.penJoinComboBox.addItem("Miter", Qt.MiterJoin) self.penJoinComboBox.addItem("Bevel", Qt.BevelJoin) self.penJoinComboBox.addItem("Round", Qt.RoundJoin) penJoinLabel = QLabel("Pen &Join:") penJoinLabel.setBuddy(self.penJoinComboBox) self.brushStyleComboBox = QComboBox() self.brushStyleComboBox.addItem("Linear Gradient", Qt.LinearGradientPattern) self.brushStyleComboBox.addItem("Radial Gradient", Qt.RadialGradientPattern) self.brushStyleComboBox.addItem("Conical Gradient", Qt.ConicalGradientPattern) self.brushStyleComboBox.addItem("Texture", Qt.TexturePattern) self.brushStyleComboBox.addItem("Solid", Qt.SolidPattern) self.brushStyleComboBox.addItem("Horizontal", Qt.HorPattern) self.brushStyleComboBox.addItem("Vertical", Qt.VerPattern) self.brushStyleComboBox.addItem("Cross", Qt.CrossPattern) self.brushStyleComboBox.addItem("Backward Diagonal", Qt.BDiagPattern) self.brushStyleComboBox.addItem("Forward Diagonal", Qt.FDiagPattern) self.brushStyleComboBox.addItem("Diagonal Cross", Qt.DiagCrossPattern) self.brushStyleComboBox.addItem("Dense 1", Qt.Dense1Pattern) self.brushStyleComboBox.addItem("Dense 2", Qt.Dense2Pattern) self.brushStyleComboBox.addItem("Dense 3", Qt.Dense3Pattern) self.brushStyleComboBox.addItem("Dense 4", Qt.Dense4Pattern) self.brushStyleComboBox.addItem("Dense 5", Qt.Dense5Pattern) self.brushStyleComboBox.addItem("Dense 6", Qt.Dense6Pattern) self.brushStyleComboBox.addItem("Dense 7", Qt.Dense7Pattern) self.brushStyleComboBox.addItem("None", Qt.NoBrush) brushStyleLabel = QLabel("&Brush Style:") brushStyleLabel.setBuddy(self.brushStyleComboBox) otherOptionsLabel = QLabel("Other Options:") self.antialiasingCheckBox = QCheckBox("&Antialiasing") self.transformationsCheckBox = QCheckBox("&Transformations") self.shapeComboBox.activated.connect(self.shapeChanged) self.penWidthSpinBox.valueChanged.connect(self.penChanged) self.penStyleComboBox.activated.connect(self.penChanged) self.penCapComboBox.activated.connect(self.penChanged) self.penJoinComboBox.activated.connect(self.penChanged) self.brushStyleComboBox.activated.connect(self.brushChanged) self.antialiasingCheckBox.toggled.connect(self.renderArea.setAntialiased) self.transformationsCheckBox.toggled.connect(self.renderArea.setTransformed) mainLayout = QGridLayout() mainLayout.setColumnStretch(0, 1) mainLayout.setColumnStretch(3, 1) mainLayout.addWidget(self.renderArea, 0, 0, 1, 4) mainLayout.setRowMinimumHeight(1, 6) mainLayout.addWidget(shapeLabel, 2, 1, Qt.AlignRight) mainLayout.addWidget(self.shapeComboBox, 2, 2) mainLayout.addWidget(penWidthLabel, 3, 1, Qt.AlignRight) mainLayout.addWidget(self.penWidthSpinBox, 3, 2) mainLayout.addWidget(penStyleLabel, 4, 1, Qt.AlignRight) mainLayout.addWidget(self.penStyleComboBox, 4, 2) mainLayout.addWidget(penCapLabel, 5, 1, Qt.AlignRight) mainLayout.addWidget(self.penCapComboBox, 5, 2) mainLayout.addWidget(penJoinLabel, 6, 1, Qt.AlignRight) mainLayout.addWidget(self.penJoinComboBox, 6, 2) mainLayout.addWidget(brushStyleLabel, 7, 1, Qt.AlignRight) mainLayout.addWidget(self.brushStyleComboBox, 7, 2) mainLayout.setRowMinimumHeight(8, 6) mainLayout.addWidget(otherOptionsLabel, 9, 1, Qt.AlignRight) mainLayout.addWidget(self.antialiasingCheckBox, 9, 2) mainLayout.addWidget(self.transformationsCheckBox, 10, 2) self.setLayout(mainLayout) self.shapeChanged() self.penChanged() self.brushChanged() self.antialiasingCheckBox.setChecked(True) self.setWindowTitle("Basic Drawing") def shapeChanged(self): shape = self.shapeComboBox.itemData(self.shapeComboBox.currentIndex(), IdRole) self.renderArea.setShape(shape) def penChanged(self): width = self.penWidthSpinBox.value() style = Qt.PenStyle(self.penStyleComboBox.itemData( self.penStyleComboBox.currentIndex(), IdRole)) cap = Qt.PenCapStyle(self.penCapComboBox.itemData( self.penCapComboBox.currentIndex(), IdRole)) join = Qt.PenJoinStyle(self.penJoinComboBox.itemData( self.penJoinComboBox.currentIndex(), IdRole)) self.renderArea.setPen(QPen(Qt.blue, width, style, cap, join)) def brushChanged(self): style = Qt.BrushStyle(self.brushStyleComboBox.itemData( self.brushStyleComboBox.currentIndex(), IdRole)) if style == Qt.LinearGradientPattern: linearGradient = QLinearGradient(0, 0, 100, 100) linearGradient.setColorAt(0.0, Qt.white) linearGradient.setColorAt(0.2, Qt.green) linearGradient.setColorAt(1.0, Qt.black) self.renderArea.setBrush(QBrush(linearGradient)) elif style == Qt.RadialGradientPattern: radialGradient = QRadialGradient(50, 50, 50, 70, 70) radialGradient.setColorAt(0.0, Qt.white) radialGradient.setColorAt(0.2, Qt.green) radialGradient.setColorAt(1.0, Qt.black) self.renderArea.setBrush(QBrush(radialGradient)) elif style == Qt.ConicalGradientPattern: conicalGradient = QConicalGradient(50, 50, 150) conicalGradient.setColorAt(0.0, Qt.white) conicalGradient.setColorAt(0.2, Qt.green) conicalGradient.setColorAt(1.0, Qt.black) self.renderArea.setBrush(QBrush(conicalGradient)) elif style == Qt.TexturePattern: self.renderArea.setBrush(QBrush(QPixmap(':/images/brick.png'))) else: self.renderArea.setBrush(QBrush(Qt.green, style))
def testSetValue(self): """Direct signal emission: QSpinBox using valueChanged(int)/setValue(int)""" spinSend = QSpinBox() spinRec = QSpinBox() spinRec.setValue(5) spinSend.setValue(42) QObject.connect(spinSend, SIGNAL('valueChanged(int)'), spinRec, SLOT('setValue(int)')) self.assertEqual(spinRec.value(), 5) self.assertEqual(spinSend.value(), 42) spinSend.emit(SIGNAL('valueChanged(int)'), 3) self.assertEqual(spinRec.value(), 3) #Direct emission shouldn't change the value of the emitter self.assertEqual(spinSend.value(), 42) spinSend.emit(SIGNAL('valueChanged(int)'), 66) self.assertEqual(spinRec.value(), 66) self.assertEqual(spinSend.value(), 42)
def setUp(self): super(SpinBoxPySlot, self).setUp() self.spin = QSpinBox()
class EditView: widget = QWidget() layout = QVBoxLayout() grid_widget = QWidget() grid_layout = QGridLayout() buttons_widget = QWidget() buttons_layout = QHBoxLayout() lbl_timestamp = QLabel("Timestamp") cal_timestamp = QDateTimeEdit() lbl_duration = QLabel("Duration") lbl_hour = QLabel("Hours") spn_hour = QSpinBox() lbl_min = QLabel("Minutes") spn_min = QSpinBox() lbl_sec = QLabel("Seconds") spn_sec = QSpinBox() lbl_activity = QLabel("Activity") txt_activity = QLineEdit() btn_done = QPushButton(QIcon.fromTheme('cancel'), "Done") btn_revert = QPushButton(QIcon.fromTheme('edit-undo'), "Revert") btn_save = QPushButton(QIcon.fromTheme('document-save'), "Save") index = None entry = None done_callback = None @classmethod def build(cls): """Build the interface.""" cls.lbl_timestamp.setWhatsThis("The timestamp for the entry.") cls.cal_timestamp.setWhatsThis("The timestamp for the entry.") cls.cal_timestamp.setDisplayFormat("yyyy MMM dd hh:mm:ss") cls.cal_timestamp.dateTimeChanged.connect(cls.edited) cls.lbl_hour.setWhatsThis("The hour part of the entry duration.") cls.spn_hour.setWhatsThis("The hour part of the entry duration.") cls.spn_hour.valueChanged.connect(cls.edited) cls.lbl_min.setWhatsThis("The minute part of the entry duration.") cls.spn_min.setWhatsThis("The minute part of the entry duration.") cls.spn_min.valueChanged.connect(cls.edited) cls.lbl_sec.setWhatsThis("The second part of the entry duration.") cls.spn_sec.setWhatsThis("The second part of the entry duration.") cls.spn_sec.valueChanged.connect(cls.edited) cls.lbl_activity.setWhatsThis("The activity notes for the entry.") cls.txt_activity.setWhatsThis("The activity notes for the entry.") cls.txt_activity.textChanged.connect(cls.edited) cls.grid_layout.addWidget(cls.lbl_timestamp, 0, 0, 1, 1) cls.grid_layout.addWidget(cls.cal_timestamp, 0, 1, 1, 1) cls.grid_layout.addWidget(cls.lbl_duration, 2, 0, 1, 2) cls.grid_layout.addWidget(cls.lbl_hour, 3, 0, 1, 1) cls.grid_layout.addWidget(cls.spn_hour, 3, 1, 1, 1) cls.grid_layout.addWidget(cls.lbl_min, 4, 0, 1, 1) cls.grid_layout.addWidget(cls.spn_min, 4, 1, 1, 1) cls.grid_layout.addWidget(cls.lbl_sec, 5, 0, 1, 1) cls.grid_layout.addWidget(cls.spn_sec, 5, 1, 1, 1) cls.grid_layout.addWidget(cls.lbl_activity, 6, 0, 1, 1) cls.grid_layout.addWidget(cls.txt_activity, 6, 1, 1, 1) cls.grid_widget.setLayout(cls.grid_layout) cls.btn_done.clicked.connect(cls.done) cls.btn_done.setWhatsThis("Return to time log.") cls.buttons_layout.addWidget(cls.btn_done) cls.buttons_layout.addWidget(cls.btn_revert) cls.buttons_layout.addWidget(cls.btn_save) cls.btn_save.clicked.connect(cls.save) cls.btn_save.setWhatsThis("Save the settings.") cls.btn_revert.clicked.connect(cls.refresh) cls.btn_revert.setWhatsThis("Discard changes to settings.") cls.buttons_widget.setLayout(cls.buttons_layout) cls.layout.addWidget(cls.grid_widget) cls.layout.addWidget(cls.buttons_widget) cls.widget.setLayout(cls.layout) cls.refresh() return cls.widget @classmethod def connect(cls, done=None): if done: cls.done_callback = done @classmethod def done(cls): if cls.done_callback: cls.done_callback() @classmethod def load_item(cls, timestamp): cls.entry = TimeLog.retrieve_from_log(timestamp) cls.refresh() @classmethod def edited(cls): cls.btn_done.setEnabled(False) cls.btn_revert.setEnabled(True) cls.btn_save.setEnabled(True) @classmethod def not_edited(cls): cls.btn_done.setEnabled(True) cls.btn_revert.setEnabled(False) cls.btn_save.setEnabled(False) @classmethod def refresh(cls): if cls.entry is None: return timestamp = cls.entry.timestamp datetime = QDateTime() datetime.setDate(QDate(timestamp.year, timestamp.month, timestamp.day)) datetime.setTime( QTime(timestamp.hour, timestamp.minute, timestamp.second)) cls.cal_timestamp.setDateTime(datetime) hours, minutes, seconds = cls.entry.duration cls.spn_hour.setValue(hours) cls.spn_min.setValue(minutes) cls.spn_sec.setValue(seconds) cls.txt_activity.setText(cls.entry.notes) cls.not_edited() @classmethod def save(cls): TimeLog.remove_from_log(cls.entry.timestamp) timestamp = datetime(cls.cal_timestamp.date().year(), cls.cal_timestamp.date().month(), cls.cal_timestamp.date().day(), cls.cal_timestamp.time().hour(), cls.cal_timestamp.time().minute(), cls.cal_timestamp.time().second()) new_timestamp = TimeLog.add_to_log(timestamp, cls.spn_hour.value(), cls.spn_min.value(), cls.spn_sec.value(), cls.txt_activity.text()) cls.not_edited() cls.entry = TimeLog.retrieve_from_log(new_timestamp) # Display the revised data. cls.refresh()
def initUI(self): QToolTip.setFont(QFont('SansSerif', 12)) Title = QLabel('Выберите параметры обучения нейросети') Title.setToolTip('Для корректной работы функций обучения и оптимизации \n' 'в каталоге с программой должны находится подкаталоги \n' 'train, val, test. В каждом из этих каталогов должно \n' 'быть столько подкаталогов с изображениями, сколько \n' 'необходимо распознавать классов') Title1 = QLabel('Выберите параметры исследования изображения') Title1.setToolTip('Для корректной работы функции классификации и локализации \n' 'изображения для исследования и модель нейросети должны \n' 'находиться в одном каталоге с программой, формат изображения \n' '.jpg, формат модели нейросети .h5, указывать формат в полях не нужно') TitleEp = QLabel('Эпохи:') TitleEp.setToolTip('Эпоха — один «проход» данных через нейросеть. \n' 'Изменение этого параметра позволяет избежать \n' 'недообученности или переобученности нейросети') TitleBa = QLabel('Размер мини-выборки:') TitleBa.setToolTip('Количество изображений загружаемых в нейросеть ' 'за раз') TitleTr = QLabel('Количество изображений для обучения:') TitleTr.setToolTip('Количество изображений во всех подкаталогах ' 'каталога train') TitleVa = QLabel('Количество изображений для проверки:') TitleVa.setToolTip('Количество изображений во всех подкаталогах ' 'каталога val') TitleTe = QLabel('Количество изображений для тестирования:') TitleTe.setToolTip('Количество изображений во всех подкаталогах ' 'каталога test') TitleSc = QLabel('Масштабирование пирамиды изображений:') TitleSc.setToolTip('Коэффициент масштабирования изображения') TitleSs = QLabel('Шаг скользящего окна:') TitleSs.setToolTip('Расстояние в пикселях, на которое смещается \n' 'окно классификатора по изображению за одну итерацию') TitleNi = QLabel('Имя изображения для исследования:') TitleNi.setToolTip('Наименование изображения без расширения. \n' 'Изображение должно иметь формат jpg и \n' 'находится в одном каталоге с программой, иначе \n' 'необходимо указывать полный путь до изображения') TitleNm = QLabel('Имя модели нейросети:') TitleNm.setToolTip('Наименование модели нейросети без расширения. \n' 'Модель должна иметь формат h5 и находится \n' 'в одном каталоге с программой, иначе необходимо \n' 'указывать полный путь до модели нейросети') TitleCl = QLabel('Количество классов:') self.InputEpochs = QSpinBox(self) self.InputEpochs.setRange(5,50) self.InputEpochs.setValue(10) self.InputBatch = QSpinBox(self) self.InputBatch.setRange(5,100) self.InputBatch.setValue(15) self.InputTrain = QSpinBox(self) self.InputTrain.setRange(100,100000) self.InputTrain.setValue(1050) self.InputValidation = QSpinBox(self) self.InputValidation.setRange(100,100000) self.InputValidation.setValue(225) self.InputTest = QSpinBox(self) self.InputTest.setRange(100,100000) self.InputTest.setValue(225) self.InputScale = QDoubleSpinBox(self) self.InputScale.setRange(1.1,5) self.InputScale.setValue(1.5) self.InputStep = QSpinBox(self) self.InputStep.setRange(1,150) self.InputStep.setValue(30) self.InputClass = QSpinBox(self) self.InputClass.setRange(3,20) self.InputClass.setValue(3) self.ImageName = QLineEdit("ImageName", self) self.ImageName.setMaxLength(20) self.ModelName = QLineEdit("TestModel", self) self.ModelName.setMaxLength(20) btn = QPushButton('Обучить нейросеть', self) btn.setToolTip('В результате обучения модель нейросети ' 'будет сохранена в каталоге с программой') btn.resize(btn.sizeHint()) btn.clicked.connect(self.buttonClicked) btn1 = QPushButton('Оптимизировать нейросеть', self) btn1.setToolTip('В результате оптимизации 3 лучшие модели ' 'будут сохранены в каталоге с программой') btn1.resize(btn1.sizeHint()) btn1.clicked.connect(self.buttonClicked1) btn2 = QPushButton('Поиск и распознавание', self) btn2.resize(btn2.sizeHint()) btn2.clicked.connect(self.buttonClicked2) grid = QGridLayout(self) grid.setSpacing(10) grid.addWidget(Title, 1, 0, 1, 4) grid.addWidget(TitleEp, 2, 0) grid.addWidget(TitleBa, 3, 0) grid.addWidget(TitleCl, 4, 0) grid.addWidget(self.InputEpochs, 2, 1) grid.addWidget(self.InputBatch, 3, 1) grid.addWidget(self.InputClass, 4, 1) grid.addWidget(TitleTr, 2, 2) grid.addWidget(TitleVa, 3, 2) grid.addWidget(TitleTe, 4, 2) grid.addWidget(self.InputTrain, 2, 3) grid.addWidget(self.InputValidation, 3, 3) grid.addWidget(self.InputTest, 4, 3) grid.addWidget(btn, 5, 0, 1, 2) grid.addWidget(btn1, 5, 2, 1, 2) grid.addWidget(Title1, 6, 0, 1, 4) grid.addWidget(TitleSc, 7, 0) grid.addWidget(self.InputScale, 7, 1) grid.addWidget(TitleSs, 7, 2) grid.addWidget(self.InputStep, 7, 3) grid.addWidget(TitleNi, 8, 0) grid.addWidget(self.ImageName, 8, 1) grid.addWidget(TitleNm, 8, 2) grid.addWidget(self.ModelName, 8, 3) grid.addWidget(btn2, 9, 1, 1, 2) self.setLayout(grid) self.setWindowTitle('Система поиска и распознавания сорных растений') self.setWindowIcon(QIcon('icon.png')) self.show()
def __init__(self, parent=None): QSpinBox.__init__(self, parent)
class PlanesWidget(ToolWidget): def __init__(self, image, parent=None): super(PlanesWidget, self).__init__(parent) self.chan_combo = QComboBox() self.chan_combo.addItems( [self.tr('Luminance'), self.tr('Red'), self.tr('Green'), self.tr('Blue'), self.tr('RGB Norm')]) self.plane_spin = QSpinBox() self.plane_spin.setPrefix(self.tr('Bit ')) self.plane_spin.setRange(0, 7) self.filter_combo = QComboBox() self.filter_combo.addItems([self.tr('Disabled'), self.tr('Median'), self.tr('Gaussian')]) self.image = image self.viewer = ImageViewer(self.image, self.image) self.planes = None self.preprocess() self.chan_combo.currentIndexChanged.connect(self.preprocess) self.plane_spin.valueChanged.connect(self.process) self.filter_combo.currentIndexChanged.connect(self.process) top_layout = QHBoxLayout() top_layout.addWidget(QLabel(self.tr('Channel:'))) top_layout.addWidget(self.chan_combo) top_layout.addWidget(QLabel(self.tr('Plane:'))) top_layout.addWidget(self.plane_spin) top_layout.addWidget(QLabel(self.tr('Filter:'))) top_layout.addWidget(self.filter_combo) top_layout.addStretch() main_layout = QVBoxLayout() main_layout.addLayout(top_layout) main_layout.addWidget(self.viewer) self.setLayout(main_layout) def preprocess(self): channel = self.chan_combo.currentIndex() if channel == 0: img = cv.cvtColor(self.image, cv.COLOR_BGR2GRAY) elif channel == 4: b, g, r = cv.split(self.image.astype(np.float64)) img = cv.sqrt(cv.pow(b, 2) + cv.pow(g, 2) + cv.pow(r, 2)).astype(np.uint8) else: img = self.image[:, :, 3 - channel] self.planes = [normalize_mat(cv.bitwise_and(np.full_like(img, 2**b), img), to_bgr=True) for b in range(8)] # rows, cols = img.shape # bits = 8 # data = [np.binary_repr(img[i][j], width=bits) for i in range(rows) for j in range(cols)] # self.planes = [ # (np.array([int(i[b]) for i in data], dtype=np.uint8) * 2 ** (bits - b - 1)).reshape( # (rows, cols)) for b in range(bits)] self.process() def process(self): plane = self.planes[self.plane_spin.value()] if self.filter_combo.currentIndex() == 1: plane = cv.medianBlur(plane, 3) elif self.filter_combo.currentIndex() == 2: plane = cv.GaussianBlur(plane, (3, 3), 0) self.viewer.update_processed(plane)
def validate(self,text,pos): return QSpinBox.validate(self,text,pos)
def setupUi(self, parent): """Setup the interfaces for the clock.""" if not self.objectName(): self.setObjectName(u"Clock") sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(parent.sizePolicy().hasHeightForWidth()) parent.setSizePolicy(sizePolicy) parent.setAutoFillBackground(True) parent.setWindowFlag(Qt.Widget, True) if os.uname().sysname == "Linux" or self.frameless: parent.setWindowFlag(Qt.FramelessWindowHint, True) self.tabWidget = QTabWidget(parent) self.tabWidget.setObjectName(u"tabWidget") self.tabWidget.setGeometry(QRect(0, 0, 800, 460)) # This works for Mac, but seems to not work with Linux/Arm/RPi # tabbar = self.tabWidget.tabBar() # tabbar.setMinimumSize(50, 24) # tabfont = QFont() # tabfont.setBold(True) # tabfont.setItalic(True) # tabfont.setPointSize(32) # tabbar.setFont(tabfont) # Setup the TABS self.clock = QWidget() self.clock.setObjectName(u"clock") self.tabWidget.addTab(self.clock, "") self.tabWidget.setTabText(self.tabWidget.indexOf(self.clock), "Clock") self.weather = QWeather(parent=None, debug=self.debug) self.tabWidget.addTab(self.weather, "") self.tabWidget.setTabText(self.tabWidget.indexOf(self.weather), "Weather") self.settings = QWidget() self.settings.setObjectName(u"settings") self.tabWidget.addTab(self.settings, "") self.tabWidget.setTabText(self.tabWidget.indexOf(self.settings), "Settings") self.tabWidget.setCurrentIndex(0) ################################################################################################# # Setup Clock Page ################################################################################################# self.analog = AnalogClock(self.clock) # DIGITAL clock in "clock" tab self.Digital = QLabel(self.clock) self.Digital.setObjectName(u"Digital") self.Digital.setGeometry(QRect(0, 5, 765, 71)) self.Digital.setAutoFillBackground(False) self.Digital.setStyleSheet(u"") self.Digital.setText(u"Current Time - Date + time") # Weather Icon self.weathericon = QWeatherIcon((480, 5), self.weather, parent=self.clock) self.weather.weather_updated.connect(self.weathericon.update) # Weather info on the Clock page. self.minipanel = QTempMiniPanel((475, 105), self.weather, parent=self.clock) self.weather.temp_updated.connect(self.minipanel.update) self.hilo = QHiLoTide((580, 5), parent=self.clock, debug=self.debug) # Moon phase self.moon = QMoon(pos=(450, 210), parent=self.clock, size=216, web=self.web) # Push buttons in "clock tab. push_button_width = 111 push_button_height = 40 push_button_x = 670 push_button_y = 220 self.ledball_off = QPushButton(self.clock) self.ledball_off.setObjectName(u"ledball_off") self.ledball_off.setText(u"LED off") self.ledball_off.setGeometry(QRect(push_button_x, push_button_y, push_button_width, push_button_height)) self.ledball_on = QPushButton(self.clock) self.ledball_on.setObjectName(u"ledball_on") self.ledball_on.setText(u"LED on ") self.ledball_on.setGeometry(QRect(push_button_x, push_button_y+push_button_height, push_button_width, push_button_height)) self.ledball_on2 = QPushButton(self.clock) self.ledball_on2.setObjectName(u"ledball_on2") self.ledball_on2.setText(u"LED on 2") self.ledball_on2.setGeometry(QRect(push_button_x, push_button_y+push_button_height*2, push_button_width, push_button_height)) self.sleep = QPushButton(self.clock) self.sleep.setObjectName(u"sleep") self.sleep.setText(u"Sleep") self.sleep.setGeometry(QRect(push_button_x, push_button_y+push_button_height*3+10, push_button_width, push_button_height)) ################################################################################################# # Setup Weather Page ################################################################################################# ################################################################################################# # Setup Setting Page ################################################################################################# self.timeEdit = QTimeEdit(self.settings) self.timeEdit.setObjectName(u"timeEdit") self.timeEdit.setDisplayFormat(u"h:mm AP") self.timeEdit.setGeometry(QRect(200, 30, 191, 41)) font8 = QFont() font8.setFamily(u"Gill Sans") font8.setPointSize(16) font8.setBold(False) font8.setItalic(False) font8.setWeight(50) self.timeEdit.setFont(font8) self.timeEdit.setAutoFillBackground(True) self.timeEdit.setTime(self.bedtime) self.bedtime_label = QLabel(self.settings) self.bedtime_label.setObjectName(u"bedtime_label") self.bedtime_label.setText(u"Set Bedtime:") self.bedtime_label.setGeometry(QRect(200, 0, 151, 31)) self.bedtime_label.setFont(font8) self.bedtime_label.setAutoFillBackground(True) self.Brightness_Value = QLCDNumber(self.settings) self.Brightness_Value.setObjectName(u"Brightness_Value") self.Brightness_Value.setGeometry(QRect(20, 120, 61, 31)) self.Brightness_Value.setStyleSheet(u"color: \"White\";\n" "margin:0px;\n" "border:0px;background:\"transparent\";") self.Brightness_Value.setDigitCount(3) self.Brightness_Value.setProperty("value", 180.000000000000000) self.Brightness = QSlider(self.settings) self.Brightness.setObjectName(u"Brightness") self.Brightness.setGeometry(QRect(30, 160, 51, 261)) self.Brightness.setAutoFillBackground(False) self.Brightness.setMaximum(255) self.Brightness.setValue(self.LCD_brightness) self.Brightness.setOrientation(Qt.Vertical) self.Brightness_label = QLabel(self.settings) self.Brightness_label.setObjectName(u"Brightness_label") self.Brightness_label.setText(u"Brightness") self.Brightness_label.setGeometry(QRect(20, 70, 101, 41)) font10 = QFont() font10.setFamily(u"Arial Black") font10.setPointSize(12) font10.setBold(True) font10.setWeight(75) self.Brightness_label.setFont(font10) self.temp_test = QLabel(self.settings) self.temp_test.setObjectName(u"temp_test") self.temp_test.setText(u"T20.5 C") self.temp_test.setFont(font8) self.temp_test.setGeometry(QRect(630, 60, 141, 51)) # self.temp_test.setFont(font_bold_20) self.temp_test_slide = QSlider(self.settings) self.temp_test_slide.setObjectName(u"temp_test_slide") self.temp_test_slide.setGeometry(QRect(660, 150, 51, 271)) self.temp_test_slide.setAutoFillBackground(False) self.temp_test_slide.setMinimum(-250) self.temp_test_slide.setMaximum(450) self.temp_test_slide.setSingleStep(5) self.temp_test_slide.setPageStep(25) self.temp_test_slide.setValue(38) self.temp_test_slide.setOrientation(Qt.Vertical) self.temp_check_outside = QCheckBox(self.settings) self.temp_check_outside.setObjectName(u"temp_check_outside") self.temp_check_outside.setText(u"Outside") self.temp_check_outside.setGeometry(QRect(640, 110, 86, 20)) self.grace_period = QSpinBox(self.settings) self.grace_period.setObjectName(u"grace_period") self.grace_period.setGeometry(QRect(411, 31, 111, 41)) self.grace_period.setFont(font8) self.grace_period.setMinimum(1) self.grace_period.setMaximum(60) self.grace_period.setValue(self.bedtime_grace_period) self.grace_period.setDisplayIntegerBase(10) self.grace_period_label = QLabel(self.settings) self.grace_period_label.setObjectName(u"grace_period_label") self.grace_period_label.setText(u"Grace period:") self.grace_period_label.setGeometry(QRect(410, 10, 111, 16)) self.grace_period_label.setFont(font8) ################################################################################################# # SET ALL LABEL TEXTS ################################################################################################# # if QT_CONFIG(tooltip) self.sleep.setToolTip(u"Put display to sleep") self.ledball_on2.setToolTip(u"Turn on the LED Ball, mode 2") self.ledball_on.setToolTip(u"Turn on the LED Ball.") self.ledball_off.setToolTip(u"Turn off the LED Ball.") # endif // QT_CONFIG(tooltip) ################################################################################################# # Make the Connections. ################################################################################################# self.temp_test_slide.valueChanged.connect(self.test_temp_update) self.temp_check_outside.clicked.connect(self.test_temp_update) self.ledball_off.clicked.connect(self.set_ledball_off) self.ledball_on.clicked.connect(self.set_ledball_on) self.ledball_on2.clicked.connect(self.set_ledball_on2) self.sleep.clicked.connect(self.set_sleep) self.timeEdit.timeChanged.connect(self.set_bedtime) self.grace_period.valueChanged.connect(self.set_grace_period) self.Brightness.valueChanged.connect(self.set_screen_brightness) self.Brightness.valueChanged.connect(self.Brightness_Value.display)
def init_ui(self): self.main_layout = QGridLayout(self) self.chart = HierarchicalChart(toolbar=True) self.main_layout.addWidget(self.chart, 0, 0, 1, 4) self.load_dataset_button = QPushButton(qta.icon("fa5s.database"), self.tr("Load Dataset")) self.load_dataset_button.clicked.connect( lambda: self.load_dataset_dialog.show()) self.main_layout.addWidget(self.load_dataset_button, 1, 0, 1, 2) self.n_samples_label = QLabel(self.tr("N<sub>components</sub>")) self.n_samples_label.setToolTip( self.tr("The Number of samples in the loaded dataset.")) self.n_samples_display = QLabel(self.tr("Unknown")) self.main_layout.addWidget(self.n_samples_label, 1, 2) self.main_layout.addWidget(self.n_samples_display, 1, 3) self.supported_methods = [ "single", "complete", "average", "weighted", "centroid", "median", "ward" ] self.supported_distances = [ "braycurtis", "canberra", "chebyshev", "cityblock", "correlation", "cosine", "dice", "euclidean", "hamming", "jaccard", "jensenshannon", "kulsinski", "mahalanobis", "matching", "minkowski", "rogerstanimoto", "russellrao", "seuclidean", "sokalmichener", "sokalsneath", "sqeuclidean", "yule" ] self.linkage_method_label = QLabel(self.tr("Linkage Method")) self.linkage_method_label.setToolTip( self. tr("The linkage method for calculating the distance between the newly formed cluster and each observation vector." )) self.linkage_method_combo_box = QComboBox() self.linkage_method_combo_box.addItems(self.supported_methods) self.linkage_method_combo_box.setCurrentText("ward") self.distance_label = QLabel(self.tr("Distance")) self.distance_label.setToolTip( self. tr("The distance metric to use in the case that y is a collection of observation vectors." )) self.distance_combo_box = QComboBox() self.distance_combo_box.addItems(self.supported_distances) self.distance_combo_box.setCurrentText("euclidean") self.main_layout.addWidget(self.linkage_method_label, 2, 0) self.main_layout.addWidget(self.linkage_method_combo_box, 2, 1) self.main_layout.addWidget(self.distance_label, 2, 2) self.main_layout.addWidget(self.distance_combo_box, 2, 3) self.p_label = QLabel(self.tr("p")) self.p_label.setToolTip( self. tr("Controls the number of leaves at the bottom level of the figure." )) self.p_input = QSpinBox() self.p_input.setMinimum(1) self.main_layout.addWidget(self.p_label, 3, 0) self.main_layout.addWidget(self.p_input, 3, 1) self.n_clusers_label = QLabel(self.tr("N<sub>clusters</sub>")) self.n_clusers_label.setToolTip( self.tr( "Controls the number of clusters of this clustering algorithm." )) self.n_clusers_input = QSpinBox() self.n_clusers_input.setMinimum(2) self.main_layout.addWidget(self.n_clusers_label, 3, 2) self.main_layout.addWidget(self.n_clusers_input, 3, 3) self.perform_button = QPushButton(qta.icon("ei.ok-sign"), self.tr("Perform")) self.perform_button.setEnabled(False) self.perform_button.clicked.connect(self.on_perform_clicked) self.show_typical_button = QPushButton(qta.icon("fa.area-chart"), self.tr("Show Typical")) self.show_typical_button.clicked.connect(self.on_show_typical_clicked) self.show_typical_button.setEnabled(False) self.save_button = QPushButton(qta.icon("fa5s.save"), self.tr("Save")) self.save_button.setEnabled(False) self.show_all_button = QPushButton(qta.icon("mdi.view-grid-outline"), self.tr("Show All")) self.show_all_button.setEnabled(False) self.show_all_button.clicked.connect(self.on_show_all_clicked) self.save_button.clicked.connect(self.on_save_clicked) self.main_layout.addWidget(self.perform_button, 4, 0, 1, 2) self.main_layout.addWidget(self.show_typical_button, 4, 2, 1, 2) self.main_layout.addWidget(self.save_button, 5, 0, 1, 2) self.main_layout.addWidget(self.show_all_button, 5, 2, 1, 2)
class NGL_HKLViewer(QWidget): def __init__(self, parent=None): super(NGL_HKLViewer, self).__init__(parent) self.verbose = 0 self.UseOSbrowser = False self.jscriptfname = "" self.devmode = False for e in sys.argv: if "verbose" in e: self.verbose = e.split("verbose=")[1] if "UseOSbrowser" in e: self.UseOSbrowser = e.split("UseOSbrowser=")[1] if "jscriptfname" in e: self.jscriptfname = e.split("jscriptfname=")[1] if "devmode" in e: self.devmode = True self.zmq_context = None self.bufsize = 20000 self.originalPalette = QApplication.palette() self.openFileNameButton = QPushButton("Load reflection file") self.openFileNameButton.setDefault(True) self.openFileNameButton.clicked.connect(self.OpenReflectionsFile) self.debugbutton = QPushButton("Debug") self.debugbutton.clicked.connect(self.DebugInteractively) self.settingsbtn = QPushButton("Settings") self.settingsbtn.clicked.connect(self.SettingsDialog) self.mousemoveslider = QSlider(Qt.Horizontal) self.mousemoveslider.setMinimum(0) self.mousemoveslider.setMaximum(300) self.mousemoveslider.setValue(0) self.mousemoveslider.sliderReleased.connect( self.onFinalMouseSensitivity) self.mousemoveslider.valueChanged.connect(self.onMouseSensitivity) self.mousesensitxtbox = QLineEdit('') self.mousesensitxtbox.setReadOnly(True) self.fontspinBox = QDoubleSpinBox() self.fontspinBox.setSingleStep(1) self.fontspinBox.setRange(4, 50) self.font = QFont() self.font.setFamily(self.font.defaultFamily()) self.fontspinBox.setValue(self.font.pointSize()) #self.fontspinBox.setValue(self.font.pixelSize()) self.fontspinBox.valueChanged.connect(self.onFontsizeChanged) self.Fontsize_labeltxt = QLabel() self.Fontsize_labeltxt.setText("Font size:") self.cameraPerspectCheckBox = QCheckBox() self.cameraPerspectCheckBox.setText("Perspective camera") self.cameraPerspectCheckBox.clicked.connect(self.onCameraPerspect) self.cameraPerspectCheckBox.setCheckState(Qt.Unchecked) self.settingsform = SettingsForm(self) self.MillerComboBox = QComboBox() self.MillerComboBox.activated.connect(self.onMillerComboSelchange) #self.MillerComboBox.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.MillerLabel = QLabel() self.MillerLabel.setText("Selected HKL Scene") self.HKLnameedit = QLineEdit('') self.HKLnameedit.setReadOnly(True) self.textInfo = QTextEdit() self.textInfo.setLineWrapMode(QTextEdit.NoWrap) self.textInfo.setReadOnly(True) labels = [ "Label", "Type", "no. of HKLs", "Span of HKLs", "Min Max data", "Min Max sigmas", "d_min, d_max", "Symmetry unique", "Anomalous" ] self.millertable = QTableWidget(0, len(labels)) self.millertable.setHorizontalHeaderLabels(labels) self.millertable.horizontalHeader().setDefaultAlignment(Qt.AlignLeft) # don't allow editing this table self.millertable.setEditTriggers(QTableWidget.NoEditTriggers) self.createExpansionBox() self.createFileInfoBox() self.CreateSliceTabs() self.createRadiiScaleGroupBox() self.createBinsBox() self.CreateFunctionTabs() mainLayout = QGridLayout() mainLayout.addWidget(self.FileInfoBox, 0, 0) mainLayout.addWidget(self.MillerLabel, 1, 0) mainLayout.addWidget(self.MillerComboBox, 2, 0) mainLayout.addWidget(self.functionTabWidget, 3, 0) mainLayout.addWidget(self.settingsbtn, 4, 0, 1, 1) #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) ) if self.UseOSbrowser == False: self.BrowserBox = QWebEngineView() mainLayout.addWidget(self.BrowserBox, 0, 1, 5, 3) self.BrowserBox.setUrl("https://cctbx.github.io/") #self.BrowserBox.setUrl("https://webglreport.com/") #self.BrowserBox.loadFinished.connect(self.onLoadFinished) mainLayout.setColumnStretch(2, 1) mainLayout.setRowStretch(0, 1) mainLayout.setRowStretch(1, 0) mainLayout.setRowStretch(2, 1) mainLayout.setRowStretch(3, 1) mainLayout.setColumnStretch(4, 0) self.setLayout(mainLayout) self.setWindowTitle("HKL-Viewer") self.cctbxproc = None self.LaunchCCTBXPython() self.out = None self.err = None self.comboviewwidth = 0 self.hklscenes_arrays = [] self.array_infotpls = [] self.matching_arrays = [] self.bin_infotpls = None self.bin_opacities = None self.html_url = "" self.spacegroups = [] self.info = [] self.infostr = "" self.fileisvalid = False self.NewFileLoaded = False self.NewHKLscenes = False self.updatingNbins = False self.binstableitemchanges = False self.show() def SettingsDialog(self): self.settingsform.show() def update(self): if self.cctbxproc: if self.cctbxproc.stdout: print(self.cctbxproc.stdout.read().decode("utf-8")) if self.cctbxproc.stderr: print(self.cctbxproc.stderr.read().decode("utf-8")) if self.out: print(self.out.decode("utf-8")) if self.err: print(self.err.decode("utf-8")) if self.zmq_context: try: msg = self.socket.recv( flags=zmq.NOBLOCK ) #To empty the socket from previous messages msgstr = msg.decode() self.infodict = eval(msgstr) #print("received from cctbx: " + str(self.infodict)) if self.infodict: if self.infodict.get("hklscenes_arrays"): self.hklscenes_arrays = self.infodict.get( "hklscenes_arrays", []) if self.infodict.get("array_infotpls"): self.array_infotpls = self.infodict.get( "array_infotpls", []) if self.infodict.get("bin_data_label"): self.BinDataComboBox.setCurrentText( self.infodict["bin_data_label"]) if self.infodict.get("bin_infotpls"): self.bin_infotpls = self.infodict["bin_infotpls"] self.nbins = len(self.bin_infotpls) self.updatingNbins = True self.Nbins_spinBox.setValue(self.nbins) self.updatingNbins = False self.binstable.clearContents() self.binstable.setRowCount(self.nbins) for row, bin_infotpl in enumerate(self.bin_infotpls): for col, elm in enumerate(bin_infotpl): # only allow changing the last column with opacity values if col != 3: item = QTableWidgetItem(str(elm)) else: item = QTableWidgetItem() item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) item.setCheckState(Qt.Checked) item.setFlags(item.flags() ^ Qt.ItemIsEditable) self.binstable.setItem(row, col, item) if self.bin_opacities: self.update_table_opacities() if self.infodict.get("bin_opacities"): self.bin_opacities = self.infodict["bin_opacities"] if self.binstable.rowCount() > 0: self.update_table_opacities() if self.infodict.get("html_url"): self.html_url = self.infodict["html_url"] if self.UseOSbrowser == False: self.BrowserBox.setUrl(self.html_url) # workaround for background colour bug in chromium # https://bugreports.qt.io/browse/QTBUG-41960 self.BrowserBox.page().setBackgroundColor( QColor(100, 100, 100, 1.0)) if self.infodict.get("spacegroups"): self.spacegroups = self.infodict.get("spacegroups", []) self.SpaceGroupComboBox.clear() self.SpaceGroupComboBox.addItems(self.spacegroups) if self.infodict.get("merge_data"): self.mergedata = self.infodict["merge_data"] currentinfostr = "" if self.infodict.get("info"): currentinfostr = self.infodict.get("info", []) if self.infodict.get("NewFileLoaded"): self.NewFileLoaded = self.infodict.get( "NewFileLoaded", False) if self.infodict.get("NewHKLscenes"): self.NewHKLscenes = self.infodict.get( "NewHKLscenes", False) self.fileisvalid = True #print("ngl_hkl_infodict: " + str(ngl_hkl_infodict)) if currentinfostr: #print(currentinfostr) self.infostr += currentinfostr + "\n" # display no more than self.bufsize bytes of text self.infostr = self.infostr[-self.bufsize:] self.textInfo.setPlainText(self.infostr) self.textInfo.verticalScrollBar().setValue( self.textInfo.verticalScrollBar().maximum()) if self.NewFileLoaded and self.NewHKLscenes: #if self.mergedata == True : val = Qt.CheckState.Checked #if self.mergedata == None : val = Qt.CheckState.PartiallyChecked #if self.mergedata == False : val = Qt.CheckState.Unchecked #self.mergecheckbox.setCheckState(val ) #print("got hklscenes: " + str(self.hklscenes_arrays)) self.MillerComboBox.clear() self.MillerComboBox.addItems( [e[3] for e in self.hklscenes_arrays]) self.MillerComboBox.setCurrentIndex( -1) # unselect the first item in the list self.comboviewwidth = 0 for e in self.hklscenes_arrays: self.comboviewwidth = max( self.comboviewwidth, self.MillerComboBox.fontMetrics().width(e[3])) self.MillerComboBox.view().setMinimumWidth( self.comboviewwidth) self.millertable.clearContents() self.millertable.setRowCount(len( self.hklscenes_arrays)) for n, millarr in enumerate(self.array_infotpls): for m, elm in enumerate(millarr): self.millertable.setItem( n, m, QTableWidgetItem(str(elm))) self.functionTabWidget.setDisabled(True) self.NewFileLoaded = False if self.NewHKLscenes: self.BinDataComboBox.clear() self.BinDataComboBox.addItems( ["Resolution"] + [e[3] for e in self.hklscenes_arrays]) self.BinDataComboBox.view().setMinimumWidth( self.comboviewwidth) #self.BinDataComboBox.setCurrentIndex(-1) # unselect the first item in the list self.NewHKLscenes = False except Exception as e: errmsg = str(e) if "Resource temporarily unavailable" not in errmsg: print(errmsg + traceback.format_exc(limit=10)) pass def onFinalMouseSensitivity(self): val = self.mousemoveslider.value() / 100.0 self.NGL_HKL_command( 'NGL_HKLviewer.viewer.NGL.mouse_sensitivity = %f' % val) def onMouseSensitivity(self): val = self.mousemoveslider.value() / 100.0 self.mousesensitxtbox.setText("%2.2f" % val) def onFontsizeChanged(self, val): font = app.font() font.setPointSize(val) app.setFont(font) self.settingsform.setFixedSize(self.settingsform.sizeHint()) def onCameraPerspect(self, val): if self.cameraPerspectCheckBox.isChecked(): self.NGL_HKL_command("NGL_HKLviewer.camera_type = perspective") else: self.NGL_HKL_command("NGL_HKLviewer.camera_type = orthographic") def MergeData(self): if self.mergecheckbox.checkState() == Qt.CheckState.Checked: self.NGL_HKL_command('NGL_HKLviewer.mergedata = True') if self.mergecheckbox.checkState() == Qt.CheckState.PartiallyChecked: self.NGL_HKL_command('NGL_HKLviewer.mergedata = None') if self.mergecheckbox.checkState() == Qt.CheckState.Unchecked: self.NGL_HKL_command('NGL_HKLviewer.mergedata = False') def ExpandToP1(self): if self.expandP1checkbox.isChecked(): self.NGL_HKL_command('NGL_HKLviewer.viewer.expand_to_p1 = True') else: self.NGL_HKL_command('NGL_HKLviewer.viewer.expand_to_p1 = False') def ExpandAnomalous(self): if self.expandAnomalouscheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.expand_anomalous = True') else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.expand_anomalous = False') def showSysAbsent(self): if self.sysabsentcheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_systematic_absences = True') else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_systematic_absences = False') def showMissing(self): if self.missingcheckbox.isChecked(): self.NGL_HKL_command('NGL_HKLviewer.viewer.show_missing = True') else: self.NGL_HKL_command('NGL_HKLviewer.viewer.show_missing = False') def showOnlyMissing(self): if self.onlymissingcheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_only_missing = True') else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_only_missing = False') def showSlice(self): if self.showslicecheckbox.isChecked(): self.NGL_HKL_command('NGL_HKLviewer.viewer.slice_mode = True') if self.expandP1checkbox.isChecked(): self.NGL_HKL_command("""NGL_HKLviewer.viewer { expand_to_p1 = True inbrowser = False } """) if self.expandAnomalouscheckbox.isChecked(): self.NGL_HKL_command("""NGL_HKLviewer.viewer { expand_anomalous = True inbrowser = False } """) else: self.NGL_HKL_command("""NGL_HKLviewer.viewer { slice_mode = False inbrowser = True } """) def onSliceComboSelchange(self, i): rmin = self.array_infotpls[self.MillerComboBox.currentIndex()][3][0][i] rmax = self.array_infotpls[self.MillerComboBox.currentIndex()][3][1][i] self.sliceindexspinBox.setRange(rmin, rmax) self.NGL_HKL_command("NGL_HKLviewer.viewer.slice_axis = %s" % self.sliceaxis[i]) def onSliceIndexChanged(self, val): self.sliceindex = val self.NGL_HKL_command("NGL_HKLviewer.viewer.slice_index = %d" % self.sliceindex) def onBindataComboSelchange(self, i): if self.BinDataComboBox.currentText(): if self.BinDataComboBox.currentIndex() > 0: bin_scene_label = str(self.BinDataComboBox.currentIndex() - 1) else: bin_scene_label = "Resolution" self.NGL_HKL_command("NGL_HKLviewer.bin_scene_label = %s" % bin_scene_label) def update_table_opacities(self, allalpha=None): bin_opacitieslst = eval(self.bin_opacities) self.binstable_isready = False for binopacity in bin_opacitieslst: if not allalpha: alpha = float(binopacity.split(",")[0]) else: alpha = allalpha bin = int(binopacity.split(",")[1]) item = QTableWidgetItem() item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) if alpha < 0.5: item.setCheckState(Qt.Unchecked) else: item.setCheckState(Qt.Checked) item.setFlags(item.flags() ^ Qt.ItemIsEditable) self.binstable.setItem(bin, 3, item) self.binstable_isready = True def SetOpaqueAll(self): if self.binstableitemchanges: return bin_opacitieslst = eval(self.bin_opacities) nbins = len(bin_opacitieslst) sum = 0 for binopacity in bin_opacitieslst: sum += float(binopacity.split(",")[0]) if sum >= nbins: self.OpaqueAllCheckbox.setCheckState(Qt.Checked) if sum == 0: self.OpaqueAllCheckbox.setCheckState(Qt.Unchecked) if sum > 0.0 and sum < nbins: self.OpaqueAllCheckbox.setCheckState(Qt.PartiallyChecked) def onBinsTableItemChanged(self, item): row = item.row() column = item.column() try: if item.checkState() == Qt.Unchecked: newval = 0 else: newval = 1.0 if column == 3 and self.binstable_isready: # changing opacity assert (newval <= 1.0 and newval >= 0.0) bin_opacitieslst = eval(self.bin_opacities) bin_opacitieslst[row] = str(newval) + ', ' + str(row) self.bin_opacities = str(bin_opacitieslst) self.SetOpaqueAll() self.NGL_HKL_command( 'NGL_HKLviewer.viewer.NGL.bin_opacities = "%s"' % self.bin_opacities) except Exception as e: print(str(e)) #self.binstable.currentItem().setText( self.currentSelectedBinsTableVal) def onBinsTableItemSelectionChanged(self): row = self.binstable.currentItem().row() column = self.binstable.currentItem().column() self.currentSelectedBinsTableVal = self.binstable.currentItem().text() #print( "in itemSelectionChanged " + self.currentSelectedBinsTableVal) def onOpaqueAll(self): self.binstableitemchanges = True bin_opacitieslst = eval(self.bin_opacities) nbins = len(bin_opacitieslst) bin_opacitieslst = [] self.binstable_isready = False if self.OpaqueAllCheckbox.isChecked(): for i in range(nbins): bin_opacitieslst.append("1.0, %d" % i) else: for i in range(nbins): bin_opacitieslst.append("0.0, %d" % i) self.bin_opacities = str(bin_opacitieslst) self.NGL_HKL_command('NGL_HKLviewer.viewer.NGL.bin_opacities = "%s"' % self.bin_opacities) self.binstableitemchanges = False self.binstable_isready = True """ def onLoadFinished(self, val): pass #print("web page finished loading now") def onBinsTableitemActivated(self, item): row = item.row() column = item.column() currentval = item.text() #print( "in itemActivated " + currentval) def onBinsTableCellentered(self, row, col): pass #print( "in Cellentered " + self.binstable.currentItem().text() ) def onBinsTableCellPressed(self, row, col): pass #print( "in CellPressed " + self.binstable.currentItem().text() ) """ def onNbinsChanged(self, val): self.nbins = val if not self.updatingNbins: # avoid possible endless loop to cctbx self.NGL_HKL_command("NGL_HKLviewer.nbins = %d" % self.nbins) def onRadiiScaleChanged(self, val): self.radii_scale = val self.NGL_HKL_command(""" NGL_HKLviewer.viewer { nth_power_scale_radii = %f scale = %f } """ % (self.nth_power_scale, self.radii_scale)) def onPowerScaleChanged(self, val): self.nth_power_scale = val self.NGL_HKL_command(""" NGL_HKLviewer.viewer { nth_power_scale_radii = %f scale = %f } """ % (self.nth_power_scale, self.radii_scale)) def onManualPowerScale(self): if self.ManualPowerScalecheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.nth_power_scale_radii = %f' % self.nth_power_scale) self.power_scale_spinBox.setEnabled(True) else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.nth_power_scale_radii = -1.0') self.power_scale_spinBox.setEnabled(False) self.nth_power_scale = -1.0 def OpenReflectionsFile(self): options = QFileDialog.Options() fileName, filtr = QFileDialog.getOpenFileName( self, "Load reflections file", "", "All Files (*);;MTZ Files (*.mtz);;CIF (*.cif)", "", options) if fileName: self.HKLnameedit.setText(fileName) #self.infostr = "" self.textInfo.setPlainText("") self.fileisvalid = False self.NGL_HKL_command('NGL_HKLviewer.filename = "%s"' % fileName) self.MillerComboBox.clear() self.BinDataComboBox.clear() def createExpansionBox(self): self.SpaceGroupComboBox = QComboBox() self.SpaceGroupComboBox.activated.connect(self.SpacegroupSelchange) self.SpacegroupLabel = QLabel() self.SpacegroupLabel.setText("Space Subgroups") self.mergecheckbox = QCheckBox() self.mergecheckbox.setText("Merge data") #self.mergecheckbox.setTristate (True) self.mergecheckbox.clicked.connect(self.MergeData) self.expandP1checkbox = QCheckBox() self.expandP1checkbox.setText("Expand to P1") self.expandP1checkbox.clicked.connect(self.ExpandToP1) self.expandAnomalouscheckbox = QCheckBox() self.expandAnomalouscheckbox.setText("Show Friedel pairs") self.expandAnomalouscheckbox.clicked.connect(self.ExpandAnomalous) self.sysabsentcheckbox = QCheckBox() self.sysabsentcheckbox.setText("Show Systematic Absences") self.sysabsentcheckbox.clicked.connect(self.showSysAbsent) self.missingcheckbox = QCheckBox() self.missingcheckbox.setText("Show Missing") self.missingcheckbox.clicked.connect(self.showMissing) self.onlymissingcheckbox = QCheckBox() self.onlymissingcheckbox.setText("Only Show Missing") self.onlymissingcheckbox.clicked.connect(self.showOnlyMissing) self.ExpansionBox = QGroupBox("Expansions") layout = QGridLayout() layout.addWidget(self.SpacegroupLabel, 0, 0) layout.addWidget(self.SpaceGroupComboBox, 0, 1) #layout.addWidget(self.mergecheckbox, 1, 0) layout.addWidget(self.expandP1checkbox, 1, 0) layout.addWidget(self.expandAnomalouscheckbox, 1, 1) layout.addWidget(self.sysabsentcheckbox, 2, 0) layout.addWidget(self.missingcheckbox, 3, 0) layout.addWidget(self.onlymissingcheckbox, 3, 1) layout.setRowStretch(0, 0) layout.setRowStretch(1, 0) layout.setRowStretch(2, 0) layout.setRowStretch(3, 1) self.ExpansionBox.setLayout(layout) def CreateSliceTabs(self): self.showslicecheckbox = QCheckBox() self.showslicecheckbox.setText("Show Slice") self.showslicecheckbox.clicked.connect(self.showSlice) self.sliceindexspinBox = QDoubleSpinBox() self.sliceindex = 0 self.sliceindexspinBox.setValue(self.sliceindex) self.sliceindexspinBox.setDecimals(0) self.sliceindexspinBox.setSingleStep(1) self.sliceindexspinBox.setRange(0, 20) self.sliceindexspinBox.valueChanged.connect(self.onSliceIndexChanged) self.SliceLabelComboBox = QComboBox() self.SliceLabelComboBox.activated.connect(self.onSliceComboSelchange) self.sliceaxis = ["h", "k", "l"] self.SliceLabelComboBox.addItems(self.sliceaxis) self.sliceTabWidget = QTabWidget() tab1 = QWidget() layout1 = QGridLayout() layout1.addWidget(self.showslicecheckbox, 0, 0, 1, 1) layout1.addWidget(self.SliceLabelComboBox, 0, 1, 1, 1) layout1.addWidget(self.sliceindexspinBox, 0, 2, 1, 1) tab1.setLayout(layout1) tab2 = QWidget() layout2 = QGridLayout() self.hvec_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.hvecval = 2.0 self.hvec_spinBox.setValue(self.hvecval) self.hvec_spinBox.setDecimals(2) self.hvec_spinBox.setSingleStep(0.5) self.hvec_spinBox.setRange(-100.0, 10.0) self.hvec_spinBox.valueChanged.connect(self.onHvecChanged) self.hvec_Label = QLabel() self.hvec_Label.setText("H") layout2.addWidget(self.hvec_Label, 0, 0, 1, 1) layout2.addWidget(self.hvec_spinBox, 0, 1, 1, 1) self.kvec_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.kvecval = 0.0 self.kvec_spinBox.setValue(self.kvecval) self.kvec_spinBox.setDecimals(2) self.kvec_spinBox.setSingleStep(0.5) self.kvec_spinBox.setRange(-100.0, 100.0) self.kvec_spinBox.valueChanged.connect(self.onKvecChanged) self.kvec_Label = QLabel() self.kvec_Label.setText("K") layout2.addWidget(self.kvec_Label, 1, 0, 1, 1) layout2.addWidget(self.kvec_spinBox, 1, 1, 1, 1) self.lvec_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.lvecval = 0.0 self.lvec_spinBox.setValue(self.lvecval) self.lvec_spinBox.setDecimals(2) self.lvec_spinBox.setSingleStep(0.5) self.lvec_spinBox.setRange(-100.0, 100.0) self.lvec_spinBox.valueChanged.connect(self.onLvecChanged) self.lvec_Label = QLabel() self.lvec_Label.setText("L") layout2.addWidget(self.lvec_Label, 2, 0, 1, 1) layout2.addWidget(self.lvec_spinBox, 2, 1, 1, 1) self.hkldist_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.hkldistval = 0.0 self.hkldist_spinBox.setValue(self.hkldistval) self.hkldist_spinBox.setDecimals(2) self.hkldist_spinBox.setSingleStep(0.5) self.hkldist_spinBox.setRange(-100.0, 100.0) self.hkldist_spinBox.valueChanged.connect(self.onHKLdistChanged) self.hkldist_Label = QLabel() self.hkldist_Label.setText("Distance from Origin") layout2.addWidget(self.hkldist_Label, 3, 0, 1, 1) layout2.addWidget(self.hkldist_spinBox, 3, 1, 1, 1) self.clipwidth_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.clipwidthval = 0.5 self.clipwidth_spinBox.setValue(self.clipwidthval) self.clipwidth_spinBox.setDecimals(2) self.clipwidth_spinBox.setSingleStep(0.05) self.clipwidth_spinBox.setRange(0.0, 100.0) self.clipwidth_spinBox.valueChanged.connect(self.onClipwidthChanged) self.clipwidth_Label = QLabel() self.clipwidth_Label.setText("Clip Plane Width") layout2.addWidget(self.clipwidth_Label, 4, 0, 1, 1) layout2.addWidget(self.clipwidth_spinBox, 4, 1, 1, 1) self.ClipBox = QGroupBox("Normal Vector to Clip Plane") self.ClipBox.setLayout(layout2) layout3 = QGridLayout() self.ClipPlaneChkBox = QCheckBox(self.sliceTabWidget) self.ClipPlaneChkBox.setText( "Use clip plane normal to HKL vector pointing out") self.ClipPlaneChkBox.clicked.connect(self.onClipPlaneChkBox) layout3.addWidget(self.ClipPlaneChkBox, 0, 0) layout3.addWidget(self.ClipBox, 1, 0) tab2.setLayout(layout3) self.sliceTabWidget.addTab(tab1, "Explicit Slicing") self.sliceTabWidget.addTab(tab2, "Clip Plane Slicing") self.ClipBox.setDisabled(True) def onClipPlaneChkBox(self): if self.ClipPlaneChkBox.isChecked(): self.ClipBox.setDisabled(False) philstr = """NGL_HKLviewer.normal_clip_plane { h = %s k = %s l = %s hkldist = %s clipwidth = %s } NGL_HKLviewer.viewer.NGL.fixorientation = %s """ %(self.hvecval, self.kvecval, self.lvecval, self.hkldistval, self.clipwidthval, \ str(self.fixedorientcheckbox.isChecked()) ) self.NGL_HKL_command(philstr) else: self.ClipBox.setDisabled(True) self.NGL_HKL_command( "NGL_HKLviewer.normal_clip_plane.clipwidth = None") def onClipwidthChanged(self, val): self.clipwidthval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.clipwidth = %f" % self.clipwidthval) def onHKLdistChanged(self, val): self.hkldistval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.hkldist = %f" % self.hkldistval) def onHvecChanged(self, val): self.hvecval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.h = %f" % self.hvecval) def onKvecChanged(self, val): self.kvecval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.k = %f" % self.kvecval) def onLvecChanged(self, val): self.lvecval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.l = %f" % self.lvecval) def onFixedorient(self): self.NGL_HKL_command('NGL_HKLviewer.viewer.NGL.fixorientation = %s' \ %str(self.fixedorientcheckbox.isChecked())) def onMillerComboSelchange(self, i): self.NGL_HKL_command("NGL_HKLviewer.scene_id = %d" % i) #self.MillerComboBox.setCurrentIndex(i) if self.MillerComboBox.currentText(): self.functionTabWidget.setEnabled(True) self.expandAnomalouscheckbox.setEnabled(True) # don' allow anomalous expansion for data that's already anomalous for arrayinfo in self.array_infotpls: isanomalous = arrayinfo[-1] label = arrayinfo[0] if isanomalous and label == self.MillerComboBox.currentText( )[:len(label)]: self.expandAnomalouscheckbox.setDisabled(True) else: self.functionTabWidget.setDisabled(True) self.SpaceGroupComboBox.clear() self.SpaceGroupComboBox.addItems(self.spacegroups) # need to supply issymunique flag in infotuple #if self.hklscenes_arrays[ i ][6] == 0: # self.mergecheckbox.setEnabled(True) #else: # self.mergecheckbox.setEnabled(False) def createFileInfoBox(self): self.FileInfoBox = QGroupBox("Reflection File Information") layout = QGridLayout() layout.addWidget(self.openFileNameButton, 0, 0, 1, 2) if self.devmode: layout.addWidget(self.debugbutton, 0, 2, 1, 1) layout.addWidget(self.HKLnameedit, 1, 0, 1, 3) layout.addWidget(self.millertable, 2, 0, 1, 3) layout.addWidget(self.textInfo, 3, 0, 1, 3) #layout.setColumnStretch(1, 2) self.FileInfoBox.setLayout(layout) def createRadiiScaleGroupBox(self): self.RadiiScaleGroupBox = QGroupBox("Radii Size of HKL Spheres") self.ManualPowerScalecheckbox = QCheckBox() self.ManualPowerScalecheckbox.setText( "Manual Power Scaling of Sphere Radii") self.ManualPowerScalecheckbox.clicked.connect(self.onManualPowerScale) self.power_scale_spinBox = QDoubleSpinBox(self.RadiiScaleGroupBox) self.nth_power_scale = 0.5 self.power_scale_spinBox.setValue(self.nth_power_scale) self.power_scale_spinBox.setDecimals(2) self.power_scale_spinBox.setSingleStep(0.05) self.power_scale_spinBox.setRange(0.0, 1.0) self.power_scale_spinBox.valueChanged.connect(self.onPowerScaleChanged) self.power_scale_spinBox.setEnabled(False) self.powerscaleLabel = QLabel() self.powerscaleLabel.setText("Power scale Factor") self.radii_scale_spinBox = QDoubleSpinBox(self.RadiiScaleGroupBox) self.radii_scale = 1.0 self.radii_scale_spinBox.setValue(self.radii_scale) self.radii_scale_spinBox.setDecimals(1) self.radii_scale_spinBox.setSingleStep(0.1) self.radii_scale_spinBox.setRange(0.2, 2.0) self.radii_scale_spinBox.valueChanged.connect(self.onRadiiScaleChanged) self.radiiscaleLabel = QLabel() self.radiiscaleLabel.setText("Linear Scale Factor") layout = QGridLayout() layout.addWidget(self.ManualPowerScalecheckbox, 1, 0, 1, 2) layout.addWidget(self.powerscaleLabel, 2, 0, 1, 2) layout.addWidget(self.power_scale_spinBox, 2, 1, 1, 2) layout.addWidget(self.radiiscaleLabel, 3, 0, 1, 2) layout.addWidget(self.radii_scale_spinBox, 3, 1, 1, 2) layout.setColumnStretch(0, 1) layout.setColumnStretch(1, 0) self.RadiiScaleGroupBox.setLayout(layout) def createBinsBox(self): self.binstable = QTableWidget(0, 4) self.binstable_isready = False labels = [ "no. of HKLs", "lower bin value", "upper bin value", "opacity" ] self.binstable.setHorizontalHeaderLabels(labels) self.binstable.horizontalHeader().setDefaultAlignment(Qt.AlignLeft) self.bindata_labeltxt = QLabel() self.bindata_labeltxt.setText("Data binned:") self.Nbins_spinBox = QSpinBox() self.Nbins_spinBox.setSingleStep(1) self.Nbins_spinBox.setRange(1, 40) self.Nbins_spinBox.valueChanged.connect(self.onNbinsChanged) self.Nbins_labeltxt = QLabel() self.Nbins_labeltxt.setText("Number of bins:") self.OpaqueAllCheckbox = QCheckBox() #self.OpaqueAllCheckbox.setTristate() self.OpaqueAllCheckbox.setText("Show all data in bins") self.OpaqueAllCheckbox.clicked.connect(self.onOpaqueAll) self.binstable.itemChanged.connect(self.onBinsTableItemChanged) self.binstable.itemSelectionChanged.connect( self.onBinsTableItemSelectionChanged) self.BinDataComboBox = QComboBox() self.BinDataComboBox.activated.connect(self.onBindataComboSelchange) self.BinsGroupBox = QGroupBox("Bins") layout = QGridLayout() layout.addWidget(self.bindata_labeltxt, 0, 0) layout.addWidget(self.BinDataComboBox, 0, 1) layout.addWidget(self.Nbins_labeltxt, 0, 2) layout.addWidget(self.Nbins_spinBox, 0, 3) layout.addWidget(self.OpaqueAllCheckbox, 1, 2) layout.addWidget(self.binstable, 2, 0, 1, 4) layout.setColumnStretch(0, 0) layout.setColumnStretch(1, 2) layout.setColumnStretch(3, 1) self.BinsGroupBox.setLayout(layout) def DebugInteractively(self): import code, traceback code.interact(local=locals(), banner="".join(traceback.format_stack(limit=10))) def CreateFunctionTabs(self): self.functionTabWidget = QTabWidget() tab1 = QWidget() layout1 = QGridLayout() layout1.addWidget(self.ExpansionBox, 0, 0) layout1.setRowStretch(0, 0) tab1.setLayout(layout1) tab2 = QWidget() layout2 = QGridLayout() self.fixedorientcheckbox = QCheckBox(self.sliceTabWidget) self.fixedorientcheckbox.setText( "Fix orientation but allow zoom and translation") self.fixedorientcheckbox.clicked.connect(self.onFixedorient) layout2.addWidget(self.fixedorientcheckbox, 0, 0) layout2.addWidget(self.sliceTabWidget, 1, 0) tab2.setLayout(layout2) tab3 = QWidget() layout3 = QGridLayout() layout3.addWidget(self.RadiiScaleGroupBox, 0, 0) tab3.setLayout(layout3) tab4 = QWidget() layout4 = QGridLayout() layout4.addWidget(self.BinsGroupBox, 0, 0) tab4.setLayout(layout4) self.functionTabWidget.addTab(tab1, "Expand") self.functionTabWidget.addTab(tab2, "Slice") self.functionTabWidget.addTab(tab3, "Size") self.functionTabWidget.addTab(tab4, "Bins") self.functionTabWidget.setDisabled(True) def SpacegroupSelchange(self, i): self.NGL_HKL_command("NGL_HKLviewer.spacegroup_choice = %d" % i) def find_free_port(self): import socket s = socket.socket() s.bind(('', 0)) # Bind to a free port provided by the host. port = s.getsockname()[1] s.close() return port def LaunchCCTBXPython(self): self.sockport = self.find_free_port() self.zmq_context = zmq.Context() self.socket = self.zmq_context.socket(zmq.PAIR) self.socket.bind("tcp://127.0.0.1:%s" % self.sockport) try: msg = self.socket.recv( flags=zmq.NOBLOCK) #To empty the socket from previous messages except Exception as e: pass cmdargs = 'cctbx.python.bat -i -c "from crys3d.hklview import cmdlineframes;' \ + ' myHKLview = cmdlineframes.HKLViewFrame(useGuiSocket=%s, high_quality=True,' %self.sockport \ + ' jscriptfname = \'%s\', ' %self.jscriptfname \ + ' verbose=%s, UseOSBrowser= %s )"\n' %(self.verbose, str(self.UseOSbrowser)) self.cctbxproc = subprocess.Popen(cmdargs, shell=True, stdin=subprocess.PIPE, stdout=sys.stdout, stderr=sys.stderr) #time.sleep(1) def NGL_HKL_command(self, cmdstr): #print("sending:\n" + cmdstr) self.socket.send(bytes(cmdstr, "utf-8"))
def onFunctionTecTree(self, item, column, function_ui, data, hidden_columns): group_box = function_ui.findChild(QGroupBox, "parameter_box") display_name_box = function_ui.findChild(QLineEdit, "display_name") labels = group_box.findChildren(QLabel) spin_boxs = group_box.findChildren(QSpinBox) for label in labels: label.close() for spin_box in spin_boxs: spin_box.close() text = item.text(column) if text in talib.get_function_groups().keys(): return indicator = abstract.Function(text.lower()) info = indicator.info display_name = info.get("display_name", "") display_name_box.setText(display_name) params_dict = indicator.get_parameters() keys = list(params_dict.keys()) keys.insert(0, u"Column") locator = 20 num = 0 paras_locators = [locator + i * 30 for i in range(len(keys))] for key in keys: p = paras_locators[num] label = QLabel(group_box) label.setText(key) label.setGeometry(10, p, 100, 20) if key == "Column": combo_box = QComboBox(group_box) combo_box.setGeometry(100, p, 100, 20) combo_box.setObjectName(key) combo_box.setWhatsThis(key) columns = [ i for i in list(data.columns) if i not in hidden_columns ] combo_box.addItems(columns) if "close" in columns: combo_box.setCurrentText("close") combo_box.show() else: spin_box = QSpinBox(group_box) spin_box.setGeometry(100, p, 50, 20) spin_box.setObjectName(text) spin_box.setWhatsThis(key) value = params_dict[key] spin_box.setValue(value) spin_box.show() label.show() num += 1
class MixedDistributionChart(QDialog): def __init__(self, parent=None, show_mode=True, toolbar=False, use_animation=False): flags = Qt.Window | Qt.WindowTitleHint | Qt.CustomizeWindowHint | Qt.WindowCloseButtonHint super().__init__(parent=parent, f=flags) self.setWindowTitle(self.tr("Mixed Distribution Chart")) self.figure = plt.figure(figsize=(4, 3)) self.axes = self.figure.subplots() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) self.main_layout = QGridLayout(self) self.main_layout.addWidget(self.toolbar, 0, 0, 1, 2) self.main_layout.addWidget(self.canvas, 1, 0, 1, 2) if not toolbar: self.toolbar.hide() self.supported_scales = [("log-linear", self.tr("Log-linear")), ("log", self.tr("Log")), ("phi", self.tr("φ")), ("linear", self.tr("Linear"))] self.scale_label = QLabel(self.tr("Scale")) self.scale_combo_box = QComboBox() self.scale_combo_box.addItems([name for key, name in self.supported_scales]) self.scale_combo_box.currentIndexChanged.connect(self.update_chart) self.main_layout.addWidget(self.scale_label, 2, 0) self.main_layout.addWidget(self.scale_combo_box, 2, 1) self.interval_label = QLabel(self.tr("Interval [ms]")) self.interval_input = QSpinBox() self.interval_input.setRange(0, 10000) self.interval_input.setValue(30) self.interval_input.valueChanged.connect(self.update_animation) self.main_layout.addWidget(self.interval_label, 3, 0) self.main_layout.addWidget(self.interval_input, 3, 1) self.repeat_check_box = QCheckBox(self.tr("Repeat")) self.repeat_check_box.setChecked(False) self.repeat_check_box.stateChanged.connect(self.update_animation) self.save_button = QPushButton(self.tr("Save")) self.save_button.clicked.connect(self.save_animation) self.main_layout.addWidget(self.repeat_check_box, 4, 0) self.main_layout.addWidget(self.save_button, 4, 1) self.show_mode = show_mode self.animation = None self.last_model = None self.last_result = None if not use_animation: self.interval_label.setVisible(False) self.interval_input.setVisible(False) self.repeat_check_box.setVisible(False) self.save_button.setVisible(False) self.normal_msg = QMessageBox(parent=self) self.file_dialog = QFileDialog(parent=self) @property def scale(self) -> str: index = self.scale_combo_box.currentIndex() key, name = self.supported_scales[index] return key @property def transfer(self) -> typing.Callable: if self.scale == "log-linear": return lambda classes_φ: convert_φ_to_μm(classes_φ) elif self.scale == "log": return lambda classes_φ: np.log(convert_φ_to_μm(classes_φ)) elif self.scale == "phi": return lambda classes_φ: classes_φ elif self.scale == "linear": return lambda classes_φ: convert_φ_to_μm(classes_φ) @property def xlabel(self) -> str: if self.scale == "log-linear": return self.tr("Grain-size [μm]") elif self.scale == "log": return self.tr("Ln(grain-size in μm)") elif self.scale == "phi": return self.tr("Grain-size [φ]") elif self.scale == "linear": return self.tr("Grain-size [μm]") @property def ylabel(self) -> str: return self.tr("Frequency") @property def xlog(self) -> bool: if self.scale == "log-linear": return True else: return False @property def interval(self) -> float: return self.interval_input.value() @property def repeat(self) -> bool: return self.repeat_check_box.isChecked() def show_demo(self): demo_model = get_demo_view_model() self.show_model(demo_model) def update_chart(self): if self.last_model is not None: self.show_model(self.last_model) elif self.last_result is not None: self.show_result(self.last_result) def update_animation(self): if self.last_result is not None: self.show_result(self.last_result) def show_model(self, model: SSUViewModel, quick=False): if self.animation is not None: self.animation._stop() self.animation = None if not quick: self.last_result = None self.last_model = model self.interval_label.setEnabled(False) self.interval_input.setEnabled(False) self.repeat_check_box.setEnabled(False) self.save_button.setEnabled(False) self.axes.clear() x = self.transfer(model.classes_φ) if self.xlog: self.axes.set_xscale("log") self.axes.set_title(model.title) self.axes.set_xlabel(self.xlabel) self.axes.set_ylabel(self.ylabel) self.target = self.axes.plot(x, model.target, c="#ffffff00", marker=".", ms=8, mfc="black", mew=0.0, label=self.tr("Target"))[0] # scatter can not be modified from the tool bar # self.target = self.axes.scatter(x, model.target, c="black", s=1) self.axes.set_xlim(x[0], x[-1]) self.axes.set_ylim(0.0, round(np.max(model.target)*1.2, 2)) self.mixed = self.axes.plot(x, model.mixed, c="black", label=self.tr("Mixed"))[0] self.components = [self.axes.plot(x, distribution*fraction, c=plt.get_cmap()(i), label=model.component_prefix+str(i+1))[0] for i, (distribution, fraction) in enumerate(zip(model.distributions, model.fractions))] if self.show_mode: modes = [self.transfer(model.classes_φ[np.unravel_index(np.argmax(distribution), distribution.shape)]) for distribution in model.distributions] colors = [plt.get_cmap()(i) for i in range(model.n_components)] self.vlines = self.axes.vlines(modes, 0.0, round(np.max(model.target)*1.2, 2), colors=colors) if model.n_components < 6: self.axes.legend(loc="upper left") self.figure.tight_layout() self.canvas.draw() else: self.mixed.set_ydata(model.mixed) for comp, distribution, fraction in zip(self.components, model.distributions, model.fractions): comp.set_ydata(distribution*fraction) if self.show_mode: modes = [self.transfer(model.classes_φ[np.unravel_index(np.argmax(distribution), distribution.shape)]) for distribution in model.distributions] self.vlines.set_offsets(modes) self.canvas.draw() def show_result(self, result: SSUResult): if self.animation is not None: self.animation._stop() self.animation = None self.last_model = None self.last_result = result self.interval_label.setEnabled(True) self.interval_input.setEnabled(True) self.repeat_check_box.setEnabled(True) self.save_button.setEnabled(True) models = iter(result.view_models) first = next(models) x = self.transfer(first.classes_φ) self.axes.cla() if self.xlog: self.axes.set_xscale("log") self.axes.set_title(first.title) self.axes.set_xlabel(self.xlabel) self.axes.set_ylabel(self.ylabel) self.target = self.axes.plot(x, first.target, c="#ffffff00", marker=".", ms=8, mfc="black", mew=0.0)[0] self.axes.set_xlim(x[0], x[-1]) self.axes.set_ylim(0.0, round(np.max(first.target)*1.2, 2)) self.figure.tight_layout() # self.canvas.draw() colors = [plt.get_cmap()(i) for i in range(first.n_components)] def init(): model = first self.mixed = self.axes.plot(x, model.mixed, c="black")[0] self.components = [self.axes.plot(x, distribution*fraction, c=plt.get_cmap()(i))[0] for i, (distribution, fraction) in enumerate(zip(model.distributions, model.fractions))] if self.show_mode: modes = [self.transfer(model.classes_φ[np.unravel_index(np.argmax(distribution), distribution.shape)]) for distribution in model.distributions] self.vlines = self.axes.vlines(modes, 0.0, round(np.max(model.target)*1.2, 2), colors=colors) return self.mixed, self.vlines, *self.components def animate(current): model = current self.mixed.set_ydata(current.mixed) for line, distribution, fraction in zip(self.components, model.distributions, model.fractions): line.set_ydata(distribution*fraction) if self.show_mode: self.vlines.remove() modes = [self.transfer(model.classes_φ[np.unravel_index(np.argmax(distribution), distribution.shape)]) for distribution in model.distributions] self.vlines = self.axes.vlines(modes, 0.0, round(np.max(model.target)*1.2, 2), colors=colors) return self.mixed, self.vlines, *self.components self.animation = FuncAnimation(self.figure, animate, frames=models, init_func=init, interval=self.interval, blit=True, repeat=self.repeat, repeat_delay=3.0, save_count=result.n_iterations) def save_animation(self): if self.last_result is not None: filename, format_str = self.file_dialog.getSaveFileName(self, self.tr("Save the animation of this SSU result"), None, self.tr("MPEG-4 Video File (*.mp4);;Graphics Interchange Format (*.gif)")) if filename is None or filename == "": return progress = QProgressDialog(self) progress.setRange(0, 100) progress.setLabelText(self.tr("Saving Animation [{0} Frames]").format(self.last_result.n_iterations)) canceled = False def save_callback(i, n): if progress.wasCanceled(): nonlocal canceled canceled = True raise StopIteration() progress.setValue((i+1)/n*100) QCoreApplication.processEvents() self.show_result(self.last_result) # plt.rcParams["savefig.dpi"] = 120.0 if "*.gif" in format_str: if not ImageMagickWriter.isAvailable(): self.normal_msg.setWindowTitle(self.tr("Error")) self.normal_msg.setText(self.tr("ImageMagick is not installed, please download and install it from its offical website (https://imagemagick.org/index.php).")) self.normal_msg.exec_() else: self.animation.save(filename, writer="imagemagick", fps=30, progress_callback=save_callback) elif "*.mp4" in format_str: if not FFMpegWriter.isAvailable(): self.normal_msg.setWindowTitle(self.tr("Error")) self.normal_msg.setText(self.tr("FFMpeg is not installed, please download and install it from its offical website (https://ffmpeg.org/).")) self.normal_msg.exec_() else: self.animation.save(filename, writer="ffmpeg", fps=30, progress_callback=save_callback) # plt.rcParams["savefig.dpi"] = 300.0 if not canceled: progress.setValue(100)
class StreamFieldsWidget(QDialog): """ A stream widget containing schema-specific properties. """ def __init__(self, parent, show_only_f142_stream: bool = False): super().__init__() self.setParent(parent) self.setLayout(QGridLayout()) self.setWindowModality(Qt.WindowModal) self.setModal(True) self._show_only_f142_stream = show_only_f142_stream self.minimum_spinbox_value = 0 self.maximum_spinbox_value = 100_000_000 self.advanced_options_enabled = False self.hs00_unimplemented_label = QLabel( "hs00 (Event histograms) has not yet been fully implemented.") self.schema_label = QLabel("Schema: ") self.schema_combo = DropDownList() self.schema_validator = SchemaSelectionValidator() self.schema_combo.setValidator(self.schema_validator) self.schema_validator.is_valid.connect( partial(validate_general_widget, self.schema_combo)) self.topic_label = QLabel("Topic: ") self.topic_line_edit = QLineEdit() self.topic_validator = NoEmptyStringValidator() self.topic_line_edit.setValidator(self.topic_validator) self.topic_validator.is_valid.connect( partial( validate_line_edit, self.topic_line_edit, tooltip_on_reject="Topic name can not be empty.", )) validate_line_edit(self.topic_line_edit, False) self.source_label = QLabel("Source: ") self.source_line_edit = QLineEdit() self.source_validator = NoEmptyStringValidator() self.source_line_edit.setValidator(self.source_validator) self.source_validator.is_valid.connect( partial( validate_line_edit, self.source_line_edit, tooltip_on_reject="Source name can not be empty.", )) validate_line_edit(self.source_line_edit, False) self.array_size_label = QLabel("Array size: ") self.array_size_spinbox = QSpinBox() self.array_size_spinbox.setMaximum(np.iinfo(np.int32).max) self.array_size_table = QTableWidget(1, 3) self.array_size_table.setHorizontalHeaderLabels(["x", "y", "z"]) self.array_size_table.setVerticalHeaderLabels([""]) table_height = self.array_size_table.sizeHintForRow( 0) + self.array_size_table.sizeHintForRow(1) self.array_size_table.setMaximumHeight(table_height) self.array_size_table.setFrameStyle(QFrame.NoFrame) self.array_size_table.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) self.array_size_table.resizeColumnsToContents() self.array_size_table.resizeRowsToContents() self.array_size_table.setItemDelegate( ValueDelegate(int, self.array_size_table)) self.type_label = QLabel("Type: ") self.type_combo = QComboBox() self.type_combo.addItems(F142_TYPES) self.type_combo.setCurrentText("double") self.value_units_edit = QLineEdit() self.value_units_label = QLabel("Value Units:") self.show_advanced_options_button = QPushButton( text="Show/hide advanced options") self.show_advanced_options_button.setCheckable(True) self.show_advanced_options_button.clicked.connect( self.advanced_options_button_clicked) self._set_up_f142_group_box() self._set_up_ev42_group_box() self.scalar_radio = QRadioButton(text=SCALAR) self.scalar_radio.clicked.connect(partial(self._show_array_size, False)) self.scalar_radio.setChecked(True) self.scalar_radio.clicked.emit() self.array_radio = QRadioButton(text=ARRAY) self.array_radio.clicked.connect(partial(self._show_array_size, True)) self.schema_combo.currentTextChanged.connect(self._schema_type_changed) if self._show_only_f142_stream: self.schema_combo.addItems([StreamModules.F142.value]) else: self.schema_combo.addItems([e.value for e in StreamModules]) self.ok_button = QPushButton("OK") self.ok_button.clicked.connect(self.parent().close) self.layout().addWidget(self.schema_label, 0, 0) self.layout().addWidget(self.schema_combo, 0, 1) self.layout().addWidget(self.topic_label, 1, 0) self.layout().addWidget(self.topic_line_edit, 1, 1) self.layout().addWidget(self.source_label, 2, 0) self.layout().addWidget(self.source_line_edit, 2, 1) self.layout().addWidget(self.value_units_label, 3, 0) self.layout().addWidget(self.value_units_edit, 3, 1) self.value_units_label.setVisible(False) self.value_units_edit.setVisible(False) self.layout().addWidget(self.type_label, 4, 0) self.layout().addWidget(self.type_combo, 4, 1) self.layout().addWidget(self.scalar_radio, 5, 0) self.layout().addWidget(self.array_radio, 5, 1) self.layout().addWidget(self.array_size_label, 6, 0) self.layout().addWidget(self.array_size_spinbox, 6, 1) self.layout().addWidget(self.array_size_table, 6, 1) self.layout().addWidget(self.hs00_unimplemented_label, 7, 0, 1, 2) # Spans both rows self.layout().addWidget(self.show_advanced_options_button, 8, 0, 1, 2) self.layout().addWidget(self.f142_advanced_group_box, 9, 0, 1, 2) self.layout().addWidget(self.ev42_advanced_group_box, 10, 0, 1, 2) self.layout().addWidget(self.ok_button, 11, 0, 1, 2) self._schema_type_changed(self.schema_combo.currentText()) self.parent().parent().field_name_edit.setVisible(False) def advanced_options_button_clicked(self): self._show_advanced_options( show=self.show_advanced_options_button.isChecked()) def _set_up_ev42_group_box(self): """ Sets up the UI for ev42 advanced options. """ self.ev42_advanced_group_box = QGroupBox( parent=self.show_advanced_options_button) self.ev42_advanced_group_box.setLayout(QFormLayout()) self.ev42_adc_pulse_debug_label = QLabel(ADC_PULSE_DEBUG) self.ev42_adc_pulse_debug_checkbox = QCheckBox() self.ev42_advanced_group_box.layout().addRow( self.ev42_adc_pulse_debug_label, self.ev42_adc_pulse_debug_checkbox) self.ev42_chunk_size_spinner = ( self.create_label_and_spinbox_for_advanced_option( CHUNK_SIZE, self.ev42_advanced_group_box)) self.ev42_cue_interval_spinner = ( self.create_label_and_spinbox_for_advanced_option( CUE_INTERVAL, self.ev42_advanced_group_box)) def create_label_and_spinbox_for_advanced_option(self, nexus_string: str, group_box: QGroupBox): """ Creates a SpinBox with a label and adds them to GroupBox then returns the SpinBox. :param nexus_string: The nexus string label for the SpinBox. :param group_box: The GroupBox that the label and SpinBox should be added to. :return: The newly created SpinBox. """ label = QLabel(nexus_string) spinner = QSpinBox() spinner.setRange(self.minimum_spinbox_value, self.maximum_spinbox_value) group_box.layout().addRow(label, spinner) return spinner def _set_up_f142_group_box(self): """ Sets up the UI for the f142 advanced options. """ self.f142_advanced_group_box = QGroupBox( parent=self.show_advanced_options_button) self.f142_advanced_group_box.setLayout(QFormLayout()) self.f142_chunk_size_spinner = ( self.create_label_and_spinbox_for_advanced_option( CHUNK_SIZE, self.f142_advanced_group_box)) self.f142_cue_interval_spinner = ( self.create_label_and_spinbox_for_advanced_option( CUE_INTERVAL, self.f142_advanced_group_box)) def _show_advanced_options(self, show): schema = self.schema_combo.currentText() if schema == WriterModules.F142.value: self.f142_advanced_group_box.setVisible(show) elif schema == WriterModules.EV42.value: self.ev42_advanced_group_box.setVisible(show) self.advanced_options_enabled = show def _show_array_size(self, show: bool): self.array_size_spinbox.setVisible(show) self.array_size_label.setVisible(show) def _schema_type_changed(self, schema: str): self.parent().setWindowTitle(f"Editing {schema} stream field") self.hs00_unimplemented_label.setVisible(False) self.f142_advanced_group_box.setVisible(False) self.ev42_advanced_group_box.setVisible(False) self.show_advanced_options_button.setVisible(False) self.show_advanced_options_button.setChecked(False) self.value_units_label.setVisible(False) self.value_units_edit.setVisible(False) self.array_size_table.setVisible(False) if schema == WriterModules.F142.value: self.value_units_label.setVisible(True) self.value_units_edit.setVisible(True) self._set_edits_visible(True, True) self.show_advanced_options_button.setVisible(True) self.f142_advanced_group_box.setVisible(False) elif schema == WriterModules.EV42.value: self._set_edits_visible(True, False) self.show_advanced_options_button.setVisible(True) self.ev42_advanced_group_box.setVisible(False) elif schema == WriterModules.ADAR.value: self._set_edits_visible(True, False) self._show_array_size_table(True) elif schema == WriterModules.HS00.value: self._set_edits_visible(True, False) self.hs00_unimplemented_label.setVisible(True) elif schema == WriterModules.NS10.value: self._set_edits_visible(True, False, "nicos/<device>/<parameter>") elif (schema == WriterModules.TDCTIME.value or schema == WriterModules.SENV.value): self._set_edits_visible(True, False) def _show_array_size_table(self, show: bool): self.array_size_label.setVisible(show) self.array_size_table.setVisible(show) def _set_edits_visible(self, source: bool, type: bool, source_hint=None): self.source_label.setVisible(source) self.source_line_edit.setVisible(source) self.type_label.setVisible(type) self.type_combo.setVisible(type) self.array_radio.setVisible(type) self.scalar_radio.setVisible(type) if source_hint: self.source_line_edit.setPlaceholderText(source_hint) else: self.source_line_edit.setPlaceholderText("") def get_stream_module(self, parent) -> StreamModule: """ Create the stream module :return: The created stream module """ source = self.source_line_edit.text() topic = self.topic_line_edit.text() stream: StreamModule = None type = self.type_combo.currentText() current_schema = self.schema_combo.currentText() if current_schema == WriterModules.F142.value: value_units = self.value_units_edit.text() array_size = self.array_size_spinbox.value() stream = F142Stream( parent_node=parent, source=source, topic=topic, type=type, value_units=value_units, array_size=array_size, ) if array_size: stream.array_size = array_size if self.advanced_options_enabled: self.record_advanced_f142_values(stream) elif current_schema == WriterModules.ADAR.value: array_size = [] for i in range(self.array_size_table.columnCount()): table_value = self.array_size_table.item(0, i) if table_value: array_size.append(int(table_value.text())) stream = ADARStream(parent_node=parent, source=source, topic=topic) stream.array_size = array_size elif current_schema == WriterModules.EV42.value: stream = EV42Stream(parent_node=parent, source=source, topic=topic) if self.advanced_options_enabled: self.record_advanced_ev42_values(stream) elif current_schema == WriterModules.NS10.value: stream = NS10Stream(parent_node=parent, source=source, topic=topic) elif current_schema == WriterModules.SENV.value: stream = SENVStream(parent_node=parent, source=source, topic=topic) elif current_schema == WriterModules.HS00.value: stream = HS00Stream( # type: ignore parent=parent, source=source, topic=topic, data_type=NotImplemented, edge_type=NotImplemented, error_type=NotImplemented, shape=[], ) elif current_schema == WriterModules.TDCTIME.value: stream = TDCTStream(parent_node=parent, source=source, topic=topic) return stream def record_advanced_f142_values(self, stream: F142Stream): """ Save the advanced f142 properties to the stream data object. :param stream: The stream data object to be modified. """ stream.chunk_size = self.f142_chunk_size_spinner.value() stream.cue_interval = self.f142_cue_interval_spinner.value() def record_advanced_ev42_values(self, stream: EV42Stream): """ Save the advanced ev42 properties to the stream data object. :param stream: The stream data object to be modified. """ stream.adc_pulse_debug = self.ev42_adc_pulse_debug_checkbox.isChecked() stream.chunk_size = self.ev42_chunk_size_spinner.value() stream.cue_interval = self.ev42_cue_interval_spinner.value() def fill_in_existing_ev42_fields(self, field: EV42Stream): """ Fill in specific existing ev42 fields into the new UI field. :param field: The stream group """ if check_if_advanced_options_should_be_enabled( [field.adc_pulse_debug, field.chunk_size, field.cue_interval]): self._show_advanced_options(True) self._fill_existing_advanced_ev42_fields(field) def _fill_existing_advanced_ev42_fields(self, field: EV42Stream): """ Fill the fields in the interface with the existing ev42 stream data. :param field: The ev42 stream data object. """ self.ev42_adc_pulse_debug_checkbox.setChecked(field.adc_pulse_debug) self.ev42_chunk_size_spinner.setValue(field.chunk_size) self.ev42_cue_interval_spinner.setValue(field.cue_interval) def fill_in_existing_f142_fields(self, field: F142Stream): """ Fill in specific existing f142 fields into the new UI field. :param field: The stream group """ self.type_combo.setCurrentText(field.type) if field.array_size is not None: self.array_radio.setChecked(True) self.scalar_radio.setChecked(False) self.array_size_spinbox.setValue(field.array_size) else: self.array_radio.setChecked(False) self.scalar_radio.setChecked(True) if field.value_units is not None: self.value_units_edit.setText(field.value_units) if check_if_advanced_options_should_be_enabled( [field.chunk_size, field.cue_interval]): self._show_advanced_options(True) self._fill_existing_advanced_f142_fields(field) def _fill_existing_advanced_f142_fields(self, field: F142Stream): """ Fill the advanced fields in the interface with the existing f142 stream data. :param field: The f412 stream data object. """ self.f142_chunk_size_spinner.setValue(field.chunk_size) self.f142_cue_interval_spinner.setValue(field.cue_interval) def update_existing_stream_info(self, field): """ Fill in stream fields and properties into the new UI field. :param field: The stream group """ if isinstance(field, Group): field = field.children[0] if hasattr(field, "parent_node") and isinstance( field.parent_node, Group): self.schema_validator.set_group(field.parent_node) else: self.schema_validator.set_group(None) schema = field.writer_module self.schema_combo.setCurrentText(schema) self.schema_validator.validate(schema, 0) self.topic_line_edit.setText(field.topic) self.topic_validator.validate(field.topic, 0) self.source_line_edit.setText(field.source) self.source_validator.validate(field.source, 0) if schema == WriterModules.F142.value: self.fill_in_existing_f142_fields(field) elif schema == WriterModules.EV42.value: self.fill_in_existing_ev42_fields(field) elif schema == WriterModules.ADAR.value: for i, val in enumerate(field.array_size): self.array_size_table.setItem(0, i, QTableWidgetItem(str(val)))
def _create_ammo_pickup_boxes(self, size_policy, item_database: ItemDatabase): """ Creates the GroupBox with SpinBoxes for selecting the pickup count of all the ammo :param item_database: :return: """ self._ammo_maximum_spinboxes = collections.defaultdict(list) self._ammo_pickup_widgets = {} resource_database = default_database.resource_database_for(self.game) broad_to_category = { ItemCategory.BEAM_RELATED: ItemCategory.BEAM, ItemCategory.MORPH_BALL_RELATED: ItemCategory.MORPH_BALL, ItemCategory.MISSILE_RELATED: ItemCategory.MISSILE, } for ammo in item_database.ammo.values(): category_box, category_layout, _ = self._boxes_for_category[ broad_to_category[ammo.broad_category]] pickup_box = QGroupBox(category_box) pickup_box.setSizePolicy(size_policy) pickup_box.setTitle(ammo.name + "s") layout = QGridLayout(pickup_box) layout.setObjectName(f"{ammo.name} Box Layout") current_row = 0 for ammo_item in ammo.items: item = resource_database.get_by_type_and_index( ResourceType.ITEM, ammo_item) target_count_label = QLabel(pickup_box) target_count_label.setText(f"{item.long_name} Target" if len( ammo.items) > 1 else "Target count") maximum_spinbox = QSpinBox(pickup_box) maximum_spinbox.setMaximum(ammo.maximum) maximum_spinbox.valueChanged.connect( partial(self._on_update_ammo_maximum_spinbox, ammo_item)) self._ammo_maximum_spinboxes[ammo_item].append(maximum_spinbox) layout.addWidget(target_count_label, current_row, 0) layout.addWidget(maximum_spinbox, current_row, 1) current_row += 1 count_label = QLabel(pickup_box) count_label.setText("Pickup Count") count_label.setToolTip( "How many instances of this expansion should be placed.") pickup_spinbox = QSpinBox(pickup_box) pickup_spinbox.setMaximum(AmmoState.maximum_pickup_count()) pickup_spinbox.valueChanged.connect( partial(self._on_update_ammo_pickup_spinbox, ammo)) layout.addWidget(count_label, current_row, 0) layout.addWidget(pickup_spinbox, current_row, 1) current_row += 1 if ammo.temporaries: require_major_item_check = QCheckBox(pickup_box) require_major_item_check.setText( "Requires the major item to work?") require_major_item_check.stateChanged.connect( partial(self._on_update_ammo_require_major_item, ammo)) layout.addWidget(require_major_item_check, current_row, 0, 1, 2) current_row += 1 else: require_major_item_check = None expected_count = QLabel(pickup_box) expected_count.setWordWrap(True) expected_count.setText(_EXPECTED_COUNT_TEXT_TEMPLATE) expected_count.setToolTip( "Some expansions may provide 1 extra, even with no variance, if the total count " "is not divisible by the pickup count.") layout.addWidget(expected_count, current_row, 0, 1, 2) current_row += 1 self._ammo_pickup_widgets[ammo] = AmmoPickupWidgets( pickup_spinbox, expected_count, pickup_box, require_major_item_check) category_layout.addWidget(pickup_box)
def __init__(self, parent, show_only_f142_stream: bool = False): super().__init__() self.setParent(parent) self.setLayout(QGridLayout()) self.setWindowModality(Qt.WindowModal) self.setModal(True) self._show_only_f142_stream = show_only_f142_stream self.minimum_spinbox_value = 0 self.maximum_spinbox_value = 100_000_000 self.advanced_options_enabled = False self.hs00_unimplemented_label = QLabel( "hs00 (Event histograms) has not yet been fully implemented.") self.schema_label = QLabel("Schema: ") self.schema_combo = DropDownList() self.schema_validator = SchemaSelectionValidator() self.schema_combo.setValidator(self.schema_validator) self.schema_validator.is_valid.connect( partial(validate_general_widget, self.schema_combo)) self.topic_label = QLabel("Topic: ") self.topic_line_edit = QLineEdit() self.topic_validator = NoEmptyStringValidator() self.topic_line_edit.setValidator(self.topic_validator) self.topic_validator.is_valid.connect( partial( validate_line_edit, self.topic_line_edit, tooltip_on_reject="Topic name can not be empty.", )) validate_line_edit(self.topic_line_edit, False) self.source_label = QLabel("Source: ") self.source_line_edit = QLineEdit() self.source_validator = NoEmptyStringValidator() self.source_line_edit.setValidator(self.source_validator) self.source_validator.is_valid.connect( partial( validate_line_edit, self.source_line_edit, tooltip_on_reject="Source name can not be empty.", )) validate_line_edit(self.source_line_edit, False) self.array_size_label = QLabel("Array size: ") self.array_size_spinbox = QSpinBox() self.array_size_spinbox.setMaximum(np.iinfo(np.int32).max) self.array_size_table = QTableWidget(1, 3) self.array_size_table.setHorizontalHeaderLabels(["x", "y", "z"]) self.array_size_table.setVerticalHeaderLabels([""]) table_height = self.array_size_table.sizeHintForRow( 0) + self.array_size_table.sizeHintForRow(1) self.array_size_table.setMaximumHeight(table_height) self.array_size_table.setFrameStyle(QFrame.NoFrame) self.array_size_table.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) self.array_size_table.resizeColumnsToContents() self.array_size_table.resizeRowsToContents() self.array_size_table.setItemDelegate( ValueDelegate(int, self.array_size_table)) self.type_label = QLabel("Type: ") self.type_combo = QComboBox() self.type_combo.addItems(F142_TYPES) self.type_combo.setCurrentText("double") self.value_units_edit = QLineEdit() self.value_units_label = QLabel("Value Units:") self.show_advanced_options_button = QPushButton( text="Show/hide advanced options") self.show_advanced_options_button.setCheckable(True) self.show_advanced_options_button.clicked.connect( self.advanced_options_button_clicked) self._set_up_f142_group_box() self._set_up_ev42_group_box() self.scalar_radio = QRadioButton(text=SCALAR) self.scalar_radio.clicked.connect(partial(self._show_array_size, False)) self.scalar_radio.setChecked(True) self.scalar_radio.clicked.emit() self.array_radio = QRadioButton(text=ARRAY) self.array_radio.clicked.connect(partial(self._show_array_size, True)) self.schema_combo.currentTextChanged.connect(self._schema_type_changed) if self._show_only_f142_stream: self.schema_combo.addItems([StreamModules.F142.value]) else: self.schema_combo.addItems([e.value for e in StreamModules]) self.ok_button = QPushButton("OK") self.ok_button.clicked.connect(self.parent().close) self.layout().addWidget(self.schema_label, 0, 0) self.layout().addWidget(self.schema_combo, 0, 1) self.layout().addWidget(self.topic_label, 1, 0) self.layout().addWidget(self.topic_line_edit, 1, 1) self.layout().addWidget(self.source_label, 2, 0) self.layout().addWidget(self.source_line_edit, 2, 1) self.layout().addWidget(self.value_units_label, 3, 0) self.layout().addWidget(self.value_units_edit, 3, 1) self.value_units_label.setVisible(False) self.value_units_edit.setVisible(False) self.layout().addWidget(self.type_label, 4, 0) self.layout().addWidget(self.type_combo, 4, 1) self.layout().addWidget(self.scalar_radio, 5, 0) self.layout().addWidget(self.array_radio, 5, 1) self.layout().addWidget(self.array_size_label, 6, 0) self.layout().addWidget(self.array_size_spinbox, 6, 1) self.layout().addWidget(self.array_size_table, 6, 1) self.layout().addWidget(self.hs00_unimplemented_label, 7, 0, 1, 2) # Spans both rows self.layout().addWidget(self.show_advanced_options_button, 8, 0, 1, 2) self.layout().addWidget(self.f142_advanced_group_box, 9, 0, 1, 2) self.layout().addWidget(self.ev42_advanced_group_box, 10, 0, 1, 2) self.layout().addWidget(self.ok_button, 11, 0, 1, 2) self._schema_type_changed(self.schema_combo.currentText()) self.parent().parent().field_name_edit.setVisible(False)
def init_ui(self): self.setFixedWidth(500) self.setWindowTitle(_('Event properties')) self.setWindowIcon(QIcon(config.ICON)) self.setSizeGripEnabled(False) self.setModal(True) self.layout = QFormLayout(self) self.label_main_title = QLabel(_('Main title')) self.item_main_title = QLineEdit() self.layout.addRow(self.label_main_title, self.item_main_title) self.label_sub_title = QLabel(_('Sub title')) self.item_sub_title = QTextEdit() self.item_sub_title.setMaximumHeight(100) self.layout.addRow(self.label_sub_title, self.item_sub_title) self.label_start_date = QLabel(_('Start date')) self.item_start_date = QDateTimeEdit() self.item_start_date.setDisplayFormat('yyyy.MM.dd HH:mm:ss') self.layout.addRow(self.label_start_date, self.item_start_date) self.label_end_date = QLabel(_('End date')) # self.item_end_date = QCalendarWidget() self.item_end_date = QDateTimeEdit() self.item_end_date.setDisplayFormat('yyyy.MM.dd HH:mm:ss') self.layout.addRow(self.label_end_date, self.item_end_date) self.label_location = QLabel(_('Location')) self.item_location = QLineEdit() self.layout.addRow(self.label_location, self.item_location) self.label_type = QLabel(_('Event type')) self.item_type = AdvComboBox() self.item_type.addItems(RaceType.get_titles()) self.layout.addRow(self.label_type, self.item_type) self.label_relay_legs = QLabel(_('Relay legs')) self.item_relay_legs = QSpinBox() self.item_relay_legs.setMinimum(1) self.item_relay_legs.setMaximum(20) self.item_relay_legs.setValue(3) self.layout.addRow(self.label_relay_legs, self.item_relay_legs) self.item_type.currentTextChanged.connect(self.change_type) self.label_refery = QLabel(_('Chief referee')) self.item_refery = QLineEdit() self.layout.addRow(self.label_refery, self.item_refery) self.label_secretary = QLabel(_('Secretary')) self.item_secretary = QLineEdit() self.layout.addRow(self.label_secretary, self.item_secretary) self.label_url = QLabel(_('URL')) self.item_url = QLineEdit() self.layout.addRow(self.label_url, self.item_url) def cancel_changes(): self.close() def apply_changes(): try: self.apply_changes_impl() except Exception as e: logging.error(str(e)) self.close() button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_ok = button_box.button(QDialogButtonBox.Ok) self.button_ok.setText(_('OK')) self.button_ok.clicked.connect(apply_changes) self.button_cancel = button_box.button(QDialogButtonBox.Cancel) self.button_cancel.setText(_('Cancel')) self.button_cancel.clicked.connect(cancel_changes) self.layout.addRow(button_box) self.set_values_from_model() self.show()
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) parameters = { 'Gain Scheduling': { 'GS': 'Gain scheduling', 'AS': 'Active Set', 'B12': 'Boundary 1/2', 'B23': 'Boundary 2/3' }, 'Set 1': { 'P1': 'Proportional 1', 'I1': 'Integral 1', 'D1': 'Derivative 1' }, 'Set 2': { 'P2': 'Proportional 2', 'I2': 'Integral 2', 'D2': 'Derivative 2' }, 'Set 3': { 'P3': 'Proportional 3', 'I3': 'Integral 3', 'D3': 'Derivative 3' } } self.units = { 'I1': ' s', 'I2': ' s', 'I3': ' s', 'D1': ' s', 'D2': ' s', 'D3': ' s' } self.entries = { key: QComboBox() if key == 'GS' else QSpinBox(minimum=1, maximum=3) if key == 'AS' else QDoubleSpinBox( decimals=0, singleStep=10, minimum=0, maximum=100000) for subset in parameters for key in parameters[subset] } self.entries['GS'].addItems( ['None', 'Set', 'Process Variable', 'Setpoint', 'Output']) for entry, suffix in self.units.items(): self.entries[entry].setSuffix(suffix) vbox = QVBoxLayout() vbox.setSpacing(0) vbox.setContentsMargins(10, 10, 10, 10) for subset in parameters: label = QLabel(text=subset, objectName='Header') vbox.addWidget(label) vbox.addSpacing(10) form = QFormLayout() form.setSpacing(5) form.setHorizontalSpacing(20) form.setContentsMargins(0, 0, 0, 0) for key in parameters[subset]: form.addRow(parameters[subset][key], self.entries[key]) vbox.addLayout(form) vbox.addSpacing(20) refresh_button = QPushButton(text='Refresh', objectName='Refresh') refresh_button.clicked.connect( lambda: pubsub.pub.sendMessage('gui.request.pid_parameters')) vbox.addWidget(refresh_button) vbox.addStretch() self.setLayout(vbox) for key, entry in self.entries.items(): if key == 'GS': entry.currentTextChanged.connect( functools.partial(self.set_pid_parameter, control=key)) else: entry.setKeyboardTracking(False) entry.valueChanged.connect( functools.partial(self.set_pid_parameter, control=key)) pubsub.pub.subscribe(self.update_pid_parameters, 'engine.answer.pid_parameters')
def setUp(self): super(SpinBoxPySignal, self).setUp() self.obj = Dummy() self.spin = QSpinBox() self.spin.setValue(0)
class AcquistoForm(QDialog): ''' Widget per l'inserimento di un acquisto immediato. ''' def __init__(self, conn): ''' Parameters: conn : connection Connection to the database. ''' super().__init__() self.setWindowTitle('Aggiungi Acquisto') self.setWindowFlag(QtCore.Qt.WindowContextHelpButtonHint, False) self.conn = conn self.cursor = conn.cursor() self.books = dict() self.books_qt = dict() self.gen_layout = QVBoxLayout() self.form_layout = QFormLayout() self.form_layout.setRowWrapPolicy(QFormLayout.WrapLongRows) # Widgets self.client_field = QLineEdit() self.form_layout.addRow('Numero Cliente (facoltativo): ', self.client_field) self.dip_field = QLineEdit() self.form_layout.addRow('Dipendente (CF): ', self.dip_field) self.date_picker = QDateEdit(QDate.currentDate()) self.date_picker.setDisplayFormat("MM/dd/yyyy") self.date_picker.setCalendarPopup(True) self.form_layout.addRow('Data (mm/gg/aaaa): ', self.date_picker) self.importo_field = QDoubleSpinBox() self.importo_field.setMaximum(999999999.99) self.form_layout.addRow('Importo: ', self.importo_field) self.ins_layout = QHBoxLayout() self.libro_field = QLineEdit() self.quantita_field = QSpinBox() self.quantita_field.setMinimum(1) self.libro_button = QPushButton('Aggiungi') self.libro_button.clicked.connect(self.aggiungi_libro) self.ins_layout.addWidget(QLabel('Libro (ISBN): ')) self.ins_layout.addWidget(self.libro_field) self.ins_layout.addWidget(QLabel('Quantità: ')) self.ins_layout.addWidget(self.quantita_field) self.ins_layout.addWidget(self.libro_button) self.labels = ['ISBN', 'Quantità', ''] self.table = QTableWidget(0, 3) self.table.setHorizontalHeaderLabels(self.labels) self.table.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 2, QHeaderView.ResizeToContents) self.confirm_button = QPushButton('Conferma') self.confirm_button.clicked.connect(self.post_acquisto) self.gen_layout.addLayout(self.form_layout) self.gen_layout.addLayout(self.ins_layout) self.gen_layout.addWidget(self.table) self.gen_layout.addWidget(self.confirm_button) self.setLayout(self.gen_layout) def aggiungi_libro(self): self.books[self.libro_field.text()] = self.quantita_field.value() self.update_table() def remove_libro(self, book): self.books.pop(book, None) self.update_table() def update_table(self): self.table.clearContents() while self.table.rowCount() > 0: self.table.removeRow(0) for book in self.books.keys(): row = self.table.rowCount() button = QPushButton('Rimuovi') button.clicked.connect(lambda: self.remove_libro(book)) self.table.insertRow(row) self.table.setItem(row, 0, QTableWidgetItem(book)) self.table.setItem(row, 1, QTableWidgetItem(str(self.books[book]))) self.table.setCellWidget(row, 2, button) def verif_qty(self): ''' Shows error messages based on the validity of inserted books, and returns False, or returns True if all the books are ok to sell right now. ''' if len(self.books.items()) == 0: self._show_error('Non ci sono libri nell\'acquisto') return 1 for book, qty in self.books.items(): self.cursor.execute(FIND_QUANTITA, (book, )) result = self.cursor.fetchall() if not result: self._show_error('\'{}\' non è un libro valido.'.format(book)) return 2 stored = result[0][0] if stored < qty: return self.__show_are_you_sure( 'L\'acquisto richiede {} libri {}, ma ne sono presenti solo {}.\nNon sarà possibile sottrarre i libri acquistati.\nVuoi proseguire ugualmente?' .format(qty, book, stored)) return 0 def verif_client_dip(self): ''' Returns false and displays and error message if cliente and dipendente are not valid tuples in the database, returns true if they are ok ''' cliente = self.client_field.text() if cliente: if not cliente.isdigit(): self._show_error('Il codice del Cliente deve essere numerico.') return 1 self.cursor.execute(FIND_CLIENTE, (cliente, )) result = self.cursor.fetchall() if not result or not result[0][0]: self._show_error('Cliente {} non esiste.'.format(cliente)) return 2 dipendente = self.dip_field.text() if not dipendente: self._show_error('Il Dipendente non può essere vuoto.') return 3 self.cursor.execute(FIND_DIPENDENTE, (dipendente, )) result = self.cursor.fetchall() if not result or not result[0][0]: self._show_error('Dipendente {} non esiste.'.format(dipendente)) return 4 return 0 def post_acquisto(self): if self.verif_client_dip(): return should_show = self.verif_qty() if should_show > 0: return cliente = self.client_field.text().strip() if self.client_field.text( ).strip() else None importo = self.importo_field.value() self.cursor.execute( INSERT_ACQUISTO, (self.date_picker.date().toString('MM/dd/yyyy'), self.importo_field.value(), self.dip_field.text())) new_id = self.cursor.fetchall()[0][0] self.cursor.execute(INSERT_IMMEDIATO, (new_id, cliente)) for book in self.books.keys(): self.cursor.execute(INSERT_COMPRENDE, (new_id, book, self.books[book])) self.conn.commit() if should_show == 0: self._show_confirm() self.accept() def __show_are_you_sure(self, msg=''): dialog = _AreYouSureDialog(msg) dialog.setWindowTitle('ATTENZIONE') result = dialog.exec_() return -1 if result == QDialog.Accepted else 3 def _show_confirm(self): dialog = _ScalaAcquistiDialog(self.books, self.conn) dialog.setWindowTitle('Rimozione libri') dialog.exec_() def _show_error(self, msg=''): dialog = QMessageBox() dialog.setWindowTitle('ERRORE') dialog.setText(msg) dialog.exec_()
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): QToolTip.setFont(QFont('SansSerif', 12)) Title = QLabel('Выберите параметры обучения нейросети') Title.setToolTip('Для корректной работы функций обучения и оптимизации \n' 'в каталоге с программой должны находится подкаталоги \n' 'train, val, test. В каждом из этих каталогов должно \n' 'быть столько подкаталогов с изображениями, сколько \n' 'необходимо распознавать классов') Title1 = QLabel('Выберите параметры исследования изображения') Title1.setToolTip('Для корректной работы функции классификации и локализации \n' 'изображения для исследования и модель нейросети должны \n' 'находиться в одном каталоге с программой, формат изображения \n' '.jpg, формат модели нейросети .h5, указывать формат в полях не нужно') TitleEp = QLabel('Эпохи:') TitleEp.setToolTip('Эпоха — один «проход» данных через нейросеть. \n' 'Изменение этого параметра позволяет избежать \n' 'недообученности или переобученности нейросети') TitleBa = QLabel('Размер мини-выборки:') TitleBa.setToolTip('Количество изображений загружаемых в нейросеть ' 'за раз') TitleTr = QLabel('Количество изображений для обучения:') TitleTr.setToolTip('Количество изображений во всех подкаталогах ' 'каталога train') TitleVa = QLabel('Количество изображений для проверки:') TitleVa.setToolTip('Количество изображений во всех подкаталогах ' 'каталога val') TitleTe = QLabel('Количество изображений для тестирования:') TitleTe.setToolTip('Количество изображений во всех подкаталогах ' 'каталога test') TitleSc = QLabel('Масштабирование пирамиды изображений:') TitleSc.setToolTip('Коэффициент масштабирования изображения') TitleSs = QLabel('Шаг скользящего окна:') TitleSs.setToolTip('Расстояние в пикселях, на которое смещается \n' 'окно классификатора по изображению за одну итерацию') TitleNi = QLabel('Имя изображения для исследования:') TitleNi.setToolTip('Наименование изображения без расширения. \n' 'Изображение должно иметь формат jpg и \n' 'находится в одном каталоге с программой, иначе \n' 'необходимо указывать полный путь до изображения') TitleNm = QLabel('Имя модели нейросети:') TitleNm.setToolTip('Наименование модели нейросети без расширения. \n' 'Модель должна иметь формат h5 и находится \n' 'в одном каталоге с программой, иначе необходимо \n' 'указывать полный путь до модели нейросети') TitleCl = QLabel('Количество классов:') self.InputEpochs = QSpinBox(self) self.InputEpochs.setRange(5,50) self.InputEpochs.setValue(10) self.InputBatch = QSpinBox(self) self.InputBatch.setRange(5,100) self.InputBatch.setValue(15) self.InputTrain = QSpinBox(self) self.InputTrain.setRange(100,100000) self.InputTrain.setValue(1050) self.InputValidation = QSpinBox(self) self.InputValidation.setRange(100,100000) self.InputValidation.setValue(225) self.InputTest = QSpinBox(self) self.InputTest.setRange(100,100000) self.InputTest.setValue(225) self.InputScale = QDoubleSpinBox(self) self.InputScale.setRange(1.1,5) self.InputScale.setValue(1.5) self.InputStep = QSpinBox(self) self.InputStep.setRange(1,150) self.InputStep.setValue(30) self.InputClass = QSpinBox(self) self.InputClass.setRange(3,20) self.InputClass.setValue(3) self.ImageName = QLineEdit("ImageName", self) self.ImageName.setMaxLength(20) self.ModelName = QLineEdit("TestModel", self) self.ModelName.setMaxLength(20) btn = QPushButton('Обучить нейросеть', self) btn.setToolTip('В результате обучения модель нейросети ' 'будет сохранена в каталоге с программой') btn.resize(btn.sizeHint()) btn.clicked.connect(self.buttonClicked) btn1 = QPushButton('Оптимизировать нейросеть', self) btn1.setToolTip('В результате оптимизации 3 лучшие модели ' 'будут сохранены в каталоге с программой') btn1.resize(btn1.sizeHint()) btn1.clicked.connect(self.buttonClicked1) btn2 = QPushButton('Поиск и распознавание', self) btn2.resize(btn2.sizeHint()) btn2.clicked.connect(self.buttonClicked2) grid = QGridLayout(self) grid.setSpacing(10) grid.addWidget(Title, 1, 0, 1, 4) grid.addWidget(TitleEp, 2, 0) grid.addWidget(TitleBa, 3, 0) grid.addWidget(TitleCl, 4, 0) grid.addWidget(self.InputEpochs, 2, 1) grid.addWidget(self.InputBatch, 3, 1) grid.addWidget(self.InputClass, 4, 1) grid.addWidget(TitleTr, 2, 2) grid.addWidget(TitleVa, 3, 2) grid.addWidget(TitleTe, 4, 2) grid.addWidget(self.InputTrain, 2, 3) grid.addWidget(self.InputValidation, 3, 3) grid.addWidget(self.InputTest, 4, 3) grid.addWidget(btn, 5, 0, 1, 2) grid.addWidget(btn1, 5, 2, 1, 2) grid.addWidget(Title1, 6, 0, 1, 4) grid.addWidget(TitleSc, 7, 0) grid.addWidget(self.InputScale, 7, 1) grid.addWidget(TitleSs, 7, 2) grid.addWidget(self.InputStep, 7, 3) grid.addWidget(TitleNi, 8, 0) grid.addWidget(self.ImageName, 8, 1) grid.addWidget(TitleNm, 8, 2) grid.addWidget(self.ModelName, 8, 3) grid.addWidget(btn2, 9, 1, 1, 2) self.setLayout(grid) self.setWindowTitle('Система поиска и распознавания сорных растений') self.setWindowIcon(QIcon('icon.png')) self.show() def buttonClicked(self): train_dir = 'train' # Каталог с данными для обучения val_dir = 'val' # Каталог с данными для проверки test_dir = 'test' # Каталог с данными для тестирования img_width, img_height = 150, 150 # Размеры изображения input_shape = (img_width, img_height, 3) # Размерность тензора на основе изображения для входных данных в нейронную сеть epochs = self.InputEpochs.value() Nclasses = self.InputClass.value() batch_size = self.InputBatch.value() nb_train_samples = self.InputTrain.value() nb_validation_samples = self.InputValidation.value() nb_test_samples = self.InputTest.value() model = Sequential() model.add(Conv2D(32, (3, 3), input_shape=input_shape)) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Conv2D(64, (3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Conv2D(64, (3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Conv2D(128, (3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Flatten()) model.add(Dense(768)) model.add(Activation('selu')) model.add(Dropout(0.5)) model.add(Dense(Nclasses)) model.add(Activation('softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) datagen = ImageDataGenerator(rescale=1. / 255) train_generator = datagen.flow_from_directory( train_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='categorical') val_generator = datagen.flow_from_directory( val_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='categorical') test_generator = datagen.flow_from_directory( test_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='categorical') model.fit_generator( train_generator, steps_per_epoch=nb_train_samples // batch_size, epochs=epochs, validation_data=val_generator, validation_steps=nb_validation_samples // batch_size) scores = model.evaluate_generator(test_generator, nb_test_samples // batch_size) print("Аккуратность на тестовых данных: %.2f%%" % (scores[1]*100)) model.save('TestModel.h5') def buttonClicked1(self): train_dir = 'train' val_dir = 'val' test_dir = 'test' img_width, img_height = 150, 150 input_shape = (img_width, img_height, 3) epochs = self.InputEpochs.value() Nclasses = self.InputClass.value() batch_size = self.InputBatch.value() nb_train_samples = self.InputTrain.value() nb_validation_samples = self.InputValidation.value() nb_test_samples = self.InputTest.value() l=0 def build_model(hp): model = Sequential() num_hidden_layers = hp.Int('num_hidden_layers', 1, 3, default=1) num_conv_layers = hp.Int('num_conv_layers', 2, 6, default=2) model.add(Conv2D(32, (3, 3), input_shape=input_shape)) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) for i in range(num_conv_layers): filters = hp.Int('filters'+str(i), 32, 64, step=16) model.add(Conv2D(filters,(3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Conv2D(128, (3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Flatten()) for j in range(num_hidden_layers): model.add(Dense(units=hp.Int('units_hiddenNeurons_'+str(j), min_value=128, max_value=1024, step=64), activation=hp.Choice('activation'+str(j),values=['relu','tanh','elu','selu']))) model.add(Dropout(0.5)) model.add(Dense(Nclasses)) model.add(Activation('softmax')) model.compile( loss='categorical_crossentropy', optimizer=hp.Choice('optimizer', values=['adam','rmsprop','SGD'],default='adam'), metrics=['accuracy']) return model tuner = RandomSearch( build_model, objective='val_accuracy', max_trials=15, directory='test_directory') tuner.search_space_summary() datagen = ImageDataGenerator(rescale=1. / 255) train_generator = datagen.flow_from_directory( train_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='categorical') val_generator = datagen.flow_from_directory( val_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='categorical') test_generator = datagen.flow_from_directory( test_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='categorical') tuner.search( train_generator, steps_per_epoch=nb_train_samples // batch_size, epochs=epochs, validation_data=val_generator, validation_steps=nb_validation_samples // batch_size) tuner.results_summary() models = tuner.get_best_models(num_models=3) for model in models: model.summary() l=l+1 scores = model.evaluate_generator(test_generator, nb_test_samples // batch_size) model.save('bestmodel_'+str(l)+'.h5') print("Аккуратность на тестовых данных: %.2f%%" % (scores[1]*100)) def buttonClicked2(self): def pyramid(image, scale, minSize=(150, 150)): yield image while True: w = int(image.shape[1] / scale) image = imutils.resize(image, width=w) if image.shape[0] < minSize[1] or image.shape[1] < minSize[0]: break yield image def sliding_window(image, stepSize, windowSize): # сдвиг окна по изображению for y in range(0, image.shape[0], stepSize): for x in range(0, image.shape[1], stepSize): yield (x, y, image[y:y + windowSize[1], x:x + windowSize[0]]) # расстояние между точками def dist(x,y): return np.sqrt(np.sum(np.square(np.array(center(x))-np.array(center(y))))) # вычисляем точку-центр рамки def center(frame): (x, y, x2, y2, _ , _ , _ ) = frame return [ x+((x2-x)//2), y2+((y-y2)//2) ] # очистка списка найденных рамок def clean(X, i=0, max_dist=150): # выбираем основной элемент X[i] j = i+1 # и, следующий за ним, элемент X[j] if i <= len(X) and i > 0: max_dist *= X[i][6] while(j<len(X)): # для всех элементов j (!= i) d = dist( X[i], X[j] ) # считаем расстояние между точками i,j if ( d < max_dist ): # i,j в одном кластере if ( X[i][4] >= X[j][4] ): # сравниваем рейтинг del X[j] # удаляем элемент j else: del X[i] # удаляем основной элемент i X = clean(X, i=i, max_dist=max_dist) # рекурсивно повторяем уже без элемента i break else: j+=1 if ( i<(len(X)-1) ): # если есть ещё точки в других, относительно X[i], кластерах X = clean(X, i=i+1, max_dist=max_dist) # то выполняем проверку return X if __name__ == "__main__": k = 1 path = os.getcwd() classes = os.listdir(path + "/train") boxes = [] scale = self.InputScale.value() stepSize = self.InputStep.value() imagename = self.ImageName.text() modelname = self.ModelName.text() font = cv2.FONT_HERSHEY_SIMPLEX model = load_model(modelname+'.h5') img = cv2.imread(imagename+'.jpg') width1, height1, channels1 = img.shape if (width1 > 1000) or (height1 > 1000): img = cv2.resize(img, (0, 0), fx = 0.5, fy = 0.5) (winW, winH) = (150, 150) clone = img.copy() for resized in pyramid(img, scale): for (x, y, window) in sliding_window(resized, stepSize, windowSize=(winW, winH)): # если окно не соответствует нашему желаемому размеру окна, игнорируем его if window.shape[0] != winH or window.shape[1] != winW: continue img_tensor = image.img_to_array(window) # (height, width, channels) img_tensor = np.expand_dims(img_tensor, axis=0) # (1, height, width, channels), добавим измерение, потому что модель ожидает эту форму: (batch_size, height, width, channels) img_tensor /= 255. # imshow ожидает значений в диапазоне [0, 1] pred = model.predict(img_tensor) nclass = np.argmax(pred) pred = np.amax(pred) if pred >= 0.9: boxes.append([x*k, y*k, (x + winW)*k, (y + winH)*k, pred, classes[nclass], k]) k *= scale boxes = clean(boxes) for (x, y, x2, y2, score, classname, scales) in boxes: cv2.rectangle(clone, (int(x),int(y)),(int(x2), int(y2)),(0, 255, 0), 2) cv2.putText(clone, classname + " %.3f" % score, (int(x),int(y2)), font, 0.7, (0, 255, 0), thickness=2) cv2.imshow("Result", clone) cv2.waitKey(1) def closeEvent(self, event): reply = QMessageBox.question(self, 'Выход', "Вы уверены что хотите закрыть программу?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore()
def __init__(self, conn): ''' Parameters: conn : connection Connection to the database. ''' super().__init__() self.setWindowTitle('Aggiungi Acquisto') self.setWindowFlag(QtCore.Qt.WindowContextHelpButtonHint, False) self.conn = conn self.cursor = conn.cursor() self.books = dict() self.books_qt = dict() self.gen_layout = QVBoxLayout() self.form_layout = QFormLayout() self.form_layout.setRowWrapPolicy(QFormLayout.WrapLongRows) # Widgets self.client_field = QLineEdit() self.form_layout.addRow('Numero Cliente (facoltativo): ', self.client_field) self.dip_field = QLineEdit() self.form_layout.addRow('Dipendente (CF): ', self.dip_field) self.date_picker = QDateEdit(QDate.currentDate()) self.date_picker.setDisplayFormat("MM/dd/yyyy") self.date_picker.setCalendarPopup(True) self.form_layout.addRow('Data (mm/gg/aaaa): ', self.date_picker) self.importo_field = QDoubleSpinBox() self.importo_field.setMaximum(999999999.99) self.form_layout.addRow('Importo: ', self.importo_field) self.ins_layout = QHBoxLayout() self.libro_field = QLineEdit() self.quantita_field = QSpinBox() self.quantita_field.setMinimum(1) self.libro_button = QPushButton('Aggiungi') self.libro_button.clicked.connect(self.aggiungi_libro) self.ins_layout.addWidget(QLabel('Libro (ISBN): ')) self.ins_layout.addWidget(self.libro_field) self.ins_layout.addWidget(QLabel('Quantità: ')) self.ins_layout.addWidget(self.quantita_field) self.ins_layout.addWidget(self.libro_button) self.labels = ['ISBN', 'Quantità', ''] self.table = QTableWidget(0, 3) self.table.setHorizontalHeaderLabels(self.labels) self.table.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 2, QHeaderView.ResizeToContents) self.confirm_button = QPushButton('Conferma') self.confirm_button.clicked.connect(self.post_acquisto) self.gen_layout.addLayout(self.form_layout) self.gen_layout.addLayout(self.ins_layout) self.gen_layout.addWidget(self.table) self.gen_layout.addWidget(self.confirm_button) self.setLayout(self.gen_layout)
class TrainingPanel(Panel): def __init__(self, datasets, testing_panel, threads): super().__init__() if isinstance(testing_panel, TestingPanel): self.testing_panel = testing_panel else: raise TypeError('"testing_panel" must be the instance of ' '"TestingPanel"') self.datasets = datasets self.threads = threads self.__set_execution_ui() self.__set_options_ui() self.__set_outputs_ui() self.__set_graphic_ui() def __set_execution_ui(self): group_box = QGroupBox('Training Execution') inner_layout = QHBoxLayout() group_box.setLayout(inner_layout) self.data_selector = QComboBox() self.data_selector.addItems(list(self.datasets.keys())) self.data_selector.setStatusTip('Select the training dataset.') self.start_btn = QPushButton('Train') self.start_btn.setStatusTip('Start training.') self.start_btn.clicked.connect(self.__run) self.stop_btn = QPushButton('Stop') self.stop_btn.setStatusTip('Force the training stop running.') self.stop_btn.setDisabled(True) self.multicore_cb = QCheckBox('Multicore') self.multicore_cb.setStatusTip('Use multiprocessing in calculating ' 'fitting for populations.') self.multicore_cb.setChecked(True) inner_layout.addWidget(self.data_selector, 1) inner_layout.addWidget(self.start_btn) inner_layout.addWidget(self.stop_btn) inner_layout.addWidget(self.multicore_cb) self._layout.addWidget(group_box) def __set_options_ui(self): group_box = QGroupBox('Training Options') inner_layout = QFormLayout() group_box.setLayout(inner_layout) self.iter_times = QSpinBox() self.iter_times.setRange(1, 1000000) self.iter_times.setValue(200) self.iter_times.setStatusTip('The total iterating times for training.') self.population_size = QSpinBox() self.population_size.setRange(1, 100000) self.population_size.setValue(100) self.population_size.setStatusTip('The population size for the PSO.') self.inertia_weight = QDoubleSpinBox() self.inertia_weight.setRange(0, 50) self.inertia_weight.setValue(1) self.inertia_weight.setSingleStep(0.1) self.inertia_weight.setStatusTip('The inertia weight of the velocity ' ' for each individual.') self.cognitive_const_rand_upper = QDoubleSpinBox() self.cognitive_const_rand_upper.setRange(0, 50) self.cognitive_const_rand_upper.setValue(2) self.cognitive_const_rand_upper.setSingleStep(0.1) self.cognitive_const_rand_upper.setStatusTip( 'The random upper bound for cognitive accelerate constant.') self.social_const_rand_upper = QDoubleSpinBox() self.social_const_rand_upper.setRange(0, 50) self.social_const_rand_upper.setValue(3) self.social_const_rand_upper.setSingleStep(0.1) self.social_const_rand_upper.setStatusTip( 'The random upper bound for social accelerate constant.') self.v_max = QDoubleSpinBox() self.v_max.setRange(0.5, 100) self.v_max.setValue(5) self.v_max.setSingleStep(1) self.v_max.setStatusTip('The maximum of velocity for each individual.') self.nneuron = QSpinBox() self.nneuron.setRange(1, 100) self.nneuron.setValue(6) self.nneuron.setStatusTip('The number of RBFN neuron.') self.sd_max = QDoubleSpinBox() self.sd_max.setRange(0.01, 20) self.sd_max.setValue(10) self.sd_max.setSingleStep(0.1) self.sd_max.setStatusTip('The random range maximum of standard ' 'deviation of each neuron in RBFN (only for ' 'initialization).') inner_layout.addRow('Iterating Times:', self.iter_times) inner_layout.addRow('Population Size:', self.population_size) inner_layout.addRow('Inertia Weight:', self.inertia_weight) inner_layout.addRow('Cognitive Const Upper:', self.cognitive_const_rand_upper) inner_layout.addRow('Social Const Upper:', self.social_const_rand_upper) inner_layout.addRow('Maximum of Velocity:', self.v_max) inner_layout.addRow('Number of Neuron:', self.nneuron) inner_layout.addRow('Maximum of SD:', self.sd_max) self._layout.addWidget(group_box) def __set_outputs_ui(self): group_box = QGroupBox('Training Details') inner_layout = QFormLayout() group_box.setLayout(inner_layout) self.current_iter_time = QLabel('--') self.current_error = QLabel('--') self.avg_error = QLabel('--') self.global_best_error = QLabel('--') self.total_best_error = QLabel('--') self.progressbar = QProgressBar() self.current_iter_time.setAlignment(Qt.AlignCenter) self.current_error.setAlignment(Qt.AlignCenter) self.avg_error.setAlignment(Qt.AlignCenter) self.global_best_error.setAlignment(Qt.AlignCenter) self.total_best_error.setAlignment(Qt.AlignCenter) self.current_iter_time.setStatusTip('The current iterating time of ' 'the PSO.') self.current_error.setStatusTip('The current error from the fitting ' 'function. ("( )": normalized error)') self.avg_error.setStatusTip('The average error from the fitting ' 'function in current iteration. ("( )": ' 'normalized error)') self.global_best_error.setStatusTip( 'The error of global best individual from the fitting function in ' 'current iteration. ("( )": normalized error)') self.total_best_error.setStatusTip( 'The error of total best individual from the fitting function in ' 'training. ("( )": normalized error)') inner_layout.addRow('Current Iterating Time:', self.current_iter_time) inner_layout.addRow('Current Error:', self.current_error) inner_layout.addRow('Average Error:', self.avg_error) inner_layout.addRow('Global Best Error:', self.global_best_error) inner_layout.addRow('Total Best Error:', self.total_best_error) inner_layout.addRow(self.progressbar) self._layout.addWidget(group_box) def __set_graphic_ui(self): group_box = QGroupBox('Error Line Charts:') inner_layout = QVBoxLayout() group_box.setLayout(inner_layout) self.err_chart = ErrorLineChart(1) self.err_chart.setStatusTip('The history of error from the fitting ' 'of the PSO for each data.') self.__err_x = 1 self.iter_err_chart = ErrorLineChart( 3, ('Avg', 'Global Best', 'Total Best')) self.iter_err_chart.setStatusTip('The history of average and least ' 'error from the fitting of the PSO ' 'for each iteration.') self.iter_err_chart.setMinimumHeight(150) inner_layout.addWidget(QLabel('Current Error')) inner_layout.addWidget(self.err_chart) inner_layout.addWidget(QLabel('Average Error')) inner_layout.addWidget(self.iter_err_chart) self._layout.addWidget(group_box) @Slot() def __init_widgets(self): self.start_btn.setDisabled(True) self.stop_btn.setEnabled(True) self.multicore_cb.setDisabled(True) self.data_selector.setDisabled(True) self.iter_times.setDisabled(True) self.population_size.setDisabled(True) self.inertia_weight.setDisabled(True) self.cognitive_const_rand_upper.setDisabled(True) self.social_const_rand_upper.setDisabled(True) self.v_max.setDisabled(True) self.nneuron.setDisabled(True) self.sd_max.setDisabled(True) self.err_chart.clear() self.iter_err_chart.clear() self.__err_x = 1 @Slot() def __reset_widgets(self): self.start_btn.setEnabled(True) self.stop_btn.setDisabled(True) self.multicore_cb.setEnabled(True) self.data_selector.setEnabled(True) self.iter_times.setEnabled(True) self.population_size.setEnabled(True) self.inertia_weight.setEnabled(True) self.cognitive_const_rand_upper.setEnabled(True) self.social_const_rand_upper.setEnabled(True) self.v_max.setEnabled(True) self.nneuron.setEnabled(True) self.sd_max.setEnabled(True) self.progressbar.setMinimum(0) self.progressbar.setMaximum(100) @Slot() def __indicate_busy(self): self.progressbar.setMinimum(0) self.progressbar.setMaximum(0) @Slot(int) def __show_current_iter_time(self, value): self.current_iter_time.setText(str(value + 1)) self.progressbar.setValue(value + 1) @Slot(float) def __show_current_error(self, value): self.current_error.setText('{:.5f} ({:.5f})'.format(value, value / 40)) self.err_chart.append_point(self.__err_x, value) self.__err_x += 1 @Slot(float, float, float) def __show_iter_error(self, avg, glob, total): self.avg_error.setText('{:.5f} ({:.5f})'.format(avg, avg / 40)) self.global_best_error.setText( '{:.5f} ({:.5f})'.format(glob, glob / 40)) self.total_best_error.setText( '{:.5f} ({:.5f})'.format(total, total / 40)) self.iter_err_chart.append_point( int(self.current_iter_time.text()), total, 2) self.iter_err_chart.append_point( int(self.current_iter_time.text()), glob, 1) self.iter_err_chart.append_point( int(self.current_iter_time.text()), avg, 0) def __run(self): self.progressbar.setMaximum(self.iter_times.value()) self.__current_dataset = self.datasets[ self.data_selector.currentText()] self.__pso = PSO(self.iter_times.value(), self.population_size.value(), self.inertia_weight.value(), self.cognitive_const_rand_upper.value(), self.social_const_rand_upper.value(), self.v_max.value(), self.nneuron.value(), self.__current_dataset, self.sd_max.value(), is_multicore=self.multicore_cb.isChecked()) self.threads.append(self.__pso) self.stop_btn.clicked.connect(self.__pso.stop) self.__pso.started.connect(self.__init_widgets) self.__pso.finished.connect(self.__reset_widgets) self.__pso.sig_current_iter_time.connect(self.__show_current_iter_time) self.__pso.sig_current_error.connect(self.__show_current_error) self.__pso.sig_iter_error.connect(self.__show_iter_error) self.__pso.sig_indicate_busy.connect(self.__indicate_busy) self.__pso.sig_console.connect(self.testing_panel.print_console) self.__pso.sig_rbfn.connect(self.testing_panel.load_rbfn) self.__pso.start()
def setup(self): "constructs the gui" Fixed = QSizePolicy() MinimumExpanding = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.minKeyLen = 8 self.maxKeyLen = 4096 self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Horizontal) self.splitter.splitterMoved.connect(self.splitterChanged) # left column self.leftColumn = QWidget() self.vl01 = QVBoxLayout() # left column - first item (0; horizonal layout 0) self.hl00 = QHBoxLayout() self.hl00.setSpacing(5) self.openButton = QPushButton('&Open') self.openButton.setToolTip('Open folder') self.openButton.setMinimumSize(60, 20) self.openButton.setMaximumSize(60, 20) self.openButton.setSizePolicy(Fixed) self.openButton.clicked.connect(self.getFolder) #ico = self.style().standardIcon(QStyle.SP_DirIcon) #self.openButton.setIcon(ico) self.folderLabel = QLabel() self.folderLabel.setMinimumSize(135, 20) self.folderLabel.setMaximumSize(16777215, 20) self.folderLabel.setSizePolicy(MinimumExpanding) self.hl00.insertWidget(0, self.openButton) self.hl00.insertWidget(1, self.folderLabel) # left column - second item (1) self.folderTable = QTableWidget() self.folderTable.setMinimumSize(200, 32) self.folderTable.horizontalHeader().setVisible(False) self.folderTable.horizontalHeader().setStretchLastSection(True) self.folderTable.verticalHeader().setVisible(False) self.folderTable.verticalHeader().setDefaultSectionSize(15) self.folderTable.itemChanged.connect(self.editFileName) # left column - third item (2) self.extraLabel = QLabel() self.extraLabel.setMinimumSize(200, 20) self.extraLabel.setMaximumSize(16777215, 20) self.extraLabel.setSizePolicy(MinimumExpanding) self.extraLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse) # finalize left column self.vl01.insertLayout(0, self.hl00) self.vl01.insertWidget(1, self.folderTable) self.vl01.insertWidget(2, self.extraLabel) self.leftColumn.setLayout(self.vl01) # right column self.rightColumn = QWidget() self.vl02 = QVBoxLayout() # right column - first item (0) self.messageLabel = QLabel() self.messageLabel.setMinimumSize(290, 20) self.messageLabel.setMaximumSize(16777215, 20) self.messageLabel.setSizePolicy(MinimumExpanding) self.messageLabel.setAlignment(Qt.AlignCenter) # right column - second item (2; horizontal layout 1) self.hl01 = QHBoxLayout() self.hl01.setSpacing(5) self.encryptButton = QPushButton('&Encrypt') #\U0001F512 self.encryptButton.setToolTip('Encrypt selected file') self.encryptButton.setMinimumSize(60, 20) self.encryptButton.setMaximumSize(60, 20) self.encryptButton.setSizePolicy(Fixed) self.encryptButton.clicked.connect(self.encrypt) self.encryptPbar = QProgressBar() self.encryptPbar.setMinimumSize(225, 20) self.encryptPbar.setMaximumSize(16777215, 20) self.encryptPbar.setSizePolicy(MinimumExpanding) self.encryptPbar.setTextVisible(False) palette = self.encryptPbar.palette() # color of progress bar color = QColor(211, 70, 0) palette.setColor(QPalette.Highlight, color) self.encryptPbar.setPalette(palette) self.hl01.insertWidget(0, self.encryptButton) self.hl01.insertWidget(1, self.encryptPbar) # right column - third item (3; horizontal layout 2) self.hl02 = QHBoxLayout() self.hl02.setSpacing(5) self.cancelButton = QPushButton('C&ANCEL') self.cancelButton.setToolTip('Cancels current operation') self.cancelButton.setMinimumSize(70, 24) self.cancelButton.setMaximumSize(70, 24) self.cancelButton.setSizePolicy(Fixed) self.cancelButton.clicked.connect(self.setCancel) font = self.cancelButton.font() font.setBold(True) self.cancelButton.setFont(font) self.cancelButton.blockSignals(True) self.cancelButton.setEnabled(False) self.cancelButton.hide() self._requestStop = False self.keyInput = QLineEdit() self.keyInput.setMinimumSize(225, 20) self.keyInput.setMaximumSize(16777215, 20) self.keyInput.setSizePolicy(MinimumExpanding) self.keyInput.setPlaceholderText('key') self.keyInput.setMaxLength(self.maxKeyLen) self.keyInput.setAlignment(Qt.AlignCenter) self.keyInput.textEdited.connect(self.showKeyLen) self.genKeyButton = QPushButton('&Gen Key') #\U0001F511 self.genKeyButton.setToolTip('Generate a random key') self.genKeyButton.setMinimumSize(60, 20) self.genKeyButton.setMaximumSize(60, 20) self.genKeyButton.setSizePolicy(Fixed) self.genKeyButton.clicked.connect(self.genKey) self.keySizeSB = QSpinBox() self.keySizeSB.setToolTip('Length of key to generate') self.keySizeSB.setRange(32, 1024) self.keySizeSB.setMinimumSize(40, 20) self.keySizeSB.setMaximumSize(40, 20) self.keySizeSB.setSizePolicy(Fixed) self.keySizeSB.setAlignment(Qt.AlignCenter) self.keySizeSB.setButtonSymbols(QSpinBox.NoButtons) self.keySizeSB.setWrapping(True) self.hl02.insertWidget(0, self.cancelButton) self.hl02.insertWidget(1, self.keyInput) self.hl02.insertWidget(2, self.genKeyButton) self.hl02.insertWidget(3, self.keySizeSB) # right column - fourth item (4; horizontal layout 3) self.hl03 = QHBoxLayout() self.hl03.setSpacing(5) self.decryptButton = QPushButton('&Decrypt') #\U0001F513 self.decryptButton.setToolTip('Decrypt selected file') self.decryptButton.setMinimumSize(60, 20) self.decryptButton.setMaximumSize(60, 20) self.decryptButton.setSizePolicy(Fixed) self.decryptButton.clicked.connect(self.decrypt) self.decryptPbar = QProgressBar() self.decryptPbar.setMinimumSize(225, 20) self.decryptPbar.setMaximumSize(16777215, 20) self.decryptPbar.setSizePolicy(MinimumExpanding) self.decryptPbar.setTextVisible(False) self.decryptPbar.setInvertedAppearance(True) palette = self.decryptPbar.palette() # color of progress bar color = QColor(0, 170, 255) palette.setColor(QPalette.Highlight, color) self.decryptPbar.setPalette(palette) self.hl03.insertWidget(0, self.decryptButton) self.hl03.insertWidget(1, self.decryptPbar) # right column - fifth item (7; horizontal layout 4) self.hl04 = QHBoxLayout() self.hl04.setSpacing(5) self.showKeyCB = QCheckBox('&Show Key') self.showKeyCB.setToolTip('Show/Hide key value') self.showKeyCB.setMinimumSize(75, 20) self.showKeyCB.setMaximumSize(75, 20) self.showKeyCB.setSizePolicy(Fixed) self.showKeyCB.clicked.connect(self.showKey) self.showKeyCB.setChecked(True) self.hashPbar = QProgressBar() self.hashPbar.setMinimumSize(150, 20) self.hashPbar.setMaximumSize(16777215, 20) self.hashPbar.setSizePolicy(MinimumExpanding) self.hashPbar.setTextVisible(False) palette = self.hashPbar.palette() # color of progress bar color = QColor(31, 120, 73) palette.setColor(QPalette.Highlight, color) self.hashPbar.setPalette(palette) self.hashButton = QPushButton('&Hash') self.hashButton.setToolTip('Determine file hash') self.hashButton.setMinimumSize(60, 20) self.hashButton.setMaximumSize(60, 20) self.hashButton.setSizePolicy(Fixed) menu = QMenu(self.hashButton) ico = self.style().standardIcon(QStyle.SP_DialogYesButton) for alg in sorted( filter(lambda x: 'shake' not in x, hashlib.algorithms_guaranteed), key=lambda n: (len(n), sorted(hashlib.algorithms_guaranteed).index(n))): menu.addAction( ico, alg ) # drop shake algs as their .hexdigest requires an argument - the rest don't menu.addAction(ico, 'Party') for i in menu.actions(): i.setIconVisibleInMenu(False) self.hashButton.setMenu(menu) menu.triggered.connect(self.genHash) self.hl04.insertWidget(0, self.showKeyCB) self.hl04.insertWidget(1, self.hashPbar) self.hl04.insertWidget(2, self.hashButton) # right column - sixth item (8; horizontal layout 5) self.hl05 = QHBoxLayout() self.hl05.setSpacing(5) self.copyButton = QPushButton('&Copy') #\U0001F4CB self.copyButton.setToolTip('Copy key or hash to clipboard') self.copyButton.setMinimumSize(60, 20) self.copyButton.setMaximumSize(60, 20) self.copyButton.setSizePolicy(Fixed) menu2 = QMenu(self.copyButton) menu2.addAction('Copy Key') menu2.addAction('Copy Hash') self.copyButton.setMenu(menu2) menu2.triggered.connect(self.copyKeyHash) self.hashLabel = QLabel() self.hashLabel.setMinimumSize(225, 20) self.hashLabel.setMaximumSize(16777215, 20) self.hashLabel.setSizePolicy(MinimumExpanding) self.hashLabel.setTextFormat(Qt.PlainText) self.hashLabel.setAlignment(Qt.AlignCenter) self.hashLabel.setTextInteractionFlags(Qt.TextSelectableByMouse) self.hl05.insertWidget(0, self.copyButton) self.hl05.insertWidget(1, self.hashLabel) # finalize right column self.vl02.insertWidget(0, self.messageLabel) self.vl02.insertSpacerItem(1, QSpacerItem(0, 0)) self.vl02.insertLayout(2, self.hl01) self.vl02.insertLayout(3, self.hl02) self.vl02.insertLayout(4, self.hl03) self.vl02.insertSpacerItem(5, QSpacerItem(0, 0)) self.vl02.insertWidget(6, QFrame()) self.vl02.insertLayout(7, self.hl04) self.vl02.insertLayout(8, self.hl05) self.rightColumn.setLayout(self.vl02) # finalize main window self.splitter.insertWidget(0, self.leftColumn) self.splitter.insertWidget(1, self.rightColumn) layout = QHBoxLayout(self) layout.addWidget(self.splitter) self.setLayout(layout) self.setWindowTitle('Simple File Encryptor/Decryptor') self.resize(self.sizeHint())
def __set_options_ui(self): group_box = QGroupBox('Training Options') inner_layout = QFormLayout() group_box.setLayout(inner_layout) self.iter_times = QSpinBox() self.iter_times.setRange(1, 1000000) self.iter_times.setValue(200) self.iter_times.setStatusTip('The total iterating times for training.') self.population_size = QSpinBox() self.population_size.setRange(1, 100000) self.population_size.setValue(100) self.population_size.setStatusTip('The population size for the PSO.') self.inertia_weight = QDoubleSpinBox() self.inertia_weight.setRange(0, 50) self.inertia_weight.setValue(1) self.inertia_weight.setSingleStep(0.1) self.inertia_weight.setStatusTip('The inertia weight of the velocity ' ' for each individual.') self.cognitive_const_rand_upper = QDoubleSpinBox() self.cognitive_const_rand_upper.setRange(0, 50) self.cognitive_const_rand_upper.setValue(2) self.cognitive_const_rand_upper.setSingleStep(0.1) self.cognitive_const_rand_upper.setStatusTip( 'The random upper bound for cognitive accelerate constant.') self.social_const_rand_upper = QDoubleSpinBox() self.social_const_rand_upper.setRange(0, 50) self.social_const_rand_upper.setValue(3) self.social_const_rand_upper.setSingleStep(0.1) self.social_const_rand_upper.setStatusTip( 'The random upper bound for social accelerate constant.') self.v_max = QDoubleSpinBox() self.v_max.setRange(0.5, 100) self.v_max.setValue(5) self.v_max.setSingleStep(1) self.v_max.setStatusTip('The maximum of velocity for each individual.') self.nneuron = QSpinBox() self.nneuron.setRange(1, 100) self.nneuron.setValue(6) self.nneuron.setStatusTip('The number of RBFN neuron.') self.sd_max = QDoubleSpinBox() self.sd_max.setRange(0.01, 20) self.sd_max.setValue(10) self.sd_max.setSingleStep(0.1) self.sd_max.setStatusTip('The random range maximum of standard ' 'deviation of each neuron in RBFN (only for ' 'initialization).') inner_layout.addRow('Iterating Times:', self.iter_times) inner_layout.addRow('Population Size:', self.population_size) inner_layout.addRow('Inertia Weight:', self.inertia_weight) inner_layout.addRow('Cognitive Const Upper:', self.cognitive_const_rand_upper) inner_layout.addRow('Social Const Upper:', self.social_const_rand_upper) inner_layout.addRow('Maximum of Velocity:', self.v_max) inner_layout.addRow('Number of Neuron:', self.nneuron) inner_layout.addRow('Maximum of SD:', self.sd_max) self._layout.addWidget(group_box)
class DataBrowserMain(QWidget): sliceUpdated = Signal(int, int, int, int) def __init__(self, parent): super(DataBrowserMain, self).__init__(parent) # data import self.brkraw_obj = self.parent().brkraw_obj self.selectedScan = None self.selectedScanTR = None self.set_viewer_frame() self.set_controller_frame() self.set_gridlayouts() self.set_font() # self.set_palette() # TODO self.set_size() self.set_objectnames() self.set_texts() self.ratio_container = [] self.init_connection() self.inactivate_widgets() # Inactivate during startup def init_connection(self): self.parent().dataSelected.connect( self.selectScanEvent) # run selectScanEvent when data selected self.event_timer = QTimer() self.event_timer.timeout.connect(self.sliceUpdateEvent) # self.sliceUpdated.connect(self.updateImage) self.xaxis_slider.valueChanged.connect(self.xaxis_spinbox.setValue) self.xaxis_spinbox.valueChanged.connect(self.xaxis_slider.setValue) self.yaxis_slider.valueChanged.connect(self.yaxis_spinbox.setValue) self.yaxis_spinbox.valueChanged.connect(self.yaxis_slider.setValue) self.zaxis_slider.valueChanged.connect(self.zaxis_spinbox.setValue) self.zaxis_spinbox.valueChanged.connect(self.zaxis_slider.setValue) self.frame_slider.valueChanged.connect(self.frame_spinbox.setValue) self.frame_spinbox.valueChanged.connect(self.frame_slider.setValue) self.axial_view.pointed.connect(self.axialview_pointing_event) self.sagittal_view.pointed.connect(self.sagittalview_pointing_event) self.coronal_view.pointed.connect(self.coronalview_pointing_event) self.connect_sliders_to_update() def sagittalview_pointing_event(self, pos_x, pos_y, meta): max_x = self.yaxis_slider.maximum() max_y = self.zaxis_slider.maximum() # print(pos_x, pos_y, max_x, max_y) self.yaxis_slider.setValue(int(max_x * pos_x)) self.zaxis_slider.setValue(max_y - int(max_y * pos_y)) # print(int(max_x * pos_x), int(max_y * pos_y)) def axialview_pointing_event(self, pos_x, pos_y, meta): max_x = self.yaxis_slider.maximum() max_y = self.xaxis_slider.maximum() # print(pos_x, pos_y, max_x, max_y) self.yaxis_slider.setValue(int(max_x * pos_x)) self.xaxis_slider.setValue(int(max_y * pos_y)) # print(int(max_x * pos_x), int(max_y * pos_y)) def coronalview_pointing_event(self, pos_x, pos_y, meta): max_x = self.xaxis_slider.maximum() max_y = self.zaxis_slider.maximum() # print(pos_x, pos_y, max_x, max_y) self.xaxis_slider.setValue(int(max_x * pos_x)) self.zaxis_slider.setValue(max_y - int(max_y * pos_y)) # print(int(max_x * pos_x), int(max_y * pos_y)) def sliderChangeEvent(self): self.event_timer.start(10) def sliceUpdateEvent(self): # This will executed only when timer timeout x = self.xaxis_slider.value() y = self.yaxis_slider.value() z = self.zaxis_slider.value() t = self.frame_slider.value() self.sliceUpdated.emit(x, y, z, t) self.event_timer.stop() @staticmethod def slice_data(dataobj, slice_orient, slice_num): if slice_orient == 'axial': sliced_data = dataobj[:, :, slice_num] elif slice_orient == 'sagittal': sliced_data = dataobj[:, slice_num, ::-1] elif slice_orient == 'coronal': sliced_data = dataobj[slice_num, :, ::-1] else: popup_error_dialog(UnexpectedError.message) return None return sliced_data def updateImage(self, x, y, z, frame): if len(self.selectedScan.shape) == 4: dataobj = self.selectedScan[:, :, :, frame] else: dataobj = self.selectedScan[...] data_xy = self.slice_data(dataobj, 'axial', z) data_yz = self.slice_data(dataobj, 'sagittal', x) data_xz = self.slice_data(dataobj, 'coronal', y) ratio_xy, ratio_yz, ratio_xz = self.ratio_container # ratio_xy, ratio_yz, ratio_xz = 1, 1, 1 qm_xy = convert_arr2qpixmap(data_xy, ratio_xy) qm_yz = convert_arr2qpixmap(data_yz, ratio_yz) qm_xz = convert_arr2qpixmap(data_xz, ratio_xz) self.axial_view.setPixmap(qm_xy) self.sagittal_view.setPixmap(qm_yz) self.coronal_view.setPixmap(qm_xz) def selectScanEvent(self, delivery_package: list): """ this event is occurring when a scan selected on scanlist """ self.axial_view.setEnabled(True) self.sagittal_view.setEnabled(True) self.coronal_view.setEnabled(True) self.selectedScan, affine, resol, self.selectedScanTR, is_localizer = delivery_package self.selectedScanTR /= 1000 from slfmri.imgman import reorient_to_ras, determine_slice_plane slice_plane_ref = dict(sagittal=0, coronal=1, axial=2) if is_localizer: img_container = dict() for i, aff in enumerate(affine): size = config.get('ImageViewer', 'size') data = self.selectedScan[..., i] slice_plane = determine_slice_plane(2, aff, resol) ras_data, ras_resol = reorient_to_ras(data[:, :, np.newaxis], aff, resol) slice_axis = slice_plane_ref[slice_plane] ras_data = ras_data.mean(slice_axis) ras_resol = np.delete(ras_resol, slice_axis) qpixmap = convert_arr2qpixmap(ras_data, ras_resol, size) img_container[slice_plane] = qpixmap self.update_axisview(img_container) else: # other than localizer self.init_data(self.selectedScan) matrix_size = np.asarray(self.selectedScan.shape) resol = np.asarray(resol) fov = matrix_size[:3] * resol self.ratio_container = [ fov[0] / fov[1], fov[1] / fov[2], fov[0] / fov[2] ] # reset value init_x, init_y, init_z = (np.asarray(self.selectedScan.shape[:3]) / 2.0).astype(int) init_f = 0 self.disconnect_sliders_to_update() self.xaxis_slider.setValue(init_x) self.yaxis_slider.setValue(init_y) self.zaxis_slider.setValue(init_z) self.frame_slider.setValue(init_f) self.connect_sliders_to_update() self.updateImage(init_x, init_y, init_z, init_f) def connect_sliders_to_update(self): # connect to check slice update self.xaxis_slider.valueChanged.connect(self.sliderChangeEvent) self.yaxis_slider.valueChanged.connect(self.sliderChangeEvent) self.zaxis_slider.valueChanged.connect(self.sliderChangeEvent) self.frame_slider.valueChanged.connect(self.sliderChangeEvent) def disconnect_sliders_to_update(self): # disconnect to check slice update self.xaxis_slider.valueChanged.disconnect(self.sliderChangeEvent) self.yaxis_slider.valueChanged.disconnect(self.sliderChangeEvent) self.zaxis_slider.valueChanged.disconnect(self.sliderChangeEvent) self.frame_slider.valueChanged.disconnect(self.sliderChangeEvent) def init_data(self, dataobj): self.slicecontrol_pane.setEnabled(True) dim = len(dataobj.shape) if dim == 3: size_x, size_y, size_z = dataobj.shape size_frame = None elif dim == 4: size_x, size_y, size_z, size_frame = dataobj.shape else: popup_error_dialog(UnexpectedError.message) return None # init sliders and spinboxes self.xaxis_slider.setRange(0, size_x - 1) self.yaxis_slider.setRange(0, size_y - 1) self.zaxis_slider.setRange(0, size_z - 1) self.xaxis_spinbox.setRange(0, size_x - 1) self.yaxis_spinbox.setRange(0, size_y - 1) self.zaxis_spinbox.setRange(0, size_z - 1) if dim == 3: self.frame_label.setDisabled(True) self.frame_slider.setDisabled(True) self.frame_spinbox.setDisabled(True) else: self.frame_label.setEnabled(True) self.frame_slider.setEnabled(True) self.frame_spinbox.setEnabled(True) self.frame_slider.setRange(0, size_frame - 1) self.frame_spinbox.setRange(0, size_frame - 1) def update_axisview(self, img_container: dict): for view_plane, pixmap in img_container.items(): if view_plane == 'axial': self.axial_view.setPixmap(pixmap) elif view_plane == 'sagittal': self.sagittal_view.setPixmap(pixmap) else: self.coronal_view.setPixmap(pixmap) def inactivate_widgets(self): self.slicecontrol_pane.setDisabled(True) self.graph_frame.setDisabled(True) def set_navigationmode(self): # mouse click will navigate slice. pass def set_drawingmode(self): # roi drawing function pass def mask_data_handler(self): # mask later handler pass def slider_event_related(self): # slider for slicing. pass def set_viewer_frame(self): self.imageframe = QFrame(self) self.axial_view = SliceViewer(self.imageframe) self.axial_view.setDisabled(True) self.sagittal_view = SliceViewer(self.imageframe) self.sagittal_view.setDisabled(True) self.coronal_view = SliceViewer(self.imageframe) self.coronal_view.setDisabled(True) # TODO: Will reactivate these on later version # self.axial_title = QLabel(self.imageframe) # self.coronal_title = QLabel(self.imageframe) # self.sagittal_title = QLabel(self.imageframe) # # self.axialL_label = QLabel(self.imageframe) # self.axialA_label = QLabel(self.imageframe) # self.axialR_label = QLabel(self.imageframe) # self.axialP_label = QLabel(self.imageframe) # # self.sagittalS_label = QLabel(self.imageframe) # self.sagittalA_label = QLabel(self.imageframe) # self.sagittalI_label = QLabel(self.imageframe) # self.sagittalP_label = QLabel(self.imageframe) # # self.coronalL_label = QLabel(self.imageframe) # self.coronalS_label = QLabel(self.imageframe) # self.coronalR_label = QLabel(self.imageframe) # self.coronalI_label = QLabel(self.imageframe) # # self.axial_title.setTextFormat(Qt.MarkdownText) # self.axialL_label.setTextFormat(Qt.MarkdownText) # self.axialA_label.setTextFormat(Qt.MarkdownText) # self.axialR_label.setTextFormat(Qt.MarkdownText) # self.axialP_label.setTextFormat(Qt.MarkdownText) # # self.sagittal_title.setTextFormat(Qt.MarkdownText) # self.sagittalS_label.setTextFormat(Qt.MarkdownText) # self.sagittalA_label.setTextFormat(Qt.MarkdownText) # self.sagittalI_label.setTextFormat(Qt.MarkdownText) # self.sagittalP_label.setTextFormat(Qt.MarkdownText) # # self.coronal_title.setTextFormat(Qt.MarkdownText) # self.coronalL_label.setTextFormat(Qt.MarkdownText) # self.coronalS_label.setTextFormat(Qt.MarkdownText) # self.coronalR_label.setTextFormat(Qt.MarkdownText) # self.coronalI_label.setTextFormat(Qt.MarkdownText) # # self.axial_title.setAlignment(Qt.AlignCenter) # self.axialL_label.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) # self.axialA_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) # self.axialR_label.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter) # self.axialP_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop) # # self.sagittal_title.setAlignment(Qt.AlignCenter) # self.sagittalS_label.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) # self.sagittalA_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) # self.sagittalI_label.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter) # self.sagittalP_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop) # # self.coronal_title.setAlignment(Qt.AlignCenter) # self.coronalL_label.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) # self.coronalS_label.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) # self.coronalR_label.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter) # self.coronalI_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop) def set_controller_frame(self): self.controller_frame = QFrame(self) self.slicecontrol_pane = QGroupBox(self.controller_frame) self.frame_spinbox = QSpinBox(self.slicecontrol_pane) self.xaxis_label = QLabel(self.slicecontrol_pane) self.yaxis_label = QLabel(self.slicecontrol_pane) self.zaxis_label = QLabel(self.slicecontrol_pane) self.frame_label = QLabel(self.slicecontrol_pane) self.xaxis_slider = QSlider(self.slicecontrol_pane) self.yaxis_slider = QSlider(self.slicecontrol_pane) self.zaxis_slider = QSlider(self.slicecontrol_pane) self.frame_slider = QSlider(self.slicecontrol_pane) self.xaxis_spinbox = QSpinBox(self.slicecontrol_pane) self.yaxis_spinbox = QSpinBox(self.slicecontrol_pane) self.zaxis_spinbox = QSpinBox(self.slicecontrol_pane) self.graph_frame = QFrame(self) self.graph_view = pg.PlotWidget(self.graph_frame) self.graph_view.setBackground('w') # TODO: Will reactivate these on later version # self.graph_view = QGraphicsView(self.graph_frame) # self.graphcontrol_pane = QGroupBox(self.graph_frame) # self.addmask_button = QPushButton(self.graphcontrol_pane) # self.removemask_button = QPushButton(self.graphcontrol_pane) # self.mask_listview = QListView(self.graphcontrol_pane) # self.savepng_button = QPushButton(self.graphcontrol_pane) # self.savecsv_button = QPushButton(self.graphcontrol_pane) self.axial_view.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.sagittal_view.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.coronal_view.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.xaxis_slider.setOrientation(Qt.Horizontal) self.yaxis_slider.setOrientation(Qt.Horizontal) self.zaxis_slider.setOrientation(Qt.Horizontal) self.frame_slider.setOrientation(Qt.Horizontal) self.slicecontrol_pane.setAlignment(Qt.AlignCenter) self.xaxis_label.setAlignment(Qt.AlignCenter) self.yaxis_label.setAlignment(Qt.AlignCenter) self.zaxis_label.setAlignment(Qt.AlignCenter) self.frame_label.setAlignment(Qt.AlignCenter) # TODO: Will reactivate these on later version # self.graphcontrol_pane.setAlignment(Qt.AlignCenter) def set_size(self): size = int(config.get('ImageViewer', 'size')) self.imageframe.setLineWidth(0) self.axial_view.setMinimumSize(QSize(size, size)) self.axial_view.setMaximumSize(QSize(size, size)) self.axial_view.setLineWidth(0) self.sagittal_view.setMinimumSize(QSize(size, size)) self.sagittal_view.setMaximumSize(QSize(size, size)) self.sagittal_view.setLineWidth(0) self.coronal_view.setMinimumSize(QSize(size, size)) self.coronal_view.setMaximumSize(QSize(size, size)) self.coronal_view.setLineWidth(0) # TODO: Will reactivate these on later version # self.axialL_label.setMinimumSize(QSize(20, 0)) # self.axialA_label.setMinimumSize(QSize(0, 20)) # self.axialR_label.setMinimumSize(QSize(20, 0)) # self.axialP_label.setMinimumSize(QSize(0, 20)) # self.sagittalS_label.setMinimumSize(QSize(20, 0)) # self.sagittalA_label.setMinimumSize(QSize(0, 20)) # self.sagittalI_label.setMinimumSize(QSize(20, 0)) # self.sagittalP_label.setMinimumSize(QSize(0, 20)) # self.coronalL_label.setMinimumSize(QSize(20, 0)) # self.coronalS_label.setMinimumSize(QSize(0, 20)) # self.coronalR_label.setMinimumSize(QSize(20, 0)) # self.coronalI_label.setMinimumSize(QSize(0, 20)) self.controller_frame.setMinimumSize(QSize(300, 300)) self.controller_frame.setMaximumSize(QSize(400, 300)) self.graph_frame.setMinimumSize(QSize(0, 300)) self.graph_frame.setMaximumSize(QSize(4000, 4000)) self.graph_view.setMaximumSize(QSize(4000, 600)) # TODO: Will reactivate these on later version # self.graphcontrol_pane.setMinimumSize(QSize(300, 0)) # self.graphcontrol_pane.setMaximumSize(QSize(300, 4000)) # self.addmask_button.setMinimumSize(QSize(30, 0)) # self.addmask_button.setMaximumSize(QSize(30, 4000)) # self.removemask_button.setMinimumSize(QSize(30, 0)) # self.removemask_button.setMaximumSize(QSize(30, 4000)) def set_font(self): self.arial_8 = QFont() self.arial_8.setFamily(u"Arial") self.arial_8.setPointSize(8) self.setFont(self.arial_8) # TODO: Will reactivate these on later version # self.axial_title.setFont(self.arial_8) # self.coronal_title.setFont(self.arial_8) # self.sagittal_title.setFont(self.arial_8) # self.axialL_label.setFont(self.arial_8) # self.axialA_label.setFont(self.arial_8) # self.axialR_label.setFont(self.arial_8) # self.axialP_label.setFont(self.arial_8) # self.sagittalS_label.setFont(self.arial_8) # self.sagittalA_label.setFont(self.arial_8) # self.sagittalI_label.setFont(self.arial_8) # self.sagittalP_label.setFont(self.arial_8) # self.coronalL_label.setFont(self.arial_8) # self.coronalS_label.setFont(self.arial_8) # self.coronalR_label.setFont(self.arial_8) # self.coronalI_label.setFont(self.arial_8) self.slicecontrol_pane.setFont(self.arial_8) # TODO: Will reactivate these on later version # self.xaxis_label.setFont(self.arial_8) # self.yaxis_label.setFont(self.arial_8) # self.zaxis_label.setFont(self.arial_8) # self.frame_label.setFont(self.arial_8) # self.graphcontrol_pane.setFont(self.arial_8) # self.addmask_button.setFont(self.arial_8) # self.removemask_button.setFont(self.arial_8) # self.savepng_button.setFont(self.arial_8) # self.savecsv_button.setFont(self.arial_8) def set_palette(self): # Brush gray_text = QBrush(QColor(171, 171, 171, 255)) gray_text.setStyle(Qt.SolidPattern) black_background = QBrush(QColor(0, 0, 0, 255)) black_background.setStyle(Qt.SolidPattern) self.orientation_label_palette = QPalette() self.orientation_label_palette.setBrush(QPalette.Active, QPalette.WindowText, gray_text) self.orientation_label_palette.setBrush(QPalette.Inactive, QPalette.WindowText, gray_text) self.orientation_label_palette.setBrush(QPalette.Disabled, QPalette.WindowText, gray_text) self.ortho_viewer_palette = QPalette() self.ortho_viewer_palette.setBrush(QPalette.Active, QPalette.Base, black_background) self.ortho_viewer_palette.setBrush(QPalette.Inactive, QPalette.Base, black_background) self.ortho_viewer_palette.setBrush(QPalette.Disabled, QPalette.Base, black_background) self.axialA_label.setPalette(self.orientation_label_palette) self.axialL_label.setPalette(self.orientation_label_palette) self.axialR_label.setPalette(self.orientation_label_palette) self.axialP_label.setPalette(self.orientation_label_palette) self.axial_view.setPalette(self.ortho_viewer_palette) self.sagittalS_label.setPalette(self.orientation_label_palette) self.sagittalA_label.setPalette(self.orientation_label_palette) self.sagittalI_label.setPalette(self.orientation_label_palette) self.sagittalP_label.setPalette(self.orientation_label_palette) self.sagittal_view.setPalette(self.ortho_viewer_palette) self.coronalL_label.setPalette(self.orientation_label_palette) self.coronalS_label.setPalette(self.orientation_label_palette) self.coronalR_label.setPalette(self.orientation_label_palette) self.coronalI_label.setPalette(self.orientation_label_palette) self.coronal_view.setPalette(self.ortho_viewer_palette) def set_gridlayouts(self): self.axial_gridLayout = QGridLayout() self.coronal_gridLayout = QGridLayout() self.sagittal_gridLayout = QGridLayout() self.imagecont_gridLayout = QGridLayout(self.slicecontrol_pane) self.imageframe_gridLayout = QGridLayout(self.imageframe) # self.graphcontrol_gridLayout = QGridLayout(self.graphcontrol_pane) self.verticalLayout = QVBoxLayout(self.controller_frame) self.horizontalLayout = QHBoxLayout(self.graph_frame) self.main_gridLayout = QGridLayout(self) # TODO: Will reactivate these on later version # self.imageframe_gridLayout.addWidget(self.axial_title, 0, 1, 1, 1) # self.imageframe_gridLayout.addWidget(self.coronal_title, 0, 2, 1, 1) # self.imageframe_gridLayout.addWidget(self.sagittal_title, 0, 0, 1, 1) # self.axial_gridLayout.addWidget(self.axialL_label, 1, 0, 1, 1) # self.axial_gridLayout.addWidget(self.axialA_label, 0, 1, 1, 1) # self.axial_gridLayout.addWidget(self.axialR_label, 1, 2, 1, 1) # self.axial_gridLayout.addWidget(self.axialP_label, 2, 1, 1, 1) self.axial_gridLayout.addWidget(self.axial_view, 1, 1, 1, 1) # self.sagittal_gridLayout.addWidget(self.sagittalS_label, 1, 0, 1, 1) # self.sagittal_gridLayout.addWidget(self.sagittalA_label, 0, 1, 1, 1) # self.sagittal_gridLayout.addWidget(self.sagittalI_label, 1, 2, 1, 1) # self.sagittal_gridLayout.addWidget(self.sagittalP_label, 2, 1, 1, 1) self.sagittal_gridLayout.addWidget(self.sagittal_view, 1, 1, 1, 1) # self.coronal_gridLayout.addWidget(self.coronalL_label, 1, 0, 1, 1) # self.coronal_gridLayout.addWidget(self.coronalS_label, 0, 1, 1, 1) # self.coronal_gridLayout.addWidget(self.coronalR_label, 1, 2, 1, 1) # self.coronal_gridLayout.addWidget(self.coronalI_label, 2, 1, 1, 1) self.coronal_gridLayout.addWidget(self.coronal_view, 1, 1, 1, 1) self.imagecont_gridLayout.addWidget(self.xaxis_label, 0, 0, 1, 1) self.imagecont_gridLayout.addWidget(self.xaxis_slider, 0, 1, 1, 1) self.imagecont_gridLayout.addWidget(self.xaxis_spinbox, 0, 2, 1, 1) self.imagecont_gridLayout.addWidget(self.yaxis_label, 1, 0, 1, 1) self.imagecont_gridLayout.addWidget(self.yaxis_slider, 1, 1, 1, 1) self.imagecont_gridLayout.addWidget(self.yaxis_spinbox, 1, 2, 1, 1) self.imagecont_gridLayout.addWidget(self.zaxis_label, 2, 0, 1, 1) self.imagecont_gridLayout.addWidget(self.zaxis_slider, 2, 1, 1, 1) self.imagecont_gridLayout.addWidget(self.zaxis_spinbox, 2, 2, 1, 1) self.imagecont_gridLayout.addWidget(self.frame_label, 3, 0, 1, 1) self.imagecont_gridLayout.addWidget(self.frame_slider, 3, 1, 1, 1) self.imagecont_gridLayout.addWidget(self.frame_spinbox, 3, 2, 1, 1) self.imageframe_gridLayout.addLayout(self.axial_gridLayout, 1, 1, 1, 1) self.imageframe_gridLayout.addLayout(self.coronal_gridLayout, 1, 2, 1, 1) self.imageframe_gridLayout.addLayout(self.sagittal_gridLayout, 1, 0, 1, 1) # self.graphcontrol_gridLayout.addWidget(self.addmask_button, 3, 0, 1, 1) # self.graphcontrol_gridLayout.addWidget(self.removemask_button, 3, 1, 1, 1) # self.graphcontrol_gridLayout.addWidget(self.mask_listview, 0, 0, 1, 5) # self.graphcontrol_gridLayout.addWidget(self.savepng_button, 3, 4, 1, 1) # self.graphcontrol_gridLayout.addWidget(self.savecsv_button, 3, 3, 1, 1) self.verticalLayout.addWidget(self.slicecontrol_pane) self.horizontalLayout.addWidget(self.graph_view) # self.horizontalLayout.addWidget(self.graphcontrol_pane) self.main_gridLayout.addWidget(self.imageframe, 0, 0, 1, 2) self.main_gridLayout.addWidget(self.controller_frame, 1, 0, 1, 1) self.main_gridLayout.addWidget(self.graph_frame, 1, 1, 1, 1) def set_objectnames(self): self.setObjectName(u"data_browser") self.imageframe.setObjectName(u"image_frame") self.axial_gridLayout.setObjectName(u"axial_gridLayout") self.coronal_gridLayout.setObjectName(u"coronal_gridLayout") self.sagittal_gridLayout.setObjectName(u"sagittal_gridLayout") # TODO: Will reactivate these on later version # self.axial_title.setObjectName(u"axial_label") # self.coronal_title.setObjectName(u"coronal_label") # self.sagittal_title.setObjectName(u"sagittal_label") self.axial_view.setObjectName(u"axial_view") self.sagittal_view.setObjectName(u"sagittal_view") self.coronal_view.setObjectName(u"coronal_view") # self.axialL_label.setObjectName(u"axialL_label") # self.axialR_label.setObjectName(u"axialR_label") # self.axialA_label.setObjectName(u"axialA_label") # self.axialP_label.setObjectName(u"axialP_label") # self.sagittalS_label.setObjectName(u"sagittalS_label") # self.sagittalA_label.setObjectName(u"sagittalA_label") # self.sagittalI_label.setObjectName(u"sagittalI_label") # self.sagittalP_label.setObjectName(u"sagittalP_label") # self.coronalL_label.setObjectName(u"coronalL_label") # self.coronalS_label.setObjectName(u"coronalS_label") # self.coronalR_label.setObjectName(u"coronalR_label") # self.coronalI_label.setObjectName(u"coronalI_label") self.controller_frame.setObjectName(u"controller_frame") self.slicecontrol_pane.setObjectName(u"slicecontrol_pane") self.xaxis_label.setObjectName(u"xaxis_label") self.xaxis_slider.setObjectName(u"xaxis_slider") self.xaxis_spinbox.setObjectName(u"xaxis_spinbox") self.yaxis_label.setObjectName(u"yaxis_label") self.yaxis_slider.setObjectName(u"yaxis_slider") self.yaxis_spinbox.setObjectName(u"yaxis_spinbox") self.zaxis_label.setObjectName(u"zaxis_label") self.zaxis_slider.setObjectName(u"zaxis_slider") self.zaxis_spinbox.setObjectName(u"zaxis_spinbox") self.frame_label.setObjectName(u"frame_label") self.frame_slider.setObjectName(u"frame_slider") self.frame_spinbox.setObjectName(u"frame_spinbox") self.graph_frame.setObjectName(u"graph_frame") self.graph_view.setObjectName(u"graph_view") # TODO: Will reactivate these on later version # self.graphcontrol_pane.setObjectName(u"graphcontrol_pane") # self.addmask_button.setObjectName(u"addmask_button") # self.removemask_button.setObjectName(u"removemask_button") # self.mask_listview.setObjectName(u"mask_listview") # self.savepng_button.setObjectName(u"savepng_button") # self.savecsv_button.setObjectName(u"savecsv_button") self.imagecont_gridLayout.setObjectName(u"imagecont_gridLayout") self.imageframe_gridLayout.setObjectName(u"imageframe_gridLayout") # self.graphcontrol_gridLayout.setObjectName(u"graphcontrol_gridLayout") self.verticalLayout.setObjectName(u"verticalLayout") self.horizontalLayout.setObjectName(u"horizontalLayout") self.main_gridLayout.setObjectName(u"main_gridLayout") QMetaObject.connectSlotsByName(self) def set_texts(self): self.setWindowTitle(u"Data Browser") # TODO: Will reactivate these on later version # self.axial_title.setText(u"**Axial**") # self.coronal_title.setText(u"**Coronal**") # self.sagittal_title.setText(u"**Sagittal**") # self.sagittalS_label.setText(u"**S**") # self.sagittalA_label.setText(u"**A**") # self.sagittalI_label.setText(u"**I**") # self.sagittalP_label.setText(u"**P**") # self.axialL_label.setText(u"**L**") # self.axialA_label.setText(u"**A**") # self.axialR_label.setText(u"**R**") # self.axialP_label.setText( u"**P**") # self.coronalL_label.setText(u"**L**") # self.coronalS_label.setText(u"**S**") # self.coronalR_label.setText(u"**R**") # self.coronalI_label.setText(u"**I**") self.slicecontrol_pane.setTitle(u"Slice Control Pane") self.xaxis_label.setText(u"x") self.yaxis_label.setText(u"y") self.zaxis_label.setText(u"z") self.frame_label.setText(u"Frame") # TODO: Will reactivate these on later version # self.graphcontrol_pane.setTitle(u"Graph Control Pane") # self.addmask_button.setText(u"+") # self.removemask_button.setText(u"-") # self.savepng_button.setText(u"toPNG") # self.savecsv_button.setText(u"toCSV") def plot_timecourse(self, x, y): self.graph_frame.setEnabled(True) self.graph_view.clear() pen = pg.mkPen(color=(255, 0, 0)) if x is None: x = [0] y = [y] self.graph_view.plot(x, y, pen=pen, symbol='o') else: self.graph_view.plot(x, y, pen=pen) def get_coord(self): x = self.xaxis_slider.value() y = self.yaxis_slider.value() z = self.zaxis_slider.value() return (x, y, z)
def editor(self): w = QWidget() l = QFormLayout(w) width = QSpinBox() width.setMinimum(1) width.setMaximum(MAX_WIDTH) width.setValue(self.desc.width) def _set_width(value): self.desc.width = value width.valueChanged.connect(_set_width) l.addRow('Width', width) num_inputs = QSpinBox() num_inputs.setMinimum(2) num_inputs.setValue(self.desc.num_inputs) num_inputs.valueChanged.connect(self._set_num_inputs) l.addRow('Number of inputs', num_inputs) return w
class Clock_widget(QMainWindow): def __init__(self, frameless=False, web=False, debug=0): super(Clock_widget, self).__init__() self.debug = debug self.frameless = frameless self.web = web self.analog = None self.bedtime = QTime(20, 15, 00) self.bedtime_grace_period = 10 self.LEDBall_state = 0 self.temp_update_interval = 10 self.n_updates = 0 self.temp_data = ['i', 0, 0, 0, 'o', 0, 0, 0, 'c', 0, 0] self.LCD_brightness = 150 self.resize(800, 460) self.setupUi(self) self.timer = QTimer(self) self.timer.timeout.connect(self.update) self.timer.start(1000) def setupUi(self, parent): """Setup the interfaces for the clock.""" if not self.objectName(): self.setObjectName(u"Clock") sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(parent.sizePolicy().hasHeightForWidth()) parent.setSizePolicy(sizePolicy) parent.setAutoFillBackground(True) parent.setWindowFlag(Qt.Widget, True) if os.uname().sysname == "Linux" or self.frameless: parent.setWindowFlag(Qt.FramelessWindowHint, True) self.tabWidget = QTabWidget(parent) self.tabWidget.setObjectName(u"tabWidget") self.tabWidget.setGeometry(QRect(0, 0, 800, 460)) # This works for Mac, but seems to not work with Linux/Arm/RPi # tabbar = self.tabWidget.tabBar() # tabbar.setMinimumSize(50, 24) # tabfont = QFont() # tabfont.setBold(True) # tabfont.setItalic(True) # tabfont.setPointSize(32) # tabbar.setFont(tabfont) # Setup the TABS self.clock = QWidget() self.clock.setObjectName(u"clock") self.tabWidget.addTab(self.clock, "") self.tabWidget.setTabText(self.tabWidget.indexOf(self.clock), "Clock") self.weather = QWeather(parent=None, debug=self.debug) self.tabWidget.addTab(self.weather, "") self.tabWidget.setTabText(self.tabWidget.indexOf(self.weather), "Weather") self.settings = QWidget() self.settings.setObjectName(u"settings") self.tabWidget.addTab(self.settings, "") self.tabWidget.setTabText(self.tabWidget.indexOf(self.settings), "Settings") self.tabWidget.setCurrentIndex(0) ################################################################################################# # Setup Clock Page ################################################################################################# self.analog = AnalogClock(self.clock) # DIGITAL clock in "clock" tab self.Digital = QLabel(self.clock) self.Digital.setObjectName(u"Digital") self.Digital.setGeometry(QRect(0, 5, 765, 71)) self.Digital.setAutoFillBackground(False) self.Digital.setStyleSheet(u"") self.Digital.setText(u"Current Time - Date + time") # Weather Icon self.weathericon = QWeatherIcon((480, 5), self.weather, parent=self.clock) self.weather.weather_updated.connect(self.weathericon.update) # Weather info on the Clock page. self.minipanel = QTempMiniPanel((475, 105), self.weather, parent=self.clock) self.weather.temp_updated.connect(self.minipanel.update) self.hilo = QHiLoTide((580, 5), parent=self.clock, debug=self.debug) # Moon phase self.moon = QMoon(pos=(450, 210), parent=self.clock, size=216, web=self.web) # Push buttons in "clock tab. push_button_width = 111 push_button_height = 40 push_button_x = 670 push_button_y = 220 self.ledball_off = QPushButton(self.clock) self.ledball_off.setObjectName(u"ledball_off") self.ledball_off.setText(u"LED off") self.ledball_off.setGeometry(QRect(push_button_x, push_button_y, push_button_width, push_button_height)) self.ledball_on = QPushButton(self.clock) self.ledball_on.setObjectName(u"ledball_on") self.ledball_on.setText(u"LED on ") self.ledball_on.setGeometry(QRect(push_button_x, push_button_y+push_button_height, push_button_width, push_button_height)) self.ledball_on2 = QPushButton(self.clock) self.ledball_on2.setObjectName(u"ledball_on2") self.ledball_on2.setText(u"LED on 2") self.ledball_on2.setGeometry(QRect(push_button_x, push_button_y+push_button_height*2, push_button_width, push_button_height)) self.sleep = QPushButton(self.clock) self.sleep.setObjectName(u"sleep") self.sleep.setText(u"Sleep") self.sleep.setGeometry(QRect(push_button_x, push_button_y+push_button_height*3+10, push_button_width, push_button_height)) ################################################################################################# # Setup Weather Page ################################################################################################# ################################################################################################# # Setup Setting Page ################################################################################################# self.timeEdit = QTimeEdit(self.settings) self.timeEdit.setObjectName(u"timeEdit") self.timeEdit.setDisplayFormat(u"h:mm AP") self.timeEdit.setGeometry(QRect(200, 30, 191, 41)) font8 = QFont() font8.setFamily(u"Gill Sans") font8.setPointSize(16) font8.setBold(False) font8.setItalic(False) font8.setWeight(50) self.timeEdit.setFont(font8) self.timeEdit.setAutoFillBackground(True) self.timeEdit.setTime(self.bedtime) self.bedtime_label = QLabel(self.settings) self.bedtime_label.setObjectName(u"bedtime_label") self.bedtime_label.setText(u"Set Bedtime:") self.bedtime_label.setGeometry(QRect(200, 0, 151, 31)) self.bedtime_label.setFont(font8) self.bedtime_label.setAutoFillBackground(True) self.Brightness_Value = QLCDNumber(self.settings) self.Brightness_Value.setObjectName(u"Brightness_Value") self.Brightness_Value.setGeometry(QRect(20, 120, 61, 31)) self.Brightness_Value.setStyleSheet(u"color: \"White\";\n" "margin:0px;\n" "border:0px;background:\"transparent\";") self.Brightness_Value.setDigitCount(3) self.Brightness_Value.setProperty("value", 180.000000000000000) self.Brightness = QSlider(self.settings) self.Brightness.setObjectName(u"Brightness") self.Brightness.setGeometry(QRect(30, 160, 51, 261)) self.Brightness.setAutoFillBackground(False) self.Brightness.setMaximum(255) self.Brightness.setValue(self.LCD_brightness) self.Brightness.setOrientation(Qt.Vertical) self.Brightness_label = QLabel(self.settings) self.Brightness_label.setObjectName(u"Brightness_label") self.Brightness_label.setText(u"Brightness") self.Brightness_label.setGeometry(QRect(20, 70, 101, 41)) font10 = QFont() font10.setFamily(u"Arial Black") font10.setPointSize(12) font10.setBold(True) font10.setWeight(75) self.Brightness_label.setFont(font10) self.temp_test = QLabel(self.settings) self.temp_test.setObjectName(u"temp_test") self.temp_test.setText(u"T20.5 C") self.temp_test.setFont(font8) self.temp_test.setGeometry(QRect(630, 60, 141, 51)) # self.temp_test.setFont(font_bold_20) self.temp_test_slide = QSlider(self.settings) self.temp_test_slide.setObjectName(u"temp_test_slide") self.temp_test_slide.setGeometry(QRect(660, 150, 51, 271)) self.temp_test_slide.setAutoFillBackground(False) self.temp_test_slide.setMinimum(-250) self.temp_test_slide.setMaximum(450) self.temp_test_slide.setSingleStep(5) self.temp_test_slide.setPageStep(25) self.temp_test_slide.setValue(38) self.temp_test_slide.setOrientation(Qt.Vertical) self.temp_check_outside = QCheckBox(self.settings) self.temp_check_outside.setObjectName(u"temp_check_outside") self.temp_check_outside.setText(u"Outside") self.temp_check_outside.setGeometry(QRect(640, 110, 86, 20)) self.grace_period = QSpinBox(self.settings) self.grace_period.setObjectName(u"grace_period") self.grace_period.setGeometry(QRect(411, 31, 111, 41)) self.grace_period.setFont(font8) self.grace_period.setMinimum(1) self.grace_period.setMaximum(60) self.grace_period.setValue(self.bedtime_grace_period) self.grace_period.setDisplayIntegerBase(10) self.grace_period_label = QLabel(self.settings) self.grace_period_label.setObjectName(u"grace_period_label") self.grace_period_label.setText(u"Grace period:") self.grace_period_label.setGeometry(QRect(410, 10, 111, 16)) self.grace_period_label.setFont(font8) ################################################################################################# # SET ALL LABEL TEXTS ################################################################################################# # if QT_CONFIG(tooltip) self.sleep.setToolTip(u"Put display to sleep") self.ledball_on2.setToolTip(u"Turn on the LED Ball, mode 2") self.ledball_on.setToolTip(u"Turn on the LED Ball.") self.ledball_off.setToolTip(u"Turn off the LED Ball.") # endif // QT_CONFIG(tooltip) ################################################################################################# # Make the Connections. ################################################################################################# self.temp_test_slide.valueChanged.connect(self.test_temp_update) self.temp_check_outside.clicked.connect(self.test_temp_update) self.ledball_off.clicked.connect(self.set_ledball_off) self.ledball_on.clicked.connect(self.set_ledball_on) self.ledball_on2.clicked.connect(self.set_ledball_on2) self.sleep.clicked.connect(self.set_sleep) self.timeEdit.timeChanged.connect(self.set_bedtime) self.grace_period.valueChanged.connect(self.set_grace_period) self.Brightness.valueChanged.connect(self.set_screen_brightness) self.Brightness.valueChanged.connect(self.Brightness_Value.display) def setup_from_json(self, json): """Set settings from the json dictionary passed.""" if "BedTime" in json: new_bedtime = QTime.fromString(json["BedTime"], "hh:mm:ss") if not new_bedtime.isValid(): new_bedtime = QTime.fromString(json["BedTime"], "hh:mm") if new_bedtime.isValid(): self.bedtime = new_bedtime self.timeEdit.setTime(self.bedtime) else: print("Could not set bedtime to {}".format(str(new_bedtime))) if "GracePeriod" in json: self.bedtime_grace_period = int(json["GracePeriod"]) self.grace_period.setValue(self.bedtime_grace_period) if "Brightness" in json: self.LCD_brightness = int(json["Brightness"]) self.Brightness.setValue(self.LCD_brightness) @Slot() def update(self): """This is called every second to perform the clock functions.""" AnalogClock.update(self) dtime = QDateTime.currentDateTime() text = dtime.toString("ddd MMM dd hh:mm:ss") self.Digital.setText(text) time = dtime.time() if self.bedtime < time < self.bedtime.addSecs(self.bedtime_grace_period * 60): self.Digital.setStyleSheet("color: rgba(200,100,0,200)") self.Digital.setText(text + " Bedtime") if self.bedtime < time < self.bedtime.addSecs(1) and self.LEDBall_state > 0: self.set_ledball_ready_for_bed() if self.bedtime.addSecs(self.bedtime_grace_period*60) < time < \ self.bedtime.addSecs(self.bedtime_grace_period*60 + 1): self.Digital.setStyleSheet("") self.set_ledball_off() self.turn_off_lcd() @Slot() def set_ledball_off(self): """Turn off the LED ball.""" if self.debug > 0: print("Set LED ball off.") os.system("ssh bbb1 \"./LEDBall_off.py\" >/dev/null") self.LEDBall_state = 0 @Slot() def set_ledball_ready_for_bed(self): """Set LED ball to very red.""" if self.LEDBall_state != 3: if self.debug > 0: print("Set LED ball to ready for bed.") os.system("ssh bbb1 \"./LEDBall_off.py && ./matrix.py 200 5.\" >/dev/null ") self.LEDBall_state = 3 @Slot() def set_ledball_on(self): """Turn LED ball to normal on""" if self.debug > 0: print("Set LED ball on.") os.system("(ssh bbb1 \"./LEDBall_off.py && ./matrix.py 200\" >/dev/null)") self.LEDBall_state = 1 @Slot() def set_ledball_on2(self): """Turn LED ball to alternate on""" if self.debug > 0: print("Set LED ball alternate on.") os.system("(ssh bbb1 \"./LEDBall_off.py && ./matrix.py 300 3. 50\" >/dev/null)"); self.LEDBall_state = 2 @Slot() def set_sleep(self): self.set_ledball_off() self.turn_off_lcd() def turn_off_lcd(self): """Turn the LCD off with the DPMS.""" if os.uname().sysname == "Linux": os.system("/usr/bin/xset dpms force off"); def set_pressure_color(selfs, obj, press, valid = True): """Set the color of obj according to the pressure. """ pressures = (900., 950., 1000., 1020., 1040.) colors = (0, 60, 120, 240, 300) if valid: if press < pressures[0]: press = pressures[0] + 0.0001 if press > pressures[-1]: press = pressures[-1] - 0.0001 i=0 while press > pressures[i]: i += 1 hue = int(((press - pressures[i-1])/(pressures[i] - pressures[i-1]))*(colors[i]-colors[i-1]) + colors[i-1]) color = QColor.fromHsv(hue, 255, 120, 255) obj.setStyleSheet("color: rgba({},{},{},255)".format(color.red(), color.green(), color.blue())) def set_temp_color(self, obj, temp, inside=True, invalid=False): """Set the color of obj depending on the temperature displayed by obj.""" temps = (-15., 16., 28., 40.) colors = (270, 145, 60, 0) if inside: temps = (12., 20., 25., 32.) if invalid: obj.setStyleSheet("color: rgba(100,100,100,100)") else: if temp < temps[0]: temp = temps[0] + 0.0001 if temp > temps[-1]: temp = temps[-1] - 0.0001 i = 0 while temp > temps[i]: i += 1 hue = int(((temp - temps[i-1])/(temps[i] - temps[i-1]))*(colors[i] - colors[i-1]) + colors[i-1]) color = QColor.fromHsv(hue, 255, 150, 255) obj.setStyleSheet("color: rgba({},{},{},255)".format(color.red(), color.green(), color.blue())) @Slot() def test_temp_update(self, val=None): """Update the temperature on the test slider.""" if val is None or type(val) is bool: val = self.temp_test_slide.value() temp = val*0.1 text = "{:6.2f} C".format(temp) self.temp_test.setText(text) self.set_temp_color(self.temp_test, temp, not self.temp_check_outside.isChecked(), False) @Slot() def set_bedtime(self, ntime): """Set the bedtime to a new time""" self.bedtime = ntime @Slot() def set_grace_period(self, grace): """Set the grace period to a new delta time""" self.bedtime_grace_period = grace @Slot() def set_screen_brightness(self, value): """Set the brightness of the screen on Raspberry Pi""" self.LCD_brightness = value if os.uname().sysname == "Linux": try: f = open("/sys/class/backlight/rpi_backlight/brightness", "w") f.write(str(value)) f.close() except Exception as e: print("Issue with opening brightness file \n",e)
class MagnifierWidget(ToolWidget): def __init__(self, image, parent=None): super(MagnifierWidget, self).__init__(parent) self.equalize_radio = QRadioButton(self.tr('Equalization')) self.contrast_radio = QRadioButton(self.tr('Auto Contrast')) self.retinex_radio = QRadioButton(self.tr('Human Retina')) self.centile_spin = QSpinBox() self.centile_spin.setRange(0, 100) self.centile_spin.setValue(20) self.centile_spin.setSuffix(self.tr(' %')) self.channel_check = QCheckBox(self.tr('By channel')) self.equalize_radio.setChecked(True) self.last_radio = self.equalize_radio self.image = image self.viewer = ImageViewer(self.image, self.image) self.change() self.viewer.view_changed.connect(self.process) self.equalize_radio.toggled.connect(self.change) self.contrast_radio.toggled.connect(self.change) self.centile_spin.valueChanged.connect(self.change) self.channel_check.stateChanged.connect(self.change) self.retinex_radio.toggled.connect(self.change) top_layout = QHBoxLayout() top_layout.addWidget(QLabel(self.tr('Enhancement:'))) top_layout.addWidget(self.equalize_radio) top_layout.addWidget(self.contrast_radio) top_layout.addWidget(self.centile_spin) top_layout.addWidget(self.channel_check) top_layout.addWidget(self.retinex_radio) top_layout.addStretch() main_layout = QVBoxLayout() main_layout.addLayout(top_layout) main_layout.addWidget(self.viewer) self.setLayout(main_layout) def process(self, rect): y1 = rect.top() y2 = rect.bottom() x1 = rect.left() x2 = rect.right() roi = self.image[y1:y2, x1:x2] if self.equalize_radio.isChecked(): roi = cv.merge([cv.equalizeHist(c) for c in cv.split(roi)]) self.last_radio = self.equalize_radio elif self.contrast_radio.isChecked(): centile = self.centile_spin.value() / 200 if self.channel_check.isChecked(): roi = cv.merge([cv.LUT(c, auto_lut(c, centile)) for c in cv.split(roi)]) else: roi = cv.LUT(roi, auto_lut(cv.cvtColor(roi, cv.COLOR_BGR2GRAY), centile)) self.last_radio = self.contrast_radio elif self.retinex_radio.isChecked(): self.last_radio = self.retinex_radio else: self.last_radio.setChecked(True) return processed = np.copy(self.image) processed[y1:y2, x1:x2] = roi self.viewer.update_processed(processed) def change(self): self.process(self.viewer.get_rect())
class FirstAlgorithm(QDialog): executed = Signal(dict, list) defaultParameters = { 'offset filter': True, 'supply filter': True, 'LPF highcut': 3, 'BPF lowcut': 8, 'BPF highcut': 30, 'art thres': 100, 'window': 25, 'prev sec': 5, 'hmt larger': 3, 'hmt larger mean': 2, } def __init__(self, dataManager, chartManager, parent=None, inputList=None, initParam=None): QDialog.__init__(self, parent) self.dataManager = dataManager self.fs = self.dataManager.getFs() self.chartManager = chartManager self.setWindowTitle('Algorithms') self.inputList = inputList if initParam: self.parameters = initParam print('initParam') else: self.parameters = self.defaultParameters print('defaultParameters') #Setup Layouts self.mainLayout = QVBoxLayout(self) self.setupInLayout() self.setupSettings() self.setupBtnBoxLayout() def setupInLayout(self): inGroup = QGroupBox('Input to process') inLayout = QFormLayout(inGroup) self.inTree = DataSelector(self.dataManager, inputList=self.inputList) inLayout.addWidget(QLabel('Select Input')) inLayout.addWidget(self.inTree) self.mainLayout.addWidget(inGroup) def setupSettings(self): spinBoxLayout = QFormLayout() self.removeOffset = QCheckBox('Remove DC offset') self.removeOffset.setChecked(self.parameters['offset filter']) spinBoxLayout.addRow(self.removeOffset) self.removeSupply = QCheckBox('Remove 50Hz') self.removeSupply.setChecked(self.parameters['supply filter']) spinBoxLayout.addRow(self.removeSupply) ## self.lpfHighcut = QSpinBox() ## self.lpfHighcut.setMaximum(10000) ## self.lpfHighcut.setValue(self.parameters['LPF highcut']) ## spinBoxLayout.addRow('LPF highcut frequency:', self.lpfHighcut) self.bpfLowcut = QSpinBox() self.bpfLowcut.setMaximum(10000) self.bpfLowcut.setValue(self.parameters['BPF lowcut']) spinBoxLayout.addRow('BPF lowcut frequency:', self.bpfLowcut) self.bpfHighcut = QSpinBox() self.bpfHighcut.setMaximum(10000) self.bpfHighcut.setValue(self.parameters['BPF highcut']) spinBoxLayout.addRow('BPF highcut frequency:', self.bpfHighcut) ## self.ArtefactsThreshold = QSpinBox() ## self.ArtefactsThreshold.setMaximum(10000) ## self.ArtefactsThreshold.setValue(self.parameters['art thres']) ## spinBoxLayout.addRow('Artefacts Threshold:', self.ArtefactsThreshold) self.algWindowSize = QSpinBox() self.algWindowSize.setMaximum(10000) self.algWindowSize.setValue(self.parameters['window']) spinBoxLayout.addRow('Window (samples):', self.algWindowSize) self.hmtLargerMean = QDoubleSpinBox() self.hmtLargerMean.setMinimum(0.1) self.hmtLargerMean.setMaximum(10000) self.hmtLargerMean.setValue(self.parameters['hmt larger mean']) spinBoxLayout.addRow('How many times larger than mean:', self.hmtLargerMean) self.prevSeconds = QDoubleSpinBox() self.prevSeconds.setMinimum(0.1) self.prevSeconds.setMaximum(10000) self.prevSeconds.setValue(self.parameters['prev sec']) spinBoxLayout.addRow('Number of previous seconds:', self.prevSeconds) self.hmtLarger = QDoubleSpinBox() self.hmtLarger.setMinimum(0.1) self.hmtLarger.setMaximum(10000) self.hmtLarger.setValue(self.parameters['hmt larger']) spinBoxLayout.addRow('How many times larger than previous:', self.hmtLarger) gBox = QGroupBox('Settings') gBox.setLayout(spinBoxLayout) self.mainLayout.addWidget(gBox) def setupBtnBoxLayout(self): bottomLayout = QHBoxLayout() self.progBar = QProgressBar() self.progBar.setVisible(False) bottomLayout.addWidget(self.progBar) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Close) buttonBox.accepted.connect(self.okBtnBox) buttonBox.rejected.connect(self.close) bottomLayout.addWidget(buttonBox) self.mainLayout.addLayout(bottomLayout) def okBtnBox(self): inStruct = self.inTree.getSelectedStruct() inDataStruct = self.dataManager.getData(inStruct, inv=True) self.progBar.setVisible(True) self.progBar.setValue(0) nProgres = 5 progStep = 100.0 / nProgres progress = 0 wName = list(inDataStruct.keys())[0] gName = list(inDataStruct[wName].keys())[0] ## Input inData = np.copy(inDataStruct[wName][gName]) ## Noises if self.removeOffset.isChecked(): inData = [signal.detrend(data, type='constant') for data in inData] if self.removeSupply.isChecked(): b, a = filterCalc(order=5, bandarr=[48, 52], fs=self.fs, btype='bandstop', ftype='butter') inData = [signal.lfilter(b, a, data) for data in inData] winLen = self.algWindowSize.value() ## ## Artefacts ## lpfHighcut = self.lpfHighcut.value() ## order=5 ## ## b, a = filterCalc(order, [lpfHighcut], self.fs, 'low', 'butter') ## lpfData = [] ## for data in inData: ## newData = signal.lfilter(b, a, data) ## lpfData.append(newData) ## ## ## ## segNmbr = int(np.shape(lpfData)[1]/winLen) ## artefactsThreshold = self.ArtefactsThreshold.value() ## ## lpfWinData = np.copy(lpfData) ## lpfWinData = [np.array_split(ch, segNmbr) for ch in lpfWinData] ## ## for ch in lpfWinData: ## for seg in ch: ## seg.fill(max(seg)- min(seg)) ## progress += progStep self.progBar.setValue(progress) ## #### thresLpfData = np.copy(lpfWinData) ## thresLpfData = deepcopy(lpfWinData) ## ## for x in thresLpfData: ## for y in x: ## if y[0] >= artefactsThreshold: ## y.fill(1) ## else: ## y.fill(0) ## ## lpfWinData = [np.concatenate(ch) for ch in lpfWinData] ## thresLpfData = [np.concatenate(ch) for ch in thresLpfData] ## progress += progStep self.progBar.setValue(progress) ## Spikes bpfLowcut = self.bpfLowcut.value() bpfHighcut = self.bpfHighcut.value() order = 4 b, a = filterCalc(order, [bpfLowcut, bpfHighcut], self.fs, 'band', 'butter') bpfData = [] for data in inData: newData = signal.lfilter(b, a, data) bpfData.append(newData) segNmbr = int(np.shape(bpfData)[1] / winLen) prevSeconds = self.prevSeconds.value() prevWindows = int(prevSeconds * self.fs / winLen) progress += progStep self.progBar.setValue(progress) bpfWinData = np.copy(bpfData) bpfWinData = [np.array_split(ch, segNmbr) for ch in bpfWinData] chi = 0 for ch in bpfWinData: for seg in ch: seg.fill(max(seg) - min(seg)) progress += progStep self.progBar.setValue(progress) hmtLarger = self.hmtLarger.value() hmtLargerMean = self.hmtLargerMean.value() ## thresBpfData = np.copy(bpfWinData) thresBpfData = deepcopy(bpfWinData) for ch in range(len(bpfWinData)): channelMean = self.hmtLargerMean.value() * np.mean(inData[ch]) for i in range(prevWindows, len(bpfWinData[ch])): if bpfWinData[ch][i][0] > channelMean: prev = [ bpfWinData[ch][j][0] for j in range(i - prevWindows, i) ] if bpfWinData[ch][i][0] > hmtLarger * np.mean(prev): thresBpfData[ch][i].fill(1) else: thresBpfData[ch][i].fill(0) else: thresBpfData[ch][i].fill(0) progress += progStep self.progBar.setValue(progress) for ch in thresBpfData: for i in range(prevWindows): ch[i].fill(0) bpfWinData = [np.concatenate(ch) for ch in bpfWinData] thresBpfData = [np.concatenate(ch) for ch in thresBpfData] spikeMap = [np.sum(x) / winLen for x in thresBpfData] nazwaPliku = str(winLen) + '_' + str(prevSeconds) + '_' + str( hmtLarger) + '.csv' with open(nazwaPliku, 'w', encoding='utf-8') as csvfile: csvwriter = csv.writer(csvfile) csvwriter.writerow(spikeMap) ## for ch in spikeMap ## csvwriter.writerow(spikeMap) ## Add data or replace existing swsName = 'Algorithm output' chNames = inStruct[wName][gName] if swsName not in self.dataManager.getDataGroups(): self.dataManager.createDataGroup(swsName, 'Algorithm') self.dataManager.addChannels(swsName, chNames) self.dataManager.addSignal(swsName, 'Input Signal', inData, chNames) ## self.dataManager.addSignal(swsName, 'LPF', lpfData, chNames) ## self.dataManager.addSignal(swsName, 'LPF+Window+Peak-to-peak', lpfWinData, chNames) ## self.dataManager.addSignal(swsName, 'LPF+Threshold - Artefacts', thresLpfData, chNames) self.dataManager.addSignal(swsName, 'BPF', bpfData, chNames) self.dataManager.addSignal(swsName, 'BPF+Window+Peak-to-peak', bpfWinData, chNames) self.dataManager.addSignal(swsName, 'BPF+Threshold - Spikes', thresBpfData, chNames) else: self.dataManager.silentChangeSignal(swsName, 'Input Signal', inData, chNames) ## self.dataManager.silentChangeSignal(swsName, 'LPF', lpfData, chNames) ## self.dataManager.silentChangeSignal(swsName, 'LPF+Window+P2P', lpfWinData, chNames) ## self.dataManager.silentChangeSignal(swsName, 'LPF+Threshold - Artefacts', thresLpfData, chNames) self.dataManager.silentChangeSignal(swsName, 'BPF', bpfData, chNames) self.dataManager.silentChangeSignal(swsName, 'BPF+Window+Peak-to-peak', bpfWinData, chNames) self.dataManager.silentChangeSignal(swsName, 'BPF+Threshold - Spikes', thresBpfData, chNames) self.chartManager.setMask('Algorithm output', 'BPF+Threshold - Spikes') self.chartManager.setMap(spikeMap) self.parameters = { 'offset filter': self.removeOffset.isChecked(), 'supply filter': self.removeSupply.isChecked(), ## 'LPF highcut' : lpfHighcut, 'BPF lowcut': bpfLowcut, 'BPF highcut': bpfHighcut, ## 'art thres' : artefactsThreshold, 'window': winLen, 'prev sec': prevSeconds, 'hmt larger': hmtLarger, 'hmt larger mean': hmtLargerMean, } self.executed.emit(self.parameters, self.inputList)
class MainWindow(QMainWindow): def __init__(self, app, parent=None): super(MainWindow, self).__init__(parent) self.imagesDir = app.dir + '/images/' self.setWindowIcon(QIcon(self.imagesDir + 'icon.png')) self.path = '' self.settings = QSettings() self.lastDir = self.settings.value('lastDir', '') self.setMinimumWidth(540) self.supportedFormats = [] for f in QImageReader.supportedImageFormats(): self.supportedFormats.append(str(f.data(), encoding="utf-8")) self.fileWatcher = QFileSystemWatcher() self.fileWatcher.fileChanged.connect(self.fileChanged) # widgets self.showPixmapWidget = None self.tileWidthSpinBox = QSpinBox() self.tileWidthSpinBox.setValue(16) self.tileWidthSpinBox.setFixedWidth(50) self.tileWidthSpinBox.setMinimum(1) self.tileHeightSpinBox = QSpinBox() self.tileHeightSpinBox.setValue(16) self.tileHeightSpinBox.setFixedWidth(50) self.tileHeightSpinBox.setMinimum(1) self.paddingSpinBox = QSpinBox() self.paddingSpinBox.setFixedWidth(50) self.paddingSpinBox.setMinimum(1) self.transparentCheckbox = QCheckBox("Transparent") self.transparentCheckbox.setChecked(True) self.transparentCheckbox.stateChanged.connect(self.transparentChanged) self.backgroundColorEdit = ColorEdit() self.backgroundColorEdit.setEnabled(False) self.backgroundColorLabel = QLabel("Background color:") self.backgroundColorLabel.setEnabled(False) self.forcePotCheckBox = QCheckBox("Force PoT") self.forcePotCheckBox.setChecked(True) self.forcePotCheckBox.stateChanged.connect(self.forcePotChanged) self.reorderTilesCheckBox = QCheckBox("Reorder tiles") self.generateAndExportButton = QPushButton("Generate and export") self.generateAndExportButton.setFixedHeight(32) self.generateAndExportButton.clicked.connect(self.generateAndExportClicked) self.generateAndExportButton.setEnabled(False) self.pixmapWidget = PixmapWidget() self.pixmapWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.pixmapWidget.setPixmap(self.createDropTextPixmap()) self.pixmapWidget.dropSignal.connect(self.fileDropped) self.pixmapWidget.setMinimumHeight(300) # load settings self.tileWidthSpinBox.setValue(int(self.settings.value('tileWidth', 16))) self.tileHeightSpinBox.setValue(int(self.settings.value('tileHeight', 16))) self.paddingSpinBox.setValue(int(self.settings.value('padding', 1))) self.forcePotCheckBox.setChecked(True if self.settings.value('forcePot', 'true') == 'true' else False) self.reorderTilesCheckBox.setChecked(True if self.settings.value('reorderTiles', 'false') == 'true' else False) self.transparentCheckbox.setChecked(True if self.settings.value('transparent', 'false') == 'true' else False) self.backgroundColorEdit.setColorText(str(self.settings.value('backgroundColor', '#FF00FF'))) self.restoreGeometry(QByteArray(self.settings.value('MainWindow/geometry'))) self.restoreState(QByteArray(self.settings.value('MainWindow/windowState'))) # layout hl1 = QHBoxLayout() hl1.setContentsMargins(5, 5, 5, 5) hl1.addWidget(QLabel("Tile width:")) hl1.addSpacing(5) hl1.addWidget(self.tileWidthSpinBox) hl1.addSpacing(15) hl1.addWidget(QLabel("Tile height:")) hl1.addSpacing(5) hl1.addWidget(self.tileHeightSpinBox) hl1.addSpacing(15) hl1.addWidget(QLabel("Padding:")) hl1.addSpacing(5) hl1.addWidget(self.paddingSpinBox) hl1.addSpacing(15) hl1.addWidget(self.forcePotCheckBox) hl1.addSpacing(15) hl1.addWidget(self.reorderTilesCheckBox) hl1.addStretch() hl2 = QHBoxLayout() hl2.setContentsMargins(5, 5, 5, 5) hl2.addWidget(self.transparentCheckbox) hl2.addSpacing(15) hl2.addWidget(self.backgroundColorLabel) hl2.addSpacing(5) hl2.addWidget(self.backgroundColorEdit) hl2.addStretch() hl3 = QHBoxLayout() hl3.setContentsMargins(5, 5, 5, 5) hl3.addWidget(self.generateAndExportButton) vl = QVBoxLayout() vl.setContentsMargins(0, 0, 0, 0) vl.setSpacing(0) vl.addLayout(hl1) vl.addLayout(hl2) vl.addWidget(self.pixmapWidget) vl.addLayout(hl3) w = QWidget() w.setLayout(vl) self.setCentralWidget(w) self.setTitle() def setTitle(self): p = ' - ' + os.path.basename(self.path) if self.path else '' self.setWindowTitle(QCoreApplication.applicationName() + ' ' + QCoreApplication.applicationVersion() + p) def createDropTextPixmap(self): pixmap = QPixmap(481, 300) pixmap.fill(QColor("#333333")) painter = QPainter(pixmap) font = QFont("Arial") font.setPixelSize(28) font.setBold(True) fm = QFontMetrics(font) painter.setFont(font) painter.setPen(QPen(QColor("#888888"), 1)) text = "Drop the tileset image here" x = (pixmap.width()-fm.width(text))/2 y = (pixmap.height()+fm.height())/2 painter.drawText(x, y, text) del painter return pixmap def fileDropped(self, path): path = str(path) name, ext = os.path.splitext(path) ext = ext[1:] if not ext in self.supportedFormats: QMessageBox.warning(self, "Warning", "The dropped file is not supported") return pixmap = QPixmap(path) if pixmap.isNull(): QMessageBox.warning(self, "Warning", "Can't load the image") return if self.path: self.fileWatcher.removePath(self.path) self.path = path self.fileWatcher.addPath(self.path) self.pixmapWidget.setPixmap(pixmap) self.generateAndExportButton.setEnabled(True) self.setTitle() self.activateWindow() def fileChanged(self, path): #self.fileDropped(path) pass def transparentChanged(self): e = self.transparentCheckbox.isChecked() self.backgroundColorEdit.setEnabled(not e) self.backgroundColorLabel.setEnabled(not e) def forcePotChanged(self): e = self.forcePotCheckBox.isChecked() self.reorderTilesCheckBox.setEnabled(e) def generateAndExportClicked(self): g = Generator() g.tileWidth = self.tileWidthSpinBox.value() g.tileHeight = self.tileHeightSpinBox.value() g.forcePot = self.forcePotCheckBox.isChecked() g.isTransparent = self.transparentCheckbox.isChecked() g.bgColor = self.backgroundColorEdit.getColor() g.reorder = self.reorderTilesCheckBox.isChecked() g.padding = self.paddingSpinBox.value() target = g.create(self.pixmapWidget.pixmap); # export self.lastDir = os.path.dirname(self.path) targetPath = QFileDialog.getSaveFileName(self, 'Export', self.lastDir, 'PNG (*.png)') if targetPath: target.save(targetPath[0]) showPixmap = QPixmap.fromImage(target) if self.showPixmapWidget: self.showPixmapWidget.deleteLater() del self.showPixmapWidget self.showPixmapWidget = PixmapWidget() self.showPixmapWidget.setWindowIcon(self.windowIcon()) self.showPixmapWidget.setWindowTitle(os.path.basename(targetPath[0])) self.showPixmapWidget.resize(showPixmap.width(), showPixmap.height()) self.showPixmapWidget.setPixmap(showPixmap) self.showPixmapWidget.show() def closeEvent(self, event): if self.showPixmapWidget: self.showPixmapWidget.close() # save settings self.settings.setValue('tileWidth', self.tileWidthSpinBox.value()) self.settings.setValue('tileHeight', self.tileHeightSpinBox.value()) self.settings.setValue('padding', self.paddingSpinBox.value()) self.settings.setValue('forcePot', self.forcePotCheckBox.isChecked()) self.settings.setValue('reorderTiles', self.reorderTilesCheckBox.isChecked()) self.settings.setValue('transparent', self.transparentCheckbox.isChecked()) self.settings.setValue('backgroundColor', self.backgroundColorEdit.getColor().name()) self.settings.setValue('lastDir', self.lastDir) self.settings.setValue('MainWindow/geometry', self.saveGeometry()) self.settings.setValue('MainWindow/windowState', self.saveState()) super(MainWindow, self).closeEvent(event)