Esempio n. 1
0
def create_parent_group_box(name: str,
                            res: float,
                            unit: str,
                            required: bool = False) -> QGroupBox:
    """Returns a 'validator-ready' group box to be used by the parent-domain tab."""
    parent_child_ratio_box = QGridLayout()
    # TODO: This should be a spinbox instead with range [1,5].
    parent_child_ratio = add_grid_lineedit(parent_child_ratio_box,
                                           0,
                                           'Child-to-Parent Ratio',
                                           RATIO_VALIDATOR,
                                           required=required)

    res_label = QLabel(
        HORIZONTAL_RESOLUTION_LABEL.format(resolution=res, unit=unit))

    sub_group_box = QGroupBox("Padding")
    grid = QGridLayout()
    top_label = QLabel('Top')
    top_label.setAlignment(Qt.AlignCenter)
    grid.addWidget(top_label, 0, 1)
    left_label = QLabel('Left')
    left_label.setAlignment(Qt.AlignCenter)
    grid.addWidget(left_label, 2, 0)
    right_label = QLabel('Right')
    right_label.setAlignment(Qt.AlignCenter)
    grid.addWidget(right_label, 2, 2)
    bottom_label = QLabel('Bottom')
    bottom_label.setAlignment(Qt.AlignCenter)
    grid.addWidget(bottom_label, 4, 1)
    top = create_lineedit(DIM_VALIDATOR, required)
    left = create_lineedit(DIM_VALIDATOR, required)
    right = create_lineedit(DIM_VALIDATOR, required)
    bottom = create_lineedit(DIM_VALIDATOR, required)
    grid.addWidget(top, 1, 1)
    grid.addWidget(left, 3, 0)
    grid.addWidget(right, 3, 2)
    grid.addWidget(bottom, 5, 1)
    sub_group_box.setLayout(grid)

    vbox = QVBoxLayout()
    vbox.addLayout(parent_child_ratio_box)
    vbox.addWidget(res_label)
    vbox.addWidget(sub_group_box)
    group_box = QGroupBox(name)
    group_box.setLayout(vbox)
    return {
        'inputs': {
            'ratio': parent_child_ratio,
            'top': top,
            'left': left,
            'right': right,
            'bottom': bottom
        },
        'other': {
            'resolution': res_label
        }
    }, group_box
Esempio n. 2
0
    def update_geo_datasets_spec_fields(self) -> None:
        msg_bar = self.iface.messageBar()  # type: QgsMessageBar
        specs = self.project.geo_dataset_specs
        domain_cnt = self.project.domain_count
        field_cnt = self.vbox_geo_datasets_spec.count()

        while field_cnt > domain_cnt:
            layout = self.vbox_geo_datasets_spec.takeAt(field_cnt - 1)
            clear_layout(layout)
            del self.geo_dataset_spec_inputs[-1]
            self.update_project_geo_dataset_specs()
            field_cnt -= 1

        while field_cnt < domain_cnt:

            def create_on_plus_clicked_callback():
                # This code is in this inner function to have a copy of field_cnt,
                # otherwise all on_clicked handlers would refer to field_cnt of the
                # last loop iteration.
                domain_index = field_cnt

                def on_clicked():
                    spec_input = self.geo_dataset_spec_inputs[domain_index]
                    item = self.tree_geog_data.currentItem()
                    if item is None:
                        msg_bar.pushInfo(
                            PLUGIN_NAME,
                            'Select a group in the dataset tree before clicking the + button.'
                        )
                        return
                    if item.childCount() == 0:
                        msg_bar.pushWarning(
                            PLUGIN_NAME,
                            'Select a group in the dataset tree, not a variable.'
                        )
                        return
                    new_group_name = item.data(0, Qt.UserRole)
                    val = spec_input.value()
                    if val:
                        existing_group_names = val.split('+')
                        if new_group_name in existing_group_names:
                            msg_bar.pushWarning(
                                PLUGIN_NAME,
                                'The group you selected is already added for this domain.'
                            )
                            return
                        val += '+'
                    val += new_group_name
                    spec_input.set_value(val)

                return on_clicked

            def create_on_info_clicked_callback():
                # This code is in this inner function to have a copy of field_cnt,
                # otherwise all on_clicked handlers would refer to field_cnt of the
                # last loop iteration.
                domain_index = field_cnt

                def on_clicked():
                    spec_input = self.geo_dataset_spec_inputs[domain_index]
                    group_names = spec_input.value().split('+')

                    # determine resolved datasets for each variable
                    tbl = self.geogrid_tbl
                    resolved_groups = dict(
                    )  # var name -> (group name or None)
                    for variable in sorted(tbl.variables.values(),
                                           key=lambda v: v.name):
                        var_group_names = variable.group_options.keys()
                        found_group_name = None
                        for group_name in group_names:
                            if group_name in var_group_names:
                                found_group_name = group_name
                                break
                        resolved_groups[variable.name] = found_group_name

                    # show in message box
                    title = 'Domain {}'.format(domain_index + 1)
                    text = '<table><tr><td><b>Variable</b></td><td><b>Group</b></td></tr>'
                    for var_name, group_name in resolved_groups.items():
                        if group_name is None:
                            group_name = '<b><i>N/A</i></b>'
                        text += '<tr><td>{}</td><td>{}</td></tr>'.format(
                            var_name, group_name)
                    text += '</table>'
                    QMessageBox.information(self.iface.mainWindow(), title,
                                            text)

                return on_clicked

            hbox_datasets_spec = QHBoxLayout()
            hbox_datasets_spec.addWidget(
                QLabel('Domain: {}'.format(field_cnt + 1)))
            dataset_spec_input = create_lineedit(StringValidator(
                self.is_valid_geo_dataset_spec),
                                                 required=True)
            try:
                dataset_spec_input.set_value(specs[field_cnt])
            except IndexError:
                pass
            dataset_spec_input.textChanged.connect(
                self.update_project_geo_dataset_specs)
            self.geo_dataset_spec_inputs.append(dataset_spec_input)
            hbox_datasets_spec.addWidget(dataset_spec_input)
            plus_btn = QPushButton('+',
                                   clicked=create_on_plus_clicked_callback())
            info_btn = QPushButton('?',
                                   clicked=create_on_info_clicked_callback())
            # TODO make this dynamic, using size policies didn't work
            info_btn.setMaximumWidth(50)
            plus_btn.setMaximumWidth(50)
            hbox_datasets_spec.addWidget(plus_btn)
            hbox_datasets_spec.addWidget(info_btn)
            self.vbox_geo_datasets_spec.addLayout(hbox_datasets_spec)
            field_cnt += 1