Пример #1
0
class _UnitRangeWidget(_ParameterWidget):

    def __init__(self, parameter, parent=None):
        _ParameterWidget.__init__(self, parameter, parent)

        # Widgets
        self._txt_lower = MultiNumericalLineEdit()
        self._txt_upper = MultiNumericalLineEdit()
        self._cb_unit = UnitComboBox(parameter.unit)

        # Layouts
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._txt_lower, 1)
        layout.addWidget(QLabel("-"))
        layout.addWidget(self._txt_upper, 1)
        layout.addWidget(self._cb_unit)
        self.setLayout(layout)

        # Signals
        self.valuesChanged.connect(self._onChanged)
        self.validationRequested.connect(self._onChanged)

        self._txt_lower.textChanged.connect(self.valuesChanged)
        self._txt_upper.textChanged.connect(self.valuesChanged)
        self._cb_unit.currentIndexChanged.connect(self.valuesChanged)

        self.validationRequested.emit()

    def _onChanged(self):
        if self.hasAcceptableInput():
            self._txt_lower.setStyleSheet("background: none")
            self._txt_upper.setStyleSheet("background: none")
        else:
            self._txt_lower.setStyleSheet("background: pink")
            self._txt_upper.setStyleSheet("background: pink")

    def values(self):
        lows = self._txt_lower.values() * self._cb_unit.factor()
        ups = self._txt_upper.values() * self._cb_unit.factor()
        return list(product(lows, ups))

    def setValues(self, values):
        values = np.array(values, ndmin=1)
        self._txt_lower.setValues(list(map(itemgetter(0), values)))
        self._txt_upper.setValues(list(map(itemgetter(1), values)))
        self._cb_unit.setUnit(self.parameter().unit)

    def isReadOnly(self):
        return self._txt_lower.isReadOnly() and \
            self._txt_upper.isReadOnly() and \
            not self._cb_unit.isEnabled()

    def setReadOnly(self, state):
        self._txt_lower.setReadOnly(state)
        self._txt_upper.setReadOnly(state)
        self._cb_unit.setEnabled(not state)
Пример #2
0
class UnitParameterWidget(_ParameterWidget):

    def __init__(self, parameter, parent=None):
        _ParameterWidget.__init__(self, parameter, parent)

        # Widgets
        self._cb_unit = UnitComboBox(parameter.unit)

        self._txt_values = MultiNumericalLineEdit()
        validator = _FactorParameterValidator(parameter, self._cb_unit)
        self._txt_values.setValidator(validator)

        # Layouts
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._txt_values, 1)
        layout.addWidget(self._cb_unit)
        self.setLayout(layout)

        # Signals
        self.valuesChanged.connect(self._onChanged)
        self.validationRequested.connect(self._onChanged)

        self._txt_values.textChanged.connect(self.valuesChanged)
        self._cb_unit.currentIndexChanged.connect(self.valuesChanged)

        self.validationRequested.emit()

    def _onChanged(self):
        if self.hasAcceptableInput():
            self._txt_values.setStyleSheet("background: none")
        else:
            self._txt_values.setStyleSheet("background: pink")

    def values(self):
        return self._txt_values.values() * self._cb_unit.factor()

    def setValues(self, values):
        self._txt_values.setValues(values)
        self._cb_unit.setUnit(self.parameter().unit)

    def isReadOnly(self):
        return self._txt_values.isReadOnly() and not self._cb_unit.isEnabled()

    def setReadOnly(self, state):
        self._txt_values.setReadOnly(state)
        self._cb_unit.setEnabled(not state)

    def hasAcceptableInput(self):
        if not _ParameterWidget.hasAcceptableInput(self):
            return False
        return self._txt_values.hasAcceptableInput()
