def initMainUi(self): role_names = self.parentApplet.dataSelectionApplet.topLevelOperator.DatasetRoles.value self.list_widgets = [] # Create a tab for each role for role_index, role_name in enumerate(role_names): select_button = QPushButton("Select " + role_name + " Files...", clicked=partial(self.select_files, role_index) ) clear_button = QPushButton("Clear " + role_name + " Files", clicked=partial(self.clear_files, role_index) ) button_layout = QHBoxLayout() button_layout.addWidget(select_button) button_layout.addSpacerItem( QSpacerItem(0,0,hPolicy=QSizePolicy.Expanding) ) button_layout.addWidget(clear_button) button_layout.setContentsMargins(0, 0, 0, 0) button_layout_widget = QWidget() button_layout_widget.setLayout(button_layout) button_layout_widget.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) ) list_widget = QListWidget(parent=self) list_widget.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) ) self.list_widgets.append( list_widget ) tab_layout = QVBoxLayout() tab_layout.setContentsMargins(0, 0, 0, 0) tab_layout.addWidget( button_layout_widget ) tab_layout.addWidget( list_widget ) layout_widget = QWidget(parent=self) layout_widget.setLayout(tab_layout) self.addTab(layout_widget, role_name)
def initMainUi(self): role_names = self.parentApplet.dataSelectionApplet.topLevelOperator.DatasetRoles.value self.list_widgets = [] # Create a tab for each role for role_index, role_name in enumerate(role_names): select_button = QPushButton("Select " + role_name + " Files...", clicked=partial( self.select_files, role_index)) clear_button = QPushButton("Clear " + role_name + " Files", clicked=partial(self.clear_files, role_index)) button_layout = QHBoxLayout() button_layout.addWidget(select_button) button_layout.addSpacerItem( QSpacerItem(0, 0, hPolicy=QSizePolicy.Expanding)) button_layout.addWidget(clear_button) button_layout.setContentsMargins(0, 0, 0, 0) button_layout_widget = QWidget() button_layout_widget.setLayout(button_layout) button_layout_widget.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)) list_widget = QListWidget(parent=self) list_widget.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) self.list_widgets.append(list_widget) tab_layout = QVBoxLayout() tab_layout.setContentsMargins(0, 0, 0, 0) tab_layout.addWidget(button_layout_widget) tab_layout.addWidget(list_widget) layout_widget = QWidget(parent=self) layout_widget.setLayout(tab_layout) self.addTab(layout_widget, role_name)
def _init_layout(self): """ Create the GUI widgets (but leave them empty). """ hostname_combobox = QComboBox(parent=self) self._hostname_combobox = hostname_combobox hostname_combobox.setEditable(True) hostname_combobox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) for hostname in self._suggested_hostnames: hostname_combobox.addItem(hostname) # EventFilter is installed after everything else is initialized. (See below.) #hostname_combobox.installEventFilter(self) self._connect_button = QPushButton("Connect", parent=self, clicked=self._handle_new_hostname) hostname_layout = QHBoxLayout() hostname_layout.addWidget(hostname_combobox) hostname_layout.addWidget(self._connect_button) hostinfo_table = QTableWidget() hostinfo_table.setColumnCount(len(SERVER_INFO_FIELDS)) hostinfo_table.setHorizontalHeaderLabels(SERVER_INFO_FIELDS) hostinfo_table.horizontalHeader().setVisible(True) hostinfo_table.verticalHeader().setVisible(False) hostinfo_table.setRowCount(1) hostinfo_table.setItem(0, 0, QTableWidgetItem("Placeholder")) hostinfo_table.setVisible(False) hostinfo_table.resizeRowsToContents() hostinfo_table.horizontalHeader().setStretchLastSection(True) table_height = hostinfo_table.verticalHeader().sectionSize( 0) + hostinfo_table.rowHeight(0) hostinfo_table.resize(QSize(hostinfo_table.width(), table_height)) hostinfo_table.setMaximumSize(QSize(1000, table_height)) hostinfo_table.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) host_layout = QVBoxLayout() host_layout.addLayout(hostname_layout) host_layout.addWidget(hostinfo_table) host_groupbox = QGroupBox("DVID Host", parent=self) host_groupbox.setLayout(host_layout) host_groupbox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) repo_treewidget = QTreeWidget(parent=self) repo_treewidget.setHeaderLabels( TREEVIEW_COLUMNS) # TODO: Add type, shape, axes, etc. repo_treewidget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) repo_treewidget.itemSelectionChanged.connect( self._handle_data_selection) data_layout = QVBoxLayout() data_layout.addWidget(repo_treewidget) data_groupbox = QGroupBox("Data Volumes", parent=self) data_groupbox.setLayout(data_layout) node_listwidget = QListWidget(parent=self) node_listwidget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) node_listwidget.itemSelectionChanged.connect(self._update_status) node_layout = QVBoxLayout() node_layout.addWidget(node_listwidget) node_groupbox = QGroupBox("Nodes", parent=self) node_groupbox.setLayout(node_layout) new_data_edit = QLineEdit(parent=self) new_data_edit.textEdited.connect(self._update_status) full_url_label = QLabel(parent=self) full_url_label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) text_flags = full_url_label.textInteractionFlags() full_url_label.setTextInteractionFlags(text_flags | Qt.TextSelectableByMouse) new_data_layout = QVBoxLayout() new_data_layout.addWidget(new_data_edit) new_data_groupbox = QGroupBox("New Data Volume", parent=self) new_data_groupbox.setLayout(new_data_layout) new_data_groupbox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) buttonbox = QDialogButtonBox(Qt.Horizontal, parent=self) buttonbox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonbox.accepted.connect(self.accept) buttonbox.rejected.connect(self.reject) buttonbox.button(QDialogButtonBox.Ok).setEnabled(False) layout = QVBoxLayout() layout.addWidget(host_groupbox) layout.addWidget(data_groupbox) layout.addWidget(node_groupbox) if self._mode == "specify_new": layout.addWidget(new_data_groupbox) else: new_data_groupbox.hide() layout.addWidget(full_url_label) layout.addWidget(buttonbox) # Stretch factors layout.setStretchFactor(data_groupbox, 3) layout.setStretchFactor(node_groupbox, 1) self.setLayout(layout) self.setWindowTitle("Select DVID Volume") self.resize(1000, 1000) # Initially disabled data_groupbox.setEnabled(False) node_groupbox.setEnabled(False) new_data_groupbox.setEnabled(False) # Set tab order self.setTabOrder(hostname_combobox, repo_treewidget) self.setTabOrder(repo_treewidget, node_listwidget) self.setTabOrder(node_listwidget, buttonbox) # Save instance members self._hostinfo_table = hostinfo_table self._data_groupbox = data_groupbox self._node_groupbox = node_groupbox self._new_data_groupbox = new_data_groupbox self._repo_treewidget = repo_treewidget self._node_listwidget = node_listwidget self._new_data_edit = new_data_edit self._full_url_label = full_url_label self._buttonbox = buttonbox # Finally install eventfilter (after everything is initialized) hostname_combobox.installEventFilter(self)
class GroupSelectParameterWidget(GenericParameterWidget): """Widget class for Group Select Parameter.""" def __init__(self, parameter, parent=None): """Constructor. :param parameter: A GroupSelectParameter object. :type parameter: GroupSelectParameter """ QWidget.__init__(self, parent) self._parameter = parameter # Store spin box self.spin_boxes = {} # Create elements # Label (name) self.label = QLabel(self._parameter.name) # Layouts self.main_layout = QVBoxLayout() self.input_layout = QVBoxLayout() # _inner_input_layout must be filled with widget in the child class self.inner_input_layout = QVBoxLayout() self.radio_button_layout = QGridLayout() # Create radio button group self.input_button_group = QButtonGroup() # List widget self.list_widget = QListWidget() self.list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection) self.list_widget.setDragDropMode(QAbstractItemView.DragDrop) self.list_widget.setDefaultDropAction(Qt.MoveAction) self.list_widget.setEnabled(False) self.list_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding) for i, key in enumerate(self._parameter.options): value = self._parameter.options[key] radio_button = QRadioButton(value.get('label')) self.radio_button_layout.addWidget(radio_button, i, 0) if value.get('type') == SINGLE_DYNAMIC: double_spin_box = QDoubleSpinBox() self.radio_button_layout.addWidget(double_spin_box, i, 1) double_spin_box.setValue(value.get('value', 0)) double_spin_box.setMinimum( value.get('constraint', {}).get('min', 0)) double_spin_box.setMaximum( value.get('constraint', {}).get('max', 1)) double_spin_box.setSingleStep( value.get('constraint', {}).get('step', 0.01)) step = double_spin_box.singleStep() if step > 1: precision = 0 else: precision = len(str(step).split('.')[1]) if precision > 3: precision = 3 double_spin_box.setDecimals(precision) self.spin_boxes[key] = double_spin_box # Enable spin box depends on the selected option if self._parameter.selected == key: double_spin_box.setEnabled(True) else: double_spin_box.setEnabled(False) elif value.get('type') == STATIC: static_value = value.get('value', 0) if static_value is not None: self.radio_button_layout.addWidget( QLabel(str(static_value)), i, 1) elif value.get('type') == MULTIPLE_DYNAMIC: selected_fields = value.get('value', []) if self._parameter.selected == key: self.list_widget.setEnabled(True) else: self.list_widget.setEnabled(False) self.input_button_group.addButton(radio_button, i) if self._parameter.selected == key: radio_button.setChecked(True) # Help text self.help_label = QLabel(self._parameter.help_text) self.help_label.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding) self.help_label.setWordWrap(True) self.help_label.setAlignment(Qt.AlignTop) self.inner_input_layout.addLayout(self.radio_button_layout) self.inner_input_layout.addWidget(self.list_widget) # Put elements into layouts self.input_layout.addWidget(self.label) self.input_layout.addLayout(self.inner_input_layout) self.help_layout = QVBoxLayout() self.help_layout.addWidget(self.help_label) self.main_layout.addLayout(self.input_layout) self.main_layout.addLayout(self.help_layout) self.setLayout(self.main_layout) self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding) # Update list widget self.update_list_widget() # Connect signal self.input_button_group.buttonClicked.connect( self.radio_buttons_clicked) def get_parameter(self): """Obtain list parameter object from the current widget state. :returns: A DefaultValueParameter from the current state of widget :rtype: DefaultValueParameter """ # Set value for each key for key, value in self._parameter.options.items(): if value.get('type') == STATIC: continue elif value.get('type') == SINGLE_DYNAMIC: new_value = self.spin_boxes.get(key).value() self._parameter.set_value_for_key(key, new_value) elif value.get('type') == MULTIPLE_DYNAMIC: # Need to iterate through all items items = [] for index in xrange(self.list_widget.count()): items.append(self.list_widget.item(index)) new_value = [i.text() for i in items] self._parameter.set_value_for_key(key, new_value) # Get selected radio button radio_button_checked_id = self.input_button_group.checkedId() # No radio button checked, then default value = None if radio_button_checked_id == -1: self._parameter.selected = None else: self._parameter.selected = self._parameter.options.keys( )[radio_button_checked_id] return self._parameter def update_list_widget(self): """Update list widget when radio button is clicked.""" # Get selected radio button radio_button_checked_id = self.input_button_group.checkedId() # No radio button checked, then default value = None if radio_button_checked_id > -1: selected_dict = self._parameter.options.values( )[radio_button_checked_id] if selected_dict.get('type') == MULTIPLE_DYNAMIC: for field in selected_dict.get('value'): # Update list widget field_item = QListWidgetItem(self.list_widget) field_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled) field_item.setData(Qt.UserRole, field) field_item.setText(field) self.list_widget.addItem(field_item) def radio_buttons_clicked(self): """Handler when selected radio button changed.""" # Disable all spin boxes for spin_box in self.spin_boxes.values(): spin_box.setEnabled(False) # Disable list widget self.list_widget.setEnabled(False) # Get selected radio button radio_button_checked_id = self.input_button_group.checkedId() if radio_button_checked_id > -1: selected_value = self._parameter.options.values( )[radio_button_checked_id] if selected_value.get('type') == MULTIPLE_DYNAMIC: # Enable list widget self.list_widget.setEnabled(True) elif selected_value.get('type') == SINGLE_DYNAMIC: selected_key = self._parameter.options.keys( )[radio_button_checked_id] self.spin_boxes[selected_key].setEnabled(True) def select_radio_button(self, key): """Helper to select a radio button with key. :param key: The key of the radio button. :type key: str """ key_index = self._parameter.options.keys().index(key) radio_button = self.input_button_group.button(key_index) radio_button.click()
def __init__(self, callback): super().__init__() self.callback = callback self.setMinimumSize(QSize(210, 200)) self.setMaximumSize(QSize(210, 16777215)) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self.lockresource = False numbervalidator = QIntValidator(0, 999) #Rom info and emulator emulator = QPushButton("Start Emulator", self) #Map/bank select buttons column_left_layout = QVBoxLayout(self) column_left_layout.setContentsMargins(0, 0, 0, 0) column_left_layout.setSpacing(2) mapinput_l = QLabel('Map:', self) mapinput_f = QLineEdit(self) mapinput_f.setValidator(numbervalidator) bankinput_l = QLabel('Bank:', self) bankinput_f = QLineEdit(self) bankinput_f.setValidator(numbervalidator) button_load = QPushButton(self) button_load.setText("Load scripts") #Select element on the map view select_script = QTreeWidget(self) select_script.setColumnCount(2) select_script.setHeaderHidden(True) select_script.header().resizeSection(0, 160) select_script.header().resizeSection(1, 20) select_script.setStyleSheet("outline: 0;") select_script.setFocusPolicy(Qt.NoFocus) select_script.setSelectionMode(QAbstractItemView.ExtendedSelection) resources_l = QLabel("Script resources:", self) resourceselector = QListWidget(self) resourceselector.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) column_left_layout.addWidget(emulator) column_left_layout.addWidget(bankinput_l) column_left_layout.addWidget(bankinput_f) column_left_layout.addWidget(mapinput_l) column_left_layout.addWidget(mapinput_f) column_left_layout.addWidget(button_load) column_left_layout.addWidget(select_script) column_left_layout.addWidget(resources_l) column_left_layout.addWidget(resourceselector) #Finally connect proper signals button_load.clicked.connect(self.maploadclick) select_script.itemSelectionChanged.connect(self.itemselected) resourceselector.itemSelectionChanged.connect(self.resourceselected) emulator.clicked.connect(self.emulate) #Keep some elements for local thingy self.mapinput = mapinput_f self.bankinput = bankinput_f self.scriptselect = select_script self.resourceselector = resourceselector
class FieldMappingTab(QWidget, object): """Widget class for field mapping.""" def __init__(self, field_group=None, parent=None, iface=None): """Constructor.""" # Init from parent class QWidget.__init__(self, parent) # Attributes self.layer = None self.metadata = {} self.parent = parent self.iface = iface self.field_group = field_group self.setting = QSettings() # TODO(IS): Make dynamic # Main container self.main_layout = QVBoxLayout() # Inner layout self.header_layout = QHBoxLayout() self.content_layout = QHBoxLayout() self.footer_layout = QHBoxLayout() # Header self.header_label = QLabel() self.header_label.setWordWrap(True) # Content self.field_layout = QVBoxLayout() self.parameter_layout = QHBoxLayout() self.field_description = QLabel(tr('List of fields')) self.field_list = QListWidget() self.field_list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.field_list.setDragDropMode(QAbstractItemView.DragDrop) self.field_list.setDefaultDropAction(Qt.MoveAction) self.field_list.setSizePolicy( QSizePolicy.Maximum, QSizePolicy.Expanding) # noinspection PyUnresolvedReferences self.field_list.itemSelectionChanged.connect(self.update_footer) # Footer self.footer_label = QLabel() # Parameters self.extra_parameters = [ (GroupSelectParameter, GroupSelectParameterWidget) ] self.parameters = [] self.parameter_container = None # Adding to layout self.header_layout.addWidget(self.header_label) self.field_layout.addWidget(self.field_description) self.field_layout.addWidget(self.field_list) self.field_layout.setSizeConstraint(QLayout.SetMaximumSize) self.content_layout.addLayout(self.field_layout) self.content_layout.addLayout(self.parameter_layout) self.footer_layout.addWidget(self.footer_label) self.main_layout.addLayout(self.header_layout) self.main_layout.addLayout(self.content_layout) self.main_layout.addLayout(self.footer_layout) self.setLayout(self.main_layout) def set_layer(self, layer, keywords=None): """Set layer and update UI accordingly. :param layer: A vector layer that has been already patched with metadata. :type layer: QgsVectorLayer :param keywords: Custom keyword for the layer. :type keywords: dict, None """ self.layer = layer if keywords is not None: self.metadata = keywords else: # Check if it has keywords if not hasattr(layer, 'keywords'): message = 'Layer {layer_name} does not have keywords.'.format( layer_name=layer.name()) raise KeywordNotFoundError(message) self.metadata = layer.keywords self.populate_parameter() def populate_field_list(self, excluded_fields=None): """Helper to add field of the layer to the list. :param excluded_fields: List of field that want to be excluded. :type excluded_fields: list """ # Populate fields list if excluded_fields is None: excluded_fields = [] self.field_list.clear() for field in self.layer.dataProvider().fields(): # Skip if it's excluded if field.name() in excluded_fields: continue # Skip if it's not number (float, int, etc) if field.type() not in qvariant_numbers: continue field_item = QListWidgetItem(self.field_list) field_item.setFlags( Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled) field_item.setData(Qt.UserRole, field.name()) field_item.setText(field.name()) self.field_list.addItem(field_item) def populate_parameter(self): """Helper to setup the parameter widget.""" used_fields = [] self.parameters = [] for field in self.field_group.get('fields', []): selected_option = DO_NOT_USE options = OrderedDict([ (DO_NOT_USE, { 'label': tr('Do not use'), 'value': None, 'type': STATIC, 'constraint': {} }), ]) # Example: count if field['absolute']: # Used in field options field_label = tr('Count fields') else: # Example: ratio # Used in field options field_label = tr('Ratio fields') global_default_value = get_inasafe_default_value_qsetting( self.setting, GLOBAL, field['key']) options[GLOBAL_DEFAULT] = { 'label': tr('Global default'), 'value': global_default_value, 'type': STATIC, 'constraint': {} } default_custom_value = get_inasafe_default_value_qsetting( self.setting, RECENT, field['key']) custom_value = self.metadata.get( 'inasafe_default_values', {}).get( field['key'], default_custom_value) if field['key'] in self.metadata.get( 'inasafe_default_values', {}): if custom_value == global_default_value: selected_option = GLOBAL_DEFAULT else: selected_option = CUSTOM_VALUE min_value = field['default_value'].get('min_value', 0) max_value = field['default_value'].get('max_value', 100) default_step = (max_value - min_value) / 100.0 step = field['default_value'].get('increment', default_step) options[CUSTOM_VALUE] = { 'label': tr('Custom'), 'value': custom_value, 'type': SINGLE_DYNAMIC, 'constraint': { 'min': min_value, 'max': max_value, 'step': step } } custom_fields = self.metadata.get('inasafe_fields', {}).get( field['key'], []) if field['key'] in self.metadata.get('inasafe_fields', {}): selected_option = FIELDS if isinstance(custom_fields, basestring): custom_fields = [custom_fields] options[FIELDS] = { 'label': field_label, 'value': custom_fields, 'type': MULTIPLE_DYNAMIC, 'constraint': {} } used_fields.extend(custom_fields) parameter = GroupSelectParameter() parameter.guid = field['key'] parameter.name = field['name'] parameter.options = options parameter.selected = selected_option parameter.help_text = field['help_text'] parameter.description = field['description'] self.parameters.append(parameter) self.parameter_container = ParameterContainer( parameters=self.parameters, extra_parameters=self.extra_parameters, vertical=False ) self.parameter_container.setup_ui() constraints = self.field_group.get('constraints', {}) for key, value in constraints.items(): self.parameter_container.add_validator( validators[key], kwargs=value['kwargs'], validation_message=value['message']) self.parameter_layout.addWidget(self.parameter_container) # Set move or copy if self.field_group.get('exclusive', False): # If exclusive, do not add used field. self.populate_field_list(excluded_fields=used_fields) # Use move action since it's exclusive self.field_list.setDefaultDropAction(Qt.MoveAction) # Just make sure that the signal is disconnected try: # noinspection PyUnresolvedReferences self.field_list.itemChanged.disconnect(self.drop_remove) except TypeError: pass # Set header header_text = self.field_group['description'] header_text += '\n\n' + tr( 'You can only map one field to one concept.') else: # If not exclusive, add all field. self.populate_field_list() # Use copy action since it's not exclusive self.field_list.setDefaultDropAction(Qt.CopyAction) # noinspection PyUnresolvedReferences self.field_list.itemChanged.connect( partial(self.drop_remove, field_list=self.field_list)) self.connect_drop_remove_parameter() # Set header header_text = self.field_group['description'] header_text += '\n\n' + tr( 'You can map one field to more than one concepts.') self.header_label.setText(header_text) def get_parameter_value(self): """Get parameter of the tab. :returns: Dictionary of parameters by type in this format: {'fields': {}, 'values': {}}. :rtype: dict """ try: parameters = self.parameter_container.get_parameters(True) except InvalidValidationException as e: raise OriginalValidationException(e) field_parameters = {} value_parameters = {} for parameter in parameters: if parameter.selected_option_type() in [SINGLE_DYNAMIC, STATIC]: value_parameters[parameter.guid] = parameter.value elif parameter.selected_option_type() == MULTIPLE_DYNAMIC: field_parameters[parameter.guid] = parameter.value return { 'fields': field_parameters, 'values': value_parameters } def update_footer(self): """Update footer when the field list change.""" field_item = self.field_list.currentItem() if not field_item: self.footer_label.setText('') return field_name = field_item.data(Qt.UserRole) field = self.layer.fields().field(field_name) index = self.layer.fieldNameIndex(field_name) unique_values = self.layer.uniqueValues(index) pretty_unique_values = ', '.join([str(v) for v in unique_values[:10]]) footer_text = tr('Field type: {0}\n').format(field.typeName()) footer_text += tr('Unique values: {0}').format(pretty_unique_values) self.footer_label.setText(footer_text) def connect_drop_remove_parameter(self): parameter_widgets = self.parameter_container.get_parameter_widgets() for parameter_widget in parameter_widgets: field_list = parameter_widget.widget().list_widget field_list.itemChanged.connect( partial(self.drop_remove, field_list=field_list)) @staticmethod def drop_remove(*args, **kwargs): """Action when we need to remove dropped item. :param args: Position arguments. :type args: list :param kwargs: Keywords arguments. :type kwargs: dict """ dropped_item = args[0] field_list = kwargs['field_list'] num_duplicate = 0 for i in range(field_list.count()): if dropped_item.text() == field_list.item(i).text(): num_duplicate += 1 if num_duplicate > 1: # Notes(IS): For some reason, removeItemWidget is not working. field_list.takeItem(field_list.row(dropped_item))
class GroupSelectParameterWidget(GenericParameterWidget): """Widget class for Group Select Parameter.""" def __init__(self, parameter, parent=None): """Constructor. :param parameter: A GroupSelectParameter object. :type parameter: GroupSelectParameter """ QWidget.__init__(self, parent) self._parameter = parameter # Store spin box self.spin_boxes = {} # Create elements # Label (name) self.label = QLabel(self._parameter.name) # Layouts self.main_layout = QVBoxLayout() self.input_layout = QVBoxLayout() # _inner_input_layout must be filled with widget in the child class self.inner_input_layout = QVBoxLayout() self.radio_button_layout = QGridLayout() # Create radio button group self.input_button_group = QButtonGroup() # List widget self.list_widget = QListWidget() self.list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection) self.list_widget.setDragDropMode(QAbstractItemView.DragDrop) self.list_widget.setDefaultDropAction(Qt.MoveAction) self.list_widget.setEnabled(False) self.list_widget.setSizePolicy( QSizePolicy.Maximum, QSizePolicy.Expanding) for i, key in enumerate(self._parameter.options): value = self._parameter.options[key] radio_button = QRadioButton(value.get('label')) self.radio_button_layout.addWidget(radio_button, i, 0) if value.get('type') == SINGLE_DYNAMIC: double_spin_box = QDoubleSpinBox() self.radio_button_layout.addWidget(double_spin_box, i, 1) double_spin_box.setValue(value.get('value', 0)) double_spin_box.setMinimum( value.get('constraint', {}).get('min', 0)) double_spin_box.setMaximum(value.get( 'constraint', {}).get('max', 1)) double_spin_box.setSingleStep( value.get('constraint', {}).get('step', 0.01)) step = double_spin_box.singleStep() if step > 1: precision = 0 else: precision = len(str(step).split('.')[1]) if precision > 3: precision = 3 double_spin_box.setDecimals(precision) self.spin_boxes[key] = double_spin_box # Enable spin box depends on the selected option if self._parameter.selected == key: double_spin_box.setEnabled(True) else: double_spin_box.setEnabled(False) elif value.get('type') == STATIC: static_value = value.get('value', 0) if static_value is not None: self.radio_button_layout.addWidget( QLabel(str(static_value)), i, 1) elif value.get('type') == MULTIPLE_DYNAMIC: selected_fields = value.get('value', []) if self._parameter.selected == key: self.list_widget.setEnabled(True) else: self.list_widget.setEnabled(False) self.input_button_group.addButton(radio_button, i) if self._parameter.selected == key: radio_button.setChecked(True) # Help text self.help_label = QLabel(self._parameter.help_text) self.help_label.setSizePolicy( QSizePolicy.Maximum, QSizePolicy.Expanding) self.help_label.setWordWrap(True) self.help_label.setAlignment(Qt.AlignTop) self.inner_input_layout.addLayout(self.radio_button_layout) self.inner_input_layout.addWidget(self.list_widget) # Put elements into layouts self.input_layout.addWidget(self.label) self.input_layout.addLayout(self.inner_input_layout) self.help_layout = QVBoxLayout() self.help_layout.addWidget(self.help_label) self.main_layout.addLayout(self.input_layout) self.main_layout.addLayout(self.help_layout) self.setLayout(self.main_layout) self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding) # Update list widget self.update_list_widget() # Connect signal self.input_button_group.buttonClicked.connect( self.radio_buttons_clicked) def get_parameter(self): """Obtain list parameter object from the current widget state. :returns: A DefaultValueParameter from the current state of widget :rtype: DefaultValueParameter """ # Set value for each key for key, value in self._parameter.options.items(): if value.get('type') == STATIC: continue elif value.get('type') == SINGLE_DYNAMIC: new_value = self.spin_boxes.get(key).value() self._parameter.set_value_for_key(key, new_value) elif value.get('type') == MULTIPLE_DYNAMIC: # Need to iterate through all items items = [] for index in xrange(self.list_widget.count()): items.append(self.list_widget.item(index)) new_value = [i.text() for i in items] self._parameter.set_value_for_key(key, new_value) # Get selected radio button radio_button_checked_id = self.input_button_group.checkedId() # No radio button checked, then default value = None if radio_button_checked_id == -1: self._parameter.selected = None else: self._parameter.selected = self._parameter.options.keys()[ radio_button_checked_id] return self._parameter def update_list_widget(self): """Update list widget when radio button is clicked.""" # Get selected radio button radio_button_checked_id = self.input_button_group.checkedId() # No radio button checked, then default value = None if radio_button_checked_id > -1: selected_dict = self._parameter.options.values()[ radio_button_checked_id] if selected_dict.get('type') == MULTIPLE_DYNAMIC: for field in selected_dict.get('value'): # Update list widget field_item = QListWidgetItem(self.list_widget) field_item.setFlags( Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled) field_item.setData(Qt.UserRole, field) field_item.setText(field) self.list_widget.addItem(field_item) def radio_buttons_clicked(self): """Handler when selected radio button changed.""" # Disable all spin boxes for spin_box in self.spin_boxes.values(): spin_box.setEnabled(False) # Disable list widget self.list_widget.setEnabled(False) # Get selected radio button radio_button_checked_id = self.input_button_group.checkedId() if radio_button_checked_id > -1: selected_value = self._parameter.options.values()[ radio_button_checked_id] if selected_value.get('type') == MULTIPLE_DYNAMIC: # Enable list widget self.list_widget.setEnabled(True) elif selected_value.get('type') == SINGLE_DYNAMIC: selected_key = self._parameter.options.keys()[ radio_button_checked_id] self.spin_boxes[selected_key].setEnabled(True) def select_radio_button(self, key): """Helper to select a radio button with key. :param key: The key of the radio button. :type key: str """ key_index = self._parameter.options.keys().index(key) radio_button = self.input_button_group.button(key_index) radio_button.click()
def __init__(self, callback): super().__init__() self.callback = callback self.setMinimumSize(QSize(210, 200)) self.setMaximumSize(QSize(210, 16777215)) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self.lockresource = False numbervalidator = QIntValidator(0, 999) #Rom info and emulator emulator = QPushButton("Start Emulator", self) #Map/bank select buttons column_left_layout = QVBoxLayout(self) column_left_layout.setContentsMargins(0, 0, 0, 0); column_left_layout.setSpacing(2) mapinput_l = QLabel('Map:', self) mapinput_f = QLineEdit(self) mapinput_f.setValidator(numbervalidator) bankinput_l = QLabel('Bank:', self) bankinput_f = QLineEdit(self) bankinput_f.setValidator(numbervalidator) button_load = QPushButton(self) button_load.setText("Load scripts") #Select element on the map view select_script = QTreeWidget(self) select_script.setColumnCount(2) select_script.setHeaderHidden(True) select_script.header().resizeSection(0, 160) select_script.header().resizeSection(1, 20) select_script.setStyleSheet("outline: 0;") select_script.setFocusPolicy(Qt.NoFocus) select_script.setSelectionMode(QAbstractItemView.ExtendedSelection) resources_l = QLabel("Script resources:", self) resourceselector = QListWidget(self) resourceselector.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) column_left_layout.addWidget(emulator) column_left_layout.addWidget(bankinput_l) column_left_layout.addWidget(bankinput_f) column_left_layout.addWidget(mapinput_l) column_left_layout.addWidget(mapinput_f) column_left_layout.addWidget(button_load) column_left_layout.addWidget(select_script) column_left_layout.addWidget(resources_l) column_left_layout.addWidget(resourceselector) #Finally connect proper signals button_load.clicked.connect(self.maploadclick) select_script.itemSelectionChanged.connect(self.itemselected) resourceselector.itemSelectionChanged.connect(self.resourceselected) emulator.clicked.connect(self.emulate) #Keep some elements for local thingy self.mapinput = mapinput_f self.bankinput = bankinput_f self.scriptselect = select_script self.resourceselector = resourceselector
def _init_layout(self): """ Create the GUI widgets (but leave them empty). """ hostname_combobox = QComboBox(parent=self) self._hostname_combobox = hostname_combobox hostname_combobox.setEditable(True) hostname_combobox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) hostname_combobox.installEventFilter(self) for hostname in self._suggested_hostnames: hostname_combobox.addItem(hostname) self._connect_button = QPushButton("Connect", parent=self, clicked=self._handle_new_hostname) hostname_layout = QHBoxLayout() hostname_layout.addWidget(hostname_combobox) hostname_layout.addWidget(self._connect_button) hostname_groupbox = QGroupBox("DVID Host", parent=self) hostname_groupbox.setLayout(hostname_layout) hostname_groupbox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) data_treewidget = QTreeWidget(parent=self) data_treewidget.setHeaderLabels( ["Data"]) # TODO: Add type, shape, axes, etc. data_treewidget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) data_treewidget.itemSelectionChanged.connect( self._handle_data_selection) data_layout = QVBoxLayout() data_layout.addWidget(data_treewidget) data_groupbox = QGroupBox("Data Volumes", parent=self) data_groupbox.setLayout(data_layout) node_listwidget = QListWidget(parent=self) node_listwidget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) node_listwidget.itemSelectionChanged.connect(self._update_display) node_layout = QVBoxLayout() node_layout.addWidget(node_listwidget) node_groupbox = QGroupBox("Nodes", parent=self) node_groupbox.setLayout(node_layout) new_data_edit = QLineEdit(parent=self) new_data_edit.textEdited.connect(self._update_display) full_url_label = QLabel(parent=self) full_url_label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) text_flags = full_url_label.textInteractionFlags() full_url_label.setTextInteractionFlags(text_flags | Qt.TextSelectableByMouse) new_data_layout = QVBoxLayout() new_data_layout.addWidget(new_data_edit) new_data_groupbox = QGroupBox("New Data Volume", parent=self) new_data_groupbox.setLayout(new_data_layout) new_data_groupbox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) buttonbox = QDialogButtonBox(Qt.Horizontal, parent=self) buttonbox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonbox.accepted.connect(self.accept) buttonbox.rejected.connect(self.reject) buttonbox.button(QDialogButtonBox.Ok).setEnabled(False) layout = QVBoxLayout() layout.addWidget(hostname_groupbox) layout.addWidget(data_groupbox) layout.addWidget(node_groupbox) if self._mode == "specify_new": layout.addWidget(new_data_groupbox) else: new_data_groupbox.hide() layout.addWidget(full_url_label) layout.addWidget(buttonbox) # Stretch factors layout.setStretchFactor(data_groupbox, 3) layout.setStretchFactor(node_groupbox, 1) self.setLayout(layout) self.setWindowTitle("Select DVID Volume") # Initially disabled data_groupbox.setEnabled(False) node_groupbox.setEnabled(False) new_data_groupbox.setEnabled(False) # Save instance members self._data_groupbox = data_groupbox self._node_groupbox = node_groupbox self._new_data_groupbox = new_data_groupbox self._data_treewidget = data_treewidget self._node_listwidget = node_listwidget self._new_data_edit = new_data_edit self._full_url_label = full_url_label self._buttonbox = buttonbox
def _init_layout(self): """ Create the GUI widgets (but leave them empty). """ hostname_combobox = QComboBox(parent=self) self._hostname_combobox = hostname_combobox hostname_combobox.setEditable(True) hostname_combobox.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Maximum ) for hostname in self._suggested_hostnames: hostname_combobox.addItem( hostname ) # EventFilter is installed after everything else is initialized. (See below.) #hostname_combobox.installEventFilter(self) self._connect_button = QPushButton("Connect", parent=self, clicked=self._handle_new_hostname) hostname_layout = QHBoxLayout() hostname_layout.addWidget( hostname_combobox ) hostname_layout.addWidget( self._connect_button ) hostinfo_table = QTableWidget() hostinfo_table.setColumnCount(len(SERVER_INFO_FIELDS)) hostinfo_table.setHorizontalHeaderLabels(SERVER_INFO_FIELDS) hostinfo_table.horizontalHeader().setVisible(True) hostinfo_table.verticalHeader().setVisible(False) hostinfo_table.setRowCount(1) hostinfo_table.setItem(0,0, QTableWidgetItem("Placeholder")) hostinfo_table.setVisible(False) hostinfo_table.resizeRowsToContents() hostinfo_table.horizontalHeader().setStretchLastSection(True) table_height = hostinfo_table.verticalHeader().sectionSize(0) + hostinfo_table.rowHeight(0) hostinfo_table.resize( QSize( hostinfo_table.width(), table_height ) ) hostinfo_table.setMaximumSize( QSize( 1000, table_height ) ) hostinfo_table.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) host_layout = QVBoxLayout() host_layout.addLayout(hostname_layout) host_layout.addWidget(hostinfo_table) host_groupbox = QGroupBox("DVID Host", parent=self) host_groupbox.setLayout( host_layout ) host_groupbox.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Preferred ) repo_treewidget = QTreeWidget(parent=self) repo_treewidget.setHeaderLabels( TREEVIEW_COLUMNS ) # TODO: Add type, shape, axes, etc. repo_treewidget.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Preferred ) repo_treewidget.itemSelectionChanged.connect( self._handle_data_selection ) data_layout = QVBoxLayout() data_layout.addWidget( repo_treewidget ) data_groupbox = QGroupBox("Data Volumes", parent=self) data_groupbox.setLayout( data_layout ) node_listwidget = QListWidget(parent=self) node_listwidget.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Preferred ) node_listwidget.itemSelectionChanged.connect( self._update_status ) node_layout = QVBoxLayout() node_layout.addWidget( node_listwidget ) node_groupbox = QGroupBox("Nodes", parent=self) node_groupbox.setLayout( node_layout ) new_data_edit = QLineEdit(parent=self) new_data_edit.textEdited.connect( self._update_status ) full_url_label = QLabel(parent=self) full_url_label.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Maximum ) text_flags = full_url_label.textInteractionFlags() full_url_label.setTextInteractionFlags( text_flags | Qt.TextSelectableByMouse ) new_data_layout = QVBoxLayout() new_data_layout.addWidget( new_data_edit ) new_data_groupbox = QGroupBox("New Data Volume", parent=self) new_data_groupbox.setLayout( new_data_layout ) new_data_groupbox.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Maximum ) buttonbox = QDialogButtonBox( Qt.Horizontal, parent=self ) buttonbox.setStandardButtons( QDialogButtonBox.Ok | QDialogButtonBox.Cancel ) buttonbox.accepted.connect( self.accept ) buttonbox.rejected.connect( self.reject ) buttonbox.button(QDialogButtonBox.Ok).setEnabled(False) layout = QVBoxLayout() layout.addWidget( host_groupbox ) layout.addWidget( data_groupbox ) layout.addWidget( node_groupbox ) if self._mode == "specify_new": layout.addWidget( new_data_groupbox ) else: new_data_groupbox.hide() layout.addWidget( full_url_label ) layout.addWidget( buttonbox ) # Stretch factors layout.setStretchFactor(data_groupbox, 3) layout.setStretchFactor(node_groupbox, 1) self.setLayout(layout) self.setWindowTitle( "Select DVID Volume" ) self.resize(1000, 1000) # Initially disabled data_groupbox.setEnabled(False) node_groupbox.setEnabled(False) new_data_groupbox.setEnabled(False) # Set tab order self.setTabOrder(hostname_combobox, repo_treewidget) self.setTabOrder(repo_treewidget, node_listwidget) self.setTabOrder(node_listwidget, buttonbox) # Save instance members self._hostinfo_table = hostinfo_table self._data_groupbox = data_groupbox self._node_groupbox = node_groupbox self._new_data_groupbox = new_data_groupbox self._repo_treewidget = repo_treewidget self._node_listwidget = node_listwidget self._new_data_edit = new_data_edit self._full_url_label = full_url_label self._buttonbox = buttonbox # Finally install eventfilter (after everything is initialized) hostname_combobox.installEventFilter(self)
def _init_layout(self): """ Create the GUI widgets (but leave them empty). """ hostname_combobox = QComboBox(parent=self) self._hostname_combobox = hostname_combobox hostname_combobox.setEditable(True) hostname_combobox.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Maximum ) hostname_combobox.installEventFilter(self) for hostname in self._suggested_hostnames: hostname_combobox.addItem( hostname ) self._connect_button = QPushButton("Connect", parent=self, clicked=self._handle_new_hostname) hostname_layout = QHBoxLayout() hostname_layout.addWidget( hostname_combobox ) hostname_layout.addWidget( self._connect_button ) hostname_groupbox = QGroupBox("DVID Host", parent=self) hostname_groupbox.setLayout( hostname_layout ) hostname_groupbox.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Maximum ) data_treewidget = QTreeWidget(parent=self) data_treewidget.setHeaderLabels( ["Data"] ) # TODO: Add type, shape, axes, etc. data_treewidget.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Preferred ) data_treewidget.itemSelectionChanged.connect( self._handle_data_selection ) data_layout = QVBoxLayout() data_layout.addWidget( data_treewidget ) data_groupbox = QGroupBox("Data Volumes", parent=self) data_groupbox.setLayout( data_layout ) node_listwidget = QListWidget(parent=self) node_listwidget.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Preferred ) node_listwidget.itemSelectionChanged.connect( self._update_display ) node_layout = QVBoxLayout() node_layout.addWidget( node_listwidget ) node_groupbox = QGroupBox("Nodes", parent=self) node_groupbox.setLayout( node_layout ) new_data_edit = QLineEdit(parent=self) new_data_edit.textEdited.connect( self._update_display ) full_url_label = QLabel(parent=self) full_url_label.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Maximum ) text_flags = full_url_label.textInteractionFlags() full_url_label.setTextInteractionFlags( text_flags | Qt.TextSelectableByMouse ) new_data_layout = QVBoxLayout() new_data_layout.addWidget( new_data_edit ) new_data_groupbox = QGroupBox("New Data Volume", parent=self) new_data_groupbox.setLayout( new_data_layout ) new_data_groupbox.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Maximum ) buttonbox = QDialogButtonBox( Qt.Horizontal, parent=self ) buttonbox.setStandardButtons( QDialogButtonBox.Ok | QDialogButtonBox.Cancel ) buttonbox.accepted.connect( self.accept ) buttonbox.rejected.connect( self.reject ) buttonbox.button(QDialogButtonBox.Ok).setEnabled(False) layout = QVBoxLayout() layout.addWidget( hostname_groupbox ) layout.addWidget( data_groupbox ) layout.addWidget( node_groupbox ) if self._mode == "specify_new": layout.addWidget( new_data_groupbox ) else: new_data_groupbox.hide() layout.addWidget( full_url_label ) layout.addWidget( buttonbox ) # Stretch factors layout.setStretchFactor(data_groupbox, 3) layout.setStretchFactor(node_groupbox, 1) self.setLayout(layout) self.setWindowTitle( "Select DVID Volume" ) # Initially disabled data_groupbox.setEnabled(False) node_groupbox.setEnabled(False) new_data_groupbox.setEnabled(False) # Save instance members self._data_groupbox = data_groupbox self._node_groupbox = node_groupbox self._new_data_groupbox = new_data_groupbox self._data_treewidget = data_treewidget self._node_listwidget = node_listwidget self._new_data_edit = new_data_edit self._full_url_label = full_url_label self._buttonbox = buttonbox