def __init__(self, parent=None, **kwargs): super().__init__(parent, **kwargs) layout = QFormLayout() self.controlArea.setLayout(layout) minf, maxf = -sys.float_info.max, sys.float_info.max self.__values = {} self.__editors = {} self.__lines = {} for name, longname in self.integrator.parameters(): v = 0. self.__values[name] = v e = SetXDoubleSpinBox(decimals=4, minimum=minf, maximum=maxf, singleStep=0.5, value=v) e.focusIn = self.activateOptions e.editingFinished.connect(self.edited) def cf(x, name=name): return self.set_value(name, x) e.valueChanged[float].connect(cf) self.__editors[name] = e layout.addRow(name, e) l = MovableVline(position=v, label=name) l.sigMoved.connect(cf) l.sigMoveFinished.connect(self.edited) self.__lines[name] = l self.focusIn = self.activateOptions self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) self.user_changed = False
def __init__(self, parent=None, **kwargs): super().__init__(parent, **kwargs) layout = QFormLayout() self.controlArea.setLayout(layout) minf, maxf = -sys.float_info.max, sys.float_info.max self.__values = {} self.__editors = {} self.__lines = {} for name, longname in self.integrator.parameters(): v = 0. self.__values[name] = v e = SetXDoubleSpinBox(decimals=4, minimum=minf, maximum=maxf, singleStep=0.5, value=v) e.focusIn = self.activateOptions e.editingFinished.connect(self.edited) def cf(x, name=name): self.edited.emit() return self.set_value(name, x) e.valueChanged[float].connect(cf) self.__editors[name] = e layout.addRow(name, e) l = MovableVline(position=v, label=name) l.sigMoved.connect(cf) self.__lines[name] = l self.focusIn = self.activateOptions self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) self.user_changed = False
def __init__(self, parent=None, **kwargs): limits = kwargs.pop('limits', None) label = kwargs.pop('label', None) delete = kwargs.pop('delete', True) super().__init__(parent, **kwargs) minf, maxf = -sys.float_info.max, sys.float_info.max if label: self.addWidget(QLabel(label)) self.lowlime = SetXDoubleSpinBox(decimals=2, minimum=minf, maximum=maxf, singleStep=0.5, value=limits[0], maximumWidth=75) self.highlime = SetXDoubleSpinBox(decimals=2, minimum=minf, maximum=maxf, singleStep=0.5, value=limits[1], maximumWidth=75) self.lowlime.setValue(limits[0]) self.highlime.setValue(limits[1]) self.addWidget(self.lowlime) self.addWidget(self.highlime) if delete: self.button = QPushButton( QApplication.style().standardIcon( QStyle.SP_DockWidgetCloseButton), "") self.addWidget(self.button) self.button.clicked.connect(self.selfDelete) self.lowlime.valueChanged[float].connect(self.limitChanged) self.highlime.valueChanged[float].connect(self.limitChanged) self.lowlime.editingFinished.connect(self.editFinished) self.highlime.editingFinished.connect(self.editFinished) self.lowlime.focusIn = self.focusInChild self.highlime.focusIn = self.focusInChild self.line1 = MovableVline(position=limits[0], label=label + " - Low") self.line1.sigMoved.connect(self.lineLimitChanged) self.line2 = MovableVline(position=limits[1], label=label + " - High") self.line2.sigMoved.connect(self.lineLimitChanged) self.line1.sigMoveFinished.connect(self.editFinished) self.line2.sigMoveFinished.connect(self.editFinished)
def __init__(self, parent=None, **kwargs): limits = kwargs.pop('limits', None) label = kwargs.pop('label', None) delete = kwargs.pop('delete', True) super().__init__(parent, **kwargs) minf, maxf = -sys.float_info.max, sys.float_info.max if label: self.addWidget(QLabel(label)) self.lowlime = SetXDoubleSpinBox(decimals=2, minimum=minf, maximum=maxf, singleStep=0.5, value=limits[0], maximumWidth=75) self.highlime = SetXDoubleSpinBox(decimals=2, minimum=minf, maximum=maxf, singleStep=0.5, value=limits[1], maximumWidth=75) self.lowlime.setValue(limits[0]) self.highlime.setValue(limits[1]) self.addWidget(self.lowlime) self.addWidget(self.highlime) if delete: self.button = QPushButton( QApplication.style().standardIcon(QStyle.SP_DockWidgetCloseButton), "") self.addWidget(self.button) self.button.clicked.connect(self.selfDelete) self.lowlime.valueChanged[float].connect(self.limitChanged) self.highlime.valueChanged[float].connect(self.limitChanged) self.lowlime.editingFinished.connect(self.editFinished) self.highlime.editingFinished.connect(self.editFinished) self.lowlime.focusIn = self.focusInChild self.highlime.focusIn = self.focusInChild self.line1 = MovableVline(position=limits[0], label=label + " - Low") self.line1.sigMoved.connect(self.lineLimitChanged) self.line2 = MovableVline(position=limits[1], label=label + " - High") self.line2.sigMoved.connect(self.lineLimitChanged) self.line1.sigMoveFinished.connect(self.editFinished) self.line2.sigMoveFinished.connect(self.editFinished)
def __init__(self, parent=None, **kwargs): super().__init__(parent, **kwargs) layout = QVBoxLayout() self.controlArea.setLayout(layout) self.__method = Normalize.Vector self.lower = 0 self.upper = 4000 self.int_method = 0 self.attrs = DomainModel(DomainModel.METAS | DomainModel.CLASSES, valid_types=ContinuousVariable) self.attrform = QFormLayout() self.chosen_attr = None self.last_domain = None self.saved_attr = None self.attrcb = gui.comboBox(None, self, "chosen_attr", callback=self.edited.emit, model=self.attrs) self.attrform.addRow("Normalize to", self.attrcb) self.areaform = QFormLayout() self.int_method_cb = QComboBox(enabled=False) self.int_method_cb.addItems(IntegrateEditor.Integrators) minf, maxf = -sys.float_info.max, sys.float_info.max self.lspin = SetXDoubleSpinBox( minimum=minf, maximum=maxf, singleStep=0.5, value=self.lower, enabled=False) self.uspin = SetXDoubleSpinBox( minimum=minf, maximum=maxf, singleStep=0.5, value=self.upper, enabled=False) self.areaform.addRow("Normalize to", self.int_method_cb) self.areaform.addRow("Lower limit", self.lspin) self.areaform.addRow("Upper limit", self.uspin) self._group = group = QButtonGroup(self) for name, method in self.Normalizers: rb = QRadioButton(self, text=name, checked=self.__method == method) layout.addWidget(rb) if method is Normalize.Attribute: layout.addLayout(self.attrform) elif method is Normalize.Area: layout.addLayout(self.areaform) group.addButton(rb, method) group.buttonClicked.connect(self.__on_buttonClicked) self.lspin.focusIn = self.activateOptions self.uspin.focusIn = self.activateOptions self.focusIn = self.activateOptions self.lspin.valueChanged[float].connect(self.setL) self.lspin.editingFinished.connect(self.reorderLimits) self.uspin.valueChanged[float].connect(self.setU) self.uspin.editingFinished.connect(self.reorderLimits) self.int_method_cb.currentIndexChanged.connect(self.setinttype) self.int_method_cb.activated.connect(self.edited) self.lline = MovableVline(position=self.lower, label="Low limit") self.lline.sigMoved.connect(self.setL) self.lline.sigMoveFinished.connect(self.reorderLimits) self.uline = MovableVline(position=self.upper, label="High limit") self.uline.sigMoved.connect(self.setU) self.uline.sigMoveFinished.connect(self.reorderLimits) self.user_changed = False
class NormalizeEditor(BaseEditorOrange): """ Normalize spectra. """ # Normalization methods Normalizers = [ ("Vector Normalization", Normalize.Vector), ("Min-Max Normalization", Normalize.MinMax), ("Area Normalization", Normalize.Area), ("Attribute Normalization", Normalize.Attribute), ("Standard Normal Variate (SNV)", Normalize.SNV), ("Normalize by Reference", NORMALIZE_BY_REFERENCE), ("Normalize by Reference (Complex Phase)", PHASE_REFERENCE)] def __init__(self, parent=None, **kwargs): super().__init__(parent, **kwargs) layout = QVBoxLayout() self.controlArea.setLayout(layout) self.__method = Normalize.Vector self.lower = 0 self.upper = 4000 self.int_method = 0 self.attrs = DomainModel(DomainModel.METAS | DomainModel.CLASSES, valid_types=ContinuousVariable) self.attrform = QFormLayout() self.chosen_attr = None self.last_domain = None self.saved_attr = None self.attrcb = gui.comboBox(None, self, "chosen_attr", callback=self.edited.emit, model=self.attrs) self.attrform.addRow("Normalize to", self.attrcb) self.areaform = QFormLayout() self.int_method_cb = QComboBox(enabled=False) self.int_method_cb.addItems(IntegrateEditor.Integrators) minf, maxf = -sys.float_info.max, sys.float_info.max self.lspin = SetXDoubleSpinBox( minimum=minf, maximum=maxf, singleStep=0.5, value=self.lower, enabled=False) self.uspin = SetXDoubleSpinBox( minimum=minf, maximum=maxf, singleStep=0.5, value=self.upper, enabled=False) self.areaform.addRow("Normalize to", self.int_method_cb) self.areaform.addRow("Lower limit", self.lspin) self.areaform.addRow("Upper limit", self.uspin) self._group = group = QButtonGroup(self) for name, method in self.Normalizers: rb = QRadioButton(self, text=name, checked=self.__method == method) layout.addWidget(rb) if method is Normalize.Attribute: layout.addLayout(self.attrform) elif method is Normalize.Area: layout.addLayout(self.areaform) group.addButton(rb, method) group.buttonClicked.connect(self.__on_buttonClicked) self.lspin.focusIn = self.activateOptions self.uspin.focusIn = self.activateOptions self.focusIn = self.activateOptions self.lspin.valueChanged[float].connect(self.setL) self.lspin.editingFinished.connect(self.reorderLimits) self.uspin.valueChanged[float].connect(self.setU) self.uspin.editingFinished.connect(self.reorderLimits) self.int_method_cb.currentIndexChanged.connect(self.setinttype) self.int_method_cb.activated.connect(self.edited) self.lline = MovableVline(position=self.lower, label="Low limit") self.lline.sigMoved.connect(self.setL) self.lline.sigMoveFinished.connect(self.reorderLimits) self.uline = MovableVline(position=self.upper, label="High limit") self.uline.sigMoved.connect(self.setU) self.uline.sigMoveFinished.connect(self.reorderLimits) self.user_changed = False def activateOptions(self): self.parent_widget.curveplot.clear_markings() if self.__method == Normalize.Area: if self.lline not in self.parent_widget.curveplot.markings: self.parent_widget.curveplot.add_marking(self.lline) if (self.uline not in self.parent_widget.curveplot.markings and IntegrateEditor.Integrators_classes[self.int_method] is not Integrate.PeakAt): self.parent_widget.curveplot.add_marking(self.uline) def setParameters(self, params): if params: #parameters were manually set somewhere else self.user_changed = True method = params.get("method", Normalize.Vector) lower = params.get("lower", 0) upper = params.get("upper", 4000) int_method = params.get("int_method", 0) if method not in [method for name, method in self.Normalizers]: # handle old worksheets method = Normalize.Vector self.setMethod(method) self.int_method_cb.setCurrentIndex(int_method) self.setL(lower, user=False) self.setU(upper, user=False) self.saved_attr = params.get("attr") # chosen_attr will be set when data are connected def parameters(self): return {"method": self.__method, "lower": self.lower, "upper": self.upper, "int_method": self.int_method, "attr": self.chosen_attr} def setMethod(self, method): if self.__method != method: self.__method = method b = self._group.button(method) b.setChecked(True) for widget in [self.attrcb, self.int_method_cb, self.lspin, self.uspin]: widget.setEnabled(False) if method is Normalize.Attribute: self.attrcb.setEnabled(True) elif method is Normalize.Area: self.int_method_cb.setEnabled(True) self.lspin.setEnabled(True) self.uspin.setEnabled(True) self.activateOptions() self.changed.emit() def setL(self, lower, user=True): if user: self.user_changed = True if self.lower != lower: self.lower = lower with blocked(self.lspin): self.lspin.setValue(lower) self.lline.setValue(lower) self.changed.emit() def setU(self, upper, user=True): if user: self.user_changed = True if self.upper != upper: self.upper = upper with blocked(self.uspin): self.uspin.setValue(upper) self.uline.setValue(upper) self.changed.emit() def reorderLimits(self): if (IntegrateEditor.Integrators_classes[self.int_method] is Integrate.PeakAt): self.upper = self.lower + 10 limits = [self.lower, self.upper] self.lower, self.upper = min(limits), max(limits) self.lspin.setValue(self.lower) self.uspin.setValue(self.upper) self.lline.setValue(self.lower) self.uline.setValue(self.upper) self.edited.emit() def setinttype(self): if self.int_method != self.int_method_cb.currentIndex(): self.int_method = self.int_method_cb.currentIndex() self.reorderLimits() self.activateOptions() self.changed.emit() def __on_buttonClicked(self): method = self._group.checkedId() if method != self.__method: self.setMethod(self._group.checkedId()) self.edited.emit() @staticmethod def createinstance(params): method = params.get("method", Normalize.Vector) lower = params.get("lower", 0) upper = params.get("upper", 4000) int_method_index = params.get("int_method", 0) int_method = IntegrateEditor.Integrators_classes[int_method_index] attr = params.get("attr", None) if method not in (NORMALIZE_BY_REFERENCE, PHASE_REFERENCE): return Normalize(method=method, lower=lower, upper=upper, int_method=int_method, attr=attr) else: # avoids circular imports reference = params.get(REFERENCE_DATA_PARAM, None) if method == PHASE_REFERENCE: return NormalizePhaseReference(reference=reference) return NormalizeReference(reference=reference) def set_preview_data(self, data): edited = False if not self.user_changed: x = getx(data) if len(x): self.setL(min(x)) self.setU(max(x)) edited = True if data is not None and data.domain != self.last_domain: self.last_domain = data.domain self.attrs.set_domain(data.domain) try: # try to load the feature self.chosen_attr = self.saved_attr except ValueError: # could not load the chosen attr self.chosen_attr = self.attrs[0] if self.attrs else None self.saved_attr = self.chosen_attr edited = True if edited: self.edited.emit()
class LimitsBox(QHBoxLayout): """ Box with two limits and optional selection lines Args: limits (list): List containing low and high limit set label (str) : Label widget delete (bool): Include self-deletion button """ valueChanged = Signal(list, QObject) editingFinished = Signal(QObject) deleted = Signal(QObject) def __init__(self, parent=None, **kwargs): limits = kwargs.pop('limits', None) label = kwargs.pop('label', None) delete = kwargs.pop('delete', True) super().__init__(parent, **kwargs) minf, maxf = -sys.float_info.max, sys.float_info.max if label: self.addWidget(QLabel(label)) self.lowlime = SetXDoubleSpinBox(minimum=minf, maximum=maxf, singleStep=0.5, value=limits[0], maximumWidth=75) self.highlime = SetXDoubleSpinBox(minimum=minf, maximum=maxf, singleStep=0.5, value=limits[1], maximumWidth=75) self.lowlime.setValue(limits[0]) self.highlime.setValue(limits[1]) self.addWidget(self.lowlime) self.addWidget(self.highlime) if delete: self.button = QPushButton( QApplication.style().standardIcon( QStyle.SP_DockWidgetCloseButton), "") self.addWidget(self.button) self.button.clicked.connect(self.selfDelete) self.lowlime.valueChanged[float].connect(self.limitChanged) self.highlime.valueChanged[float].connect(self.limitChanged) self.lowlime.editingFinished.connect(self.editFinished) self.highlime.editingFinished.connect(self.editFinished) self.lowlime.focusIn = self.focusInChild self.highlime.focusIn = self.focusInChild self.line1 = MovableVline(position=limits[0], label=label + " - Low") self.line1.sigMoved.connect(self.lineLimitChanged) self.line2 = MovableVline(position=limits[1], label=label + " - High") self.line2.sigMoved.connect(self.lineLimitChanged) self.line1.sigMoveFinished.connect(self.editFinished) self.line2.sigMoveFinished.connect(self.editFinished) def focusInEvent(self, *e): self.focusIn() return super().focusInEvent(*e) def focusInChild(self): self.focusIn() def limitChanged(self): newlimits = [self.lowlime.value(), self.highlime.value()] self.line1.setValue(newlimits[0]) self.line2.setValue(newlimits[1]) self.valueChanged.emit(newlimits, self) def lineLimitChanged(self): newlimits = [self.line1.rounded_value(), self.line2.rounded_value()] self.lowlime.setValue(newlimits[0]) self.highlime.setValue(newlimits[1]) self.limitChanged() def editFinished(self): self.editingFinished.emit(self) def selfDelete(self): self.deleted.emit(self) self.removeLayout() def removeLayout(self): while self.count(): self.takeAt(0).widget().setParent(None) self.setParent(None)
class NormalizeEditor(BaseEditorOrange): """ Normalize spectra. """ # Normalization methods Normalizers = [ ("Vector Normalization", Normalize.Vector), ("Area Normalization", Normalize.Area), ("Attribute Normalization", Normalize.Attribute), ("Normalize by Reference", NORMALIZE_BY_REFERENCE)] def __init__(self, parent=None, **kwargs): super().__init__(parent, **kwargs) layout = QVBoxLayout() self.controlArea.setLayout(layout) self.__method = Normalize.Vector self.lower = 0 self.upper = 4000 self.int_method = 0 self.attrs = DomainModel(DomainModel.METAS | DomainModel.CLASSES, valid_types=ContinuousVariable) self.attrform = QFormLayout() self.chosen_attr = None self.last_domain = None self.saved_attr = None self.attrcb = gui.comboBox(None, self, "chosen_attr", callback=self.edited.emit, model=self.attrs) self.attrform.addRow("Normalize to", self.attrcb) self.areaform = QFormLayout() self.int_method_cb = QComboBox(enabled=False) self.int_method_cb.addItems(IntegrateEditor.Integrators) minf, maxf = -sys.float_info.max, sys.float_info.max self.lspin = SetXDoubleSpinBox( minimum=minf, maximum=maxf, singleStep=0.5, value=self.lower, enabled=False) self.uspin = SetXDoubleSpinBox( minimum=minf, maximum=maxf, singleStep=0.5, value=self.upper, enabled=False) self.areaform.addRow("Normalize to", self.int_method_cb) self.areaform.addRow("Lower limit", self.lspin) self.areaform.addRow("Upper limit", self.uspin) self._group = group = QButtonGroup(self) for name, method in self.Normalizers: rb = QRadioButton(self, text=name, checked=self.__method == method) layout.addWidget(rb) if method is Normalize.Attribute: layout.addLayout(self.attrform) elif method is Normalize.Area: layout.addLayout(self.areaform) group.addButton(rb, method) group.buttonClicked.connect(self.__on_buttonClicked) self.lspin.focusIn = self.activateOptions self.uspin.focusIn = self.activateOptions self.focusIn = self.activateOptions self.lspin.valueChanged[float].connect(self.setL) self.lspin.editingFinished.connect(self.reorderLimits) self.uspin.valueChanged[float].connect(self.setU) self.uspin.editingFinished.connect(self.reorderLimits) self.int_method_cb.currentIndexChanged.connect(self.setinttype) self.int_method_cb.activated.connect(self.edited) self.lline = MovableVline(position=self.lower, label="Low limit") self.lline.sigMoved.connect(self.setL) self.lline.sigMoveFinished.connect(self.reorderLimits) self.uline = MovableVline(position=self.upper, label="High limit") self.uline.sigMoved.connect(self.setU) self.uline.sigMoveFinished.connect(self.reorderLimits) self.user_changed = False def activateOptions(self): self.parent_widget.curveplot.clear_markings() if self.__method == Normalize.Area: if self.lline not in self.parent_widget.curveplot.markings: self.parent_widget.curveplot.add_marking(self.lline) if (self.uline not in self.parent_widget.curveplot.markings and IntegrateEditor.Integrators_classes[self.int_method] is not Integrate.PeakAt): self.parent_widget.curveplot.add_marking(self.uline) def setParameters(self, params): if params: #parameters were manually set somewhere else self.user_changed = True method = params.get("method", Normalize.Vector) lower = params.get("lower", 0) upper = params.get("upper", 4000) int_method = params.get("int_method", 0) if method not in [method for name, method in self.Normalizers]: # handle old worksheets method = Normalize.Vector self.setMethod(method) self.int_method_cb.setCurrentIndex(int_method) self.setL(lower, user=False) self.setU(upper, user=False) self.saved_attr = params.get("attr") # chosen_attr will be set when data are connected def parameters(self): return {"method": self.__method, "lower": self.lower, "upper": self.upper, "int_method": self.int_method, "attr": self.chosen_attr} def setMethod(self, method): if self.__method != method: self.__method = method b = self._group.button(method) b.setChecked(True) for widget in [self.attrcb, self.int_method_cb, self.lspin, self.uspin]: widget.setEnabled(False) if method is Normalize.Attribute: self.attrcb.setEnabled(True) elif method is Normalize.Area: self.int_method_cb.setEnabled(True) self.lspin.setEnabled(True) self.uspin.setEnabled(True) self.activateOptions() self.changed.emit() def setL(self, lower, user=True): if user: self.user_changed = True if self.lower != lower: self.lower = lower with blocked(self.lspin): self.lspin.setValue(lower) self.lline.setValue(lower) self.changed.emit() def setU(self, upper, user=True): if user: self.user_changed = True if self.upper != upper: self.upper = upper with blocked(self.uspin): self.uspin.setValue(upper) self.uline.setValue(upper) self.changed.emit() def reorderLimits(self): if (IntegrateEditor.Integrators_classes[self.int_method] is Integrate.PeakAt): self.upper = self.lower + 10 limits = [self.lower, self.upper] self.lower, self.upper = min(limits), max(limits) self.lspin.setValue(self.lower) self.uspin.setValue(self.upper) self.lline.setValue(self.lower) self.uline.setValue(self.upper) self.edited.emit() def setinttype(self): if self.int_method != self.int_method_cb.currentIndex(): self.int_method = self.int_method_cb.currentIndex() self.reorderLimits() self.activateOptions() self.changed.emit() def __on_buttonClicked(self): method = self._group.checkedId() if method != self.__method: self.setMethod(self._group.checkedId()) self.edited.emit() @staticmethod def createinstance(params): method = params.get("method", Normalize.Vector) lower = params.get("lower", 0) upper = params.get("upper", 4000) int_method_index = params.get("int_method", 0) int_method = IntegrateEditor.Integrators_classes[int_method_index] attr = params.get("attr", None) if method != NORMALIZE_BY_REFERENCE: return Normalize(method=method, lower=lower, upper=upper, int_method=int_method, attr=attr) else: # avoids circular imports from orangecontrib.spectroscopy.widgets.owpreprocess import REFERENCE_DATA_PARAM reference = params.get(REFERENCE_DATA_PARAM, None) return NormalizeReference(reference=reference) def set_preview_data(self, data): edited = False if not self.user_changed: x = getx(data) if len(x): self.setL(min(x)) self.setU(max(x)) edited = True if data is not None and data.domain != self.last_domain: self.last_domain = data.domain self.attrs.set_domain(data.domain) try: # try to load the feature self.chosen_attr = self.saved_attr except ValueError: # could not load the chosen attr self.chosen_attr = self.attrs[0] if self.attrs else None self.saved_attr = self.chosen_attr edited = True if edited: self.edited.emit()
class LimitsBox(QHBoxLayout): """ Box with two limits and optional selection lines Args: limits (list): List containing low and high limit set label (str) : Label widget delete (bool): Include self-deletion button """ valueChanged = Signal(list, QObject) editingFinished = Signal(QObject) deleted = Signal(QObject) def __init__(self, parent=None, **kwargs): limits = kwargs.pop('limits', None) label = kwargs.pop('label', None) delete = kwargs.pop('delete', True) super().__init__(parent, **kwargs) minf, maxf = -sys.float_info.max, sys.float_info.max if label: self.addWidget(QLabel(label)) self.lowlime = SetXDoubleSpinBox(decimals=2, minimum=minf, maximum=maxf, singleStep=0.5, value=limits[0], maximumWidth=75) self.highlime = SetXDoubleSpinBox(decimals=2, minimum=minf, maximum=maxf, singleStep=0.5, value=limits[1], maximumWidth=75) self.lowlime.setValue(limits[0]) self.highlime.setValue(limits[1]) self.addWidget(self.lowlime) self.addWidget(self.highlime) if delete: self.button = QPushButton( QApplication.style().standardIcon(QStyle.SP_DockWidgetCloseButton), "") self.addWidget(self.button) self.button.clicked.connect(self.selfDelete) self.lowlime.valueChanged[float].connect(self.limitChanged) self.highlime.valueChanged[float].connect(self.limitChanged) self.lowlime.editingFinished.connect(self.editFinished) self.highlime.editingFinished.connect(self.editFinished) self.lowlime.focusIn = self.focusInChild self.highlime.focusIn = self.focusInChild self.line1 = MovableVline(position=limits[0], label=label + " - Low") self.line1.sigMoved.connect(self.lineLimitChanged) self.line2 = MovableVline(position=limits[1], label=label + " - High") self.line2.sigMoved.connect(self.lineLimitChanged) self.line1.sigMoveFinished.connect(self.editFinished) self.line2.sigMoveFinished.connect(self.editFinished) def focusInEvent(self, *e): self.focusIn() return super().focusInEvent(*e) def focusInChild(self): self.focusIn() def limitChanged(self): newlimits = [self.lowlime.value(), self.highlime.value()] self.line1.setValue(newlimits[0]) self.line2.setValue(newlimits[1]) self.valueChanged.emit(newlimits, self) def lineLimitChanged(self): newlimits = [self.line1.value(), self.line2.value()] self.lowlime.setValue(newlimits[0]) self.highlime.setValue(newlimits[1]) self.limitChanged() def editFinished(self): self.editingFinished.emit(self) def selfDelete(self): self.deleted.emit(self) self.removeLayout() def removeLayout(self): while self.count(): self.takeAt(0).widget().setParent(None) self.setParent(None)