Пример #3
0
class LayerListWidget(_ParameterWidget):

    def __init__(self, parameter, parent=None):
        _ParameterWidget.__init__(self, parameter, parent)

        # Variables
        model = _LayerModel()
        self._material_class = Material

        # Actions
        act_add = QAction(getIcon("list-add"), "Add layer", self)
        act_remove = QAction(getIcon("list-remove"), "Remove layer", self)
        act_clean = QAction(getIcon('edit-clear'), "Clear", self)

        # Widgets
        self._cb_unit = UnitComboBox('m')
        self._cb_unit.setUnit('um')

        self._tbl_layers = QTableView()
        self._tbl_layers.setModel(model)
        self._tbl_layers.setItemDelegate(_LayerDelegate())
        header = self._tbl_layers.horizontalHeader()
        header.setResizeMode(QHeaderView.Stretch)
        header.setStyleSheet('color: blue')

        self._tlb_layers = QToolBar()
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self._tlb_layers.addWidget(spacer)
        self._tlb_layers.addAction(act_add)
        self._tlb_layers.addAction(act_remove)
        self._tlb_layers.addAction(act_clean)

        # Layouts
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)

        sublayout = QHBoxLayout()
        sublayout.addStretch()
        sublayout.addWidget(QLabel('Thickness unit'))
        sublayout.addWidget(self._cb_unit)
        layout.addLayout(sublayout)

        layout.addWidget(self._tbl_layers)
        layout.addWidget(self._tlb_layers)
        self.setLayout(layout)

        # Signals
        self.valuesChanged.connect(self._onChanged)
        self.validationRequested.connect(self._onChanged)

        act_add.triggered.connect(self._onAdd)
        act_remove.triggered.connect(self._onRemove)
        act_clean.triggered.connect(self._onClear)

        self._tbl_layers.doubleClicked.connect(self._onDoubleClicked)

        model.dataChanged.connect(self.valuesChanged)
        model.rowsInserted.connect(self.valuesChanged)
        model.rowsRemoved.connect(self.valuesChanged)

        self.validationRequested.emit()

    def _onChanged(self):
        if self.hasAcceptableInput():
            self._tbl_layers.setStyleSheet("background: none")
        else:
            self._tbl_layers.setStyleSheet("background: pink")

    def _onDoubleClicked(self, index):
        if index.column() != 0:
            return

        model = self._tbl_layers.model()
        materials = model.materials(index)

        if len(materials) == 0:
            dialog = get_material_dialog_class(self._material_class)()
        elif len(materials) == 1:
            dialog = get_material_dialog_class(self._material_class)()
            dialog.setValue(materials[0])
        else:
            dialog = MaterialListDialog()
            dialog.setMaterialClass(self._material_class)
            dialog.setValues(materials)

        dialog.setReadOnly(self.isReadOnly())

        if not dialog.exec_():
            return

        model.setData(index, dialog.values())

    def _onAdd(self):
        index = self._tbl_layers.selectionModel().currentIndex()
        model = self._tbl_layers.model()
        model.insertRows(index.row() + 1)

        # Show material dialog right away
        index = model.createIndex(index.row() + 1, 0)
        self._onDoubleClicked(index)

    def _onRemove(self):
        selection = self._tbl_layers.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Layer", "Select a row")
            return

        model = self._tbl_layers.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            model.removeRow(row)

    def _onClear(self):
        model = self._tbl_layers.model()
        for row in reversed(range(model.rowCount())):
            model.removeRow(row)

    def values(self):
        factor = self._cb_unit.factor()

        layers = []
        for material, thickness in self._tbl_layers.model().layers():
            if not material or not thickness:
                continue
            thickness_m = np.array(thickness, ndmin=1) * factor
            layers.append(_MockLayer(material, thickness_m))

        return layers

    def setValues(self, layers):
        layers = np.array(layers, ndmin=1)
        factor = self._cb_unit.factor()

        model = self._tbl_layers.model()
        model.removeRows(0, model.rowCount())
        model.insertRows(0, len(layers))

        for i, layer in enumerate(layers):
            model.setData(model.index(i, 0), layer.material)
            model.setData(model.index(i, 1), layer.thickness_m / factor)

    def isReadOnly(self):
        return not self._cb_unit.isEnabled() and \
            not self._tlb_layers.isVisible()

    def setReadOnly(self, state):
        self._cb_unit.setEnabled(not state)
        self._tlb_layers.setVisible(not state)

        style = 'color: none' if state else 'color: blue'
        self._tbl_layers.horizontalHeader().setStyleSheet(style)
        self._tbl_layers.itemDelegate().setReadOnly(state)

    def setMaterialClass(self, clasz):
        self._material_class = clasz
