class FitParam(object): def __init__( self, name, value, min, max, logscale=False, steps=5000, format="%.3f", size_offset=0, unit="", ): self.name = name self.value = value self.min = min self.max = max self.logscale = logscale self.steps = steps self.format = format self.unit = unit self.prefix_label = None self.lineedit = None self.unit_label = None self.slider = None self.button = None self._widgets = [] self._size_offset = size_offset self._refresh_callback = None self.dataset = FitParamDataSet(title=_("Curve fitting parameter")) def copy(self): """Return a copy of this fitparam""" return self.__class__( self.name, self.value, self.min, self.max, self.logscale, self.steps, self.format, self._size_offset, self.unit, ) def create_widgets(self, parent, refresh_callback): self._refresh_callback = refresh_callback self.prefix_label = QLabel() font = self.prefix_label.font() font.setPointSize(font.pointSize() + self._size_offset) self.prefix_label.setFont(font) self.button = QPushButton() self.button.setIcon(get_icon("settings.png")) self.button.setToolTip( _("Edit '%s' fit parameter properties") % self.name) self.button.clicked.connect(lambda: self.edit_param(parent)) self.lineedit = QLineEdit() self.lineedit.editingFinished.connect(self.line_editing_finished) self.unit_label = QLabel(self.unit) self.slider = QSlider() self.slider.setOrientation(Qt.Horizontal) self.slider.setRange(0, self.steps - 1) self.slider.valueChanged.connect(self.slider_value_changed) self.update(refresh=False) self.add_widgets([ self.prefix_label, self.lineedit, self.unit_label, self.slider, self.button, ]) def add_widgets(self, widgets): self._widgets += widgets def get_widgets(self): return self._widgets def set_scale(self, state): self.logscale = state > 0 self.update_slider_value() def set_text(self, fmt=None): style = "<span style='color: #444444'><b>%s</b></span>" self.prefix_label.setText(style % self.name) if self.value is None: value_str = "" else: if fmt is None: fmt = self.format value_str = fmt % self.value self.lineedit.setText(value_str) self.lineedit.setDisabled(self.value == self.min and self.max == self.min) def line_editing_finished(self): try: self.value = float(self.lineedit.text()) except ValueError: self.set_text() self.update_slider_value() self._refresh_callback() def slider_value_changed(self, int_value): if self.logscale: total_delta = np.log10(1 + self.max - self.min) self.value = (self.min + 10**(total_delta * int_value / (self.steps - 1)) - 1) else: total_delta = self.max - self.min self.value = self.min + total_delta * int_value / (self.steps - 1) self.set_text() self._refresh_callback() def update_slider_value(self): if self.value is None or self.min is None or self.max is None: self.slider.setEnabled(False) if self.slider.parent() and self.slider.parent().isVisible(): self.slider.show() elif self.value == self.min and self.max == self.min: self.slider.hide() else: self.slider.setEnabled(True) if self.slider.parent() and self.slider.parent().isVisible(): self.slider.show() if self.logscale: value_delta = max([np.log10(1 + self.value - self.min), 0.0]) total_delta = np.log10(1 + self.max - self.min) else: value_delta = self.value - self.min total_delta = self.max - self.min intval = int(self.steps * value_delta / total_delta) self.slider.blockSignals(True) self.slider.setValue(intval) self.slider.blockSignals(False) def edit_param(self, parent): update_dataset(self.dataset, self) if self.dataset.edit(parent=parent): restore_dataset(self.dataset, self) if self.value > self.max: self.max = self.value if self.value < self.min: self.min = self.value self.update() def update(self, refresh=True): self.unit_label.setText(self.unit) self.slider.setRange(0, self.steps - 1) self.update_slider_value() self.set_text() if refresh: self._refresh_callback()
class Dimension(QWidget): stateChanged = Signal(int) valueChanged = Signal() """ pass in dimension state: one of (State.X, State.Y, State.NONE, State.DISABLE) Can be run independently by: from mantidqt.widgets.sliceviewer.dimensionwidget import Dimension from qtpy.QtWidgets import QApplication app = QApplication([]) window = Dimension({'minimum':-1.1, 'number_of_bins':11, 'width':0.2, 'name':'Dim0', 'units':'A'}) window.show() app.exec_() """ def __init__(self, dim_info, number=0, state=State.NONE, parent=None): super().__init__(parent) self.minimum = dim_info['minimum'] self.nbins = dim_info['number_of_bins'] self.width = dim_info['width'] self.number = number self.layout = QHBoxLayout(self) self.name = QLabel(dim_info['name']) self.units = QLabel(dim_info['units']) self.x = QPushButton('X') self.x.setFixedSize(32, 32) self.x.setCheckable(True) self.x.clicked.connect(self.x_clicked) self.y = QPushButton('Y') self.y.setFixedSize(32, 32) self.y.setCheckable(True) self.y.clicked.connect(self.y_clicked) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, self.nbins - 1) self.slider.valueChanged.connect(self.slider_changed) self.spinbox = QDoubleSpinBox() self.spinbox.setDecimals(3) self.spinbox.setRange(self.get_bin_center(0), self.get_bin_center(self.nbins - 1)) self.spinbox.setSingleStep(self.width) self.spinbox.editingFinished.connect(self.spinbox_changed) self.layout.addWidget(self.name) self.layout.addWidget(self.x) self.layout.addWidget(self.y) self.layout.addWidget(self.slider, stretch=1) self.layout.addStretch(0) self.layout.addWidget(self.spinbox) self.layout.addWidget(self.units) self.set_value(0) if self.nbins < 2: state = State.DISABLE self.set_state(state) def set_state(self, state): self.state = state if self.state == State.X: self.x.setChecked(True) self.y.setChecked(False) self.slider.hide() self.spinbox.hide() self.units.hide() elif self.state == State.Y: self.x.setChecked(False) self.y.setChecked(True) self.slider.hide() self.spinbox.hide() self.units.hide() elif self.state == State.NONE: self.x.setChecked(False) self.y.setChecked(False) self.slider.show() self.spinbox.show() self.units.show() else: self.x.setChecked(False) self.x.setDisabled(True) self.y.setChecked(False) self.y.setDisabled(True) self.slider.hide() self.spinbox.show() self.spinbox.setDisabled(True) self.units.show() def get_state(self): return self.state def x_clicked(self): old_state = self.state self.set_state(State.X) if self.state != old_state: self.stateChanged.emit(self.number) def y_clicked(self): old_state = self.state self.set_state(State.Y) if self.state != old_state: self.stateChanged.emit(self.number) def spinbox_changed(self): self.value = self.spinbox.value() self.update_slider() def slider_changed(self): self.value = self.get_bin_center(self.slider.value()) self.update_spinbox() self.valueChanged.emit() def get_bin_center(self, n): return (n + 0.5) * self.width + self.minimum def update_slider(self): i = (self.value - self.minimum) / self.width self.slider.setValue(int(min(max(i, 0), self.nbins - 1))) def update_spinbox(self): self.spinbox.setValue(self.value) def set_value(self, value): self.value = value self.update_slider() self.update_spinbox() def get_value(self): return self.value
class Dimension(QWidget): stateChanged = Signal(int) valueChanged = Signal() """ pass in dimension state: one of (State.X, State.Y, State.NONE, State.DISBALE) Can be run independently by: from mantidqt.widgets.sliceviewer.dimensionwidget import Dimension from qtpy.QtWidgets import QApplication app = QApplication([]) window = Dimension({'minimum':-1.1, 'number_of_bins':11, 'width':0.2, 'name':'Dim0', 'units':'A'}) window.show() app.exec_() """ def __init__(self, dim_info, number=0, state=State.NONE, parent=None): super(Dimension, self).__init__(parent) self.minimum = dim_info['minimum'] self.nbins = dim_info['number_of_bins'] self.width = dim_info['width'] self.number = number self.layout = QHBoxLayout(self) self.name = QLabel(dim_info['name']) self.units = QLabel(dim_info['units']) self.x = QPushButton('X') self.x.setFixedSize(32,32) self.x.setCheckable(True) self.x.clicked.connect(self.x_clicked) self.y = QPushButton('Y') self.y.setFixedSize(32,32) self.y.setCheckable(True) self.y.clicked.connect(self.y_clicked) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, self.nbins-1) self.slider.valueChanged.connect(self.slider_changed) self.spinbox = QDoubleSpinBox() self.spinbox.setDecimals(3) self.spinbox.setRange(self.get_bin_center(0), self.get_bin_center(self.nbins-1)) self.spinbox.setSingleStep(self.width) self.spinbox.valueChanged.connect(self.spinbox_changed) self.layout.addWidget(self.name) self.layout.addWidget(self.x) self.layout.addWidget(self.y) self.layout.addWidget(self.slider, stretch=1) self.layout.addStretch(0) self.layout.addWidget(self.spinbox) self.layout.addWidget(self.units) self.set_value(0) if self.nbins < 2: state = State.DISABLE self.set_state(state) def set_state(self, state): self.state = state if self.state == State.X: self.x.setChecked(True) self.y.setChecked(False) self.slider.hide() self.spinbox.hide() self.units.hide() elif self.state == State.Y: self.x.setChecked(False) self.y.setChecked(True) self.slider.hide() self.spinbox.hide() self.units.hide() elif self.state == State.NONE: self.x.setChecked(False) self.y.setChecked(False) self.slider.show() self.spinbox.show() self.units.show() else: self.x.setChecked(False) self.x.setDisabled(True) self.y.setChecked(False) self.y.setDisabled(True) self.slider.hide() self.spinbox.show() self.spinbox.setDisabled(True) self.units.show() def get_state(self): return self.state def x_clicked(self): old_state = self.state self.set_state(State.X) if self.state != old_state: self.stateChanged.emit(self.number) def y_clicked(self): old_state = self.state self.set_state(State.Y) if self.state != old_state: self.stateChanged.emit(self.number) def spinbox_changed(self): self.value = self.spinbox.value() self.update_slider() self.valueChanged.emit() def slider_changed(self): self.value = self.get_bin_center(self.slider.value()) self.update_spinbox() self.valueChanged.emit() def get_bin_center(self, n): return (n+0.5)*self.width+self.minimum def update_slider(self): i = (self.value-self.minimum)/self.width self.slider.setValue(int(min(max(i, 0), self.nbins-1))) def update_spinbox(self): self.spinbox.setValue(self.value) def set_value(self, value): self.value = value self.update_slider() self.update_spinbox() def get_value(self): return self.value