Пример #4
0
class OriginWidget(_ParameterWidget):

    def __init__(self, parameter, parent=None):
        _ParameterWidget.__init__(self, parameter, parent)

        # Widgets
        self._lbl_x = QLabel('x')
        self._lbl_x.setStyleSheet("color: blue")
        self._txt_x = MultiNumericalLineEdit()

        self._lbl_y = QLabel('y')
        self._lbl_y.setStyleSheet("color: blue")
        self._txt_y = MultiNumericalLineEdit()

        self._lbl_z = QLabel('z')
        self._lbl_z.setStyleSheet("color: blue")
        self._txt_z = MultiNumericalLineEdit()

        self._cb_unit = UnitComboBox(parameter.unit)

        # Layouts
        layout = QFormLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        if sys.platform == 'darwin': # Fix for Mac OS
            layout.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.ExpandingFieldsGrow)
        layout.addRow(self._lbl_x, self._txt_x)
        layout.addRow(self._lbl_y, self._txt_y)
        layout.addRow(self._lbl_z, self._txt_z)
        layout.addRow('Unit', self._cb_unit)
        self.setLayout(layout)

        # Signals
        self.valuesChanged.connect(self._onChanged)
        self.validationRequested.connect(self._onChanged)

        self._txt_x.textChanged.connect(self.valuesChanged)
        self._txt_y.textChanged.connect(self.valuesChanged)
        self._txt_z.textChanged.connect(self.valuesChanged)
        self._cb_unit.currentIndexChanged.connect(self.valuesChanged)

        self.validationRequested.emit()

    def _onChanged(self):
        if self.hasAcceptableInput():
            self._txt_x.setStyleSheet("background: none")
            self._txt_y.setStyleSheet("background: none")
            self._txt_z.setStyleSheet("background: none")
        else:
            self._txt_x.setStyleSheet("background: pink")
            self._txt_y.setStyleSheet("background: pink")
            self._txt_z.setStyleSheet("background: pink")

    def values(self):
        xs = self._txt_x.values() * self._cb_unit.factor()
        ys = self._txt_y.values() * self._cb_unit.factor()
        zs = self._txt_z.values() * self._cb_unit.factor()
        return list(product(xs, ys, zs))

    def setValues(self, values):
        values = np.array(values, ndmin=1)
        self._txt_x.setValues(list(map(itemgetter(0), values)))
        self._txt_y.setValues(list(map(itemgetter(1), values)))
        self._txt_z.setValues(list(map(itemgetter(2), values)))
        self._cb_unit.setUnit('m')

    def isReadOnly(self):
        return self._txt_x.isReadOnly() and \
                self._txt_y.isReadOnly() and \
                self._txt_z.isReadOnly() and \
                not self._cb_unit.isEnabled()

    def setReadOnly(self, state):
        style = 'color: none' if state else 'color: blue'
        self._lbl_x.setStyleSheet(style)
        self._txt_x.setReadOnly(state)
        self._lbl_y.setStyleSheet(style)
        self._txt_y.setReadOnly(state)
        self._lbl_z.setStyleSheet(style)
        self._txt_z.setReadOnly(state)
        self._cb_unit.setEnabled(not state)

    def hasAcceptableInput(self):
        if not _ParameterWidget.hasAcceptableInput(self):
            return False

        if not self._txt_x.hasAcceptableInput():
            return False
        if not self._txt_y.hasAcceptableInput():
            return False
        if not self._txt_z.hasAcceptableInput():
            return False

        return True