diff --git a/nmreval/gui_qt/_py/fitresult.py b/nmreval/gui_qt/_py/fitresult.py index bb2e98a..2634065 100644 --- a/nmreval/gui_qt/_py/fitresult.py +++ b/nmreval/gui_qt/_py/fitresult.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'resources/_ui/fitresult.ui' +# Form implementation generated from reading ui file './resources/_ui/fitresult.ui' # -# Created by: PyQt5 UI code generator 5.12.3 +# Created by: PyQt5 UI code generator 5.15.4 # -# WARNING! All changes made in this file will be lost! +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets @@ -100,17 +101,21 @@ class Ui_Dialog(object): self.page = QtWidgets.QWidget() self.page.setGeometry(QtCore.QRect(0, 0, 399, 346)) self.page.setObjectName("page") - self.verticalLayout = QtWidgets.QVBoxLayout(self.page) - self.verticalLayout.setContentsMargins(3, 3, 3, 3) - self.verticalLayout.setSpacing(3) - self.verticalLayout.setObjectName("verticalLayout") - self.graphicsView = GraphicsLayoutWidget(self.page) - self.graphicsView.setObjectName("graphicsView") - self.verticalLayout.addWidget(self.graphicsView) + self.gridLayout_3 = QtWidgets.QGridLayout(self.page) + self.gridLayout_3.setContentsMargins(3, 3, 3, 3) + self.gridLayout_3.setSpacing(3) + self.gridLayout_3.setObjectName("gridLayout_3") self.logy_box = QtWidgets.QCheckBox(self.page) self.logy_box.setLayoutDirection(QtCore.Qt.RightToLeft) self.logy_box.setObjectName("logy_box") - self.verticalLayout.addWidget(self.logy_box) + self.gridLayout_3.addWidget(self.logy_box, 2, 1, 1, 1) + self.logx_box = QtWidgets.QCheckBox(self.page) + self.logx_box.setLayoutDirection(QtCore.Qt.RightToLeft) + self.logx_box.setObjectName("logx_box") + self.gridLayout_3.addWidget(self.logx_box, 2, 0, 1, 1) + self.graphicsView = GraphicsLayoutWidget(self.page) + self.graphicsView.setObjectName("graphicsView") + self.gridLayout_3.addWidget(self.graphicsView, 0, 0, 1, 2) self.stack.addItem(self.page, "") self.page_2 = QtWidgets.QWidget() self.page_2.setGeometry(QtCore.QRect(0, 0, 399, 346)) @@ -173,6 +178,7 @@ class Ui_Dialog(object): self.reject_fit_checkBox.setText(_translate("Dialog", "Reject this fit")) self.del_prev_checkBox.setText(_translate("Dialog", "Delete previous fits")) self.logy_box.setText(_translate("Dialog", "logarithmic y axis")) + self.logx_box.setText(_translate("Dialog", "logarithmic x axis")) self.stack.setItemText(self.stack.indexOf(self.page), _translate("Dialog", "Plot")) self.stack.setItemText(self.stack.indexOf(self.page_2), _translate("Dialog", "Statistics")) item = self.corr_tableWidget.horizontalHeaderItem(0) diff --git a/nmreval/gui_qt/fit/fit_parameter.py b/nmreval/gui_qt/fit/fit_parameter.py index db57269..65992b9 100644 --- a/nmreval/gui_qt/fit/fit_parameter.py +++ b/nmreval/gui_qt/fit/fit_parameter.py @@ -1,11 +1,9 @@ from __future__ import annotations -from typing import List - from ...utils.text import convert from ..Qt import QtWidgets, QtCore, QtGui from .._py.fitfuncwidget import Ui_FormFit -from ..lib.forms import FormWidget, SelectionWidget +from ..lib.forms import SelectionWidget from .fit_forms import FitModelWidget @@ -83,8 +81,9 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit): self.global_parameter.append(widgt) self.scrollwidget.layout().addWidget(widgt) - widgt2 = FormWidget(name=name, fixable=False, parent=self.scrollwidget2) + widgt2 = ParameterSingleWidget(name=name, parent=self.scrollwidget2) widgt2.valueChanged.connect(self.change_single_parameter) + widgt2.removeSingleValue.connect(self.change_single_parameter) widgt2.installEventFilter(self) self.scrollwidget2.layout().addWidget(widgt2) self.data_parameter.append(widgt2) @@ -139,11 +138,14 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit): self.data_parameter[idx].value = value self.data_parameter[idx].blockSignals(False) - def change_single_parameter(self, value, sender=None): + def change_single_parameter(self, value: float = None, sender=None): if sender is None: sender = self.sender() idx = self.data_parameter.index(sender) self.data_values[self.comboBox.currentData()][idx] = value + # look for global parameter values if value is reset, ie None + if value is None: + self.change_data(self.comboBox.currentIndex()) def change_single_choice(self, _, value, sender=None): if sender is None: @@ -259,7 +261,7 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit): return data_parameter, lb, ub, is_fixed, global_p, is_linked - def set_parameter(self, set_id: str | None, parameter: List[float]) -> int: + def set_parameter(self, set_id: str | None, parameter: list[float]) -> int: if set_id is None: for val, g in zip(parameter, self.global_parameter): if isinstance(g, SelectionWidget): @@ -274,3 +276,50 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit): self.change_data(self.comboBox.currentIndex()) return len(self.global_parameter) + + +class ParameterSingleWidget(QtWidgets.QWidget): + valueChanged = QtCore.pyqtSignal(object) + removeSingleValue = QtCore.pyqtSignal() + + def __init__(self, name: str, parent=None): + super().__init__(parent=parent) + + self._init_ui() + + self._name = name + self.label.setText(convert(name)) + + self.value_line.setValidator(QtGui.QDoubleValidator()) + self.value_line.textChanged.connect(lambda: self.valueChanged.emit(self.value) if self.value is not None else 0) + self.reset_button.clicked.connect(lambda x: self.removeSingleValue.emit()) + + def _init_ui(self): + layout = QtWidgets.QHBoxLayout(self) + layout.setContentsMargins(2, 2, 2, 2) + layout.setSpacing(2) + + self.label = QtWidgets.QLabel(self) + layout.addWidget(self.label) + + layout.addSpacerItem(QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)) + + self.value_line = QtWidgets.QLineEdit(self) + layout.addWidget(self.value_line) + + self.reset_button = QtWidgets.QToolButton(self) + self.reset_button.setText('Use global') + layout.addWidget(self.reset_button) + + self.setLayout(layout) + + @property + def value(self) -> float: + try: + return float(self.value_line.text().replace(',', '.')) + except ValueError: + return 0.0 + + @value.setter + def value(self, val): + self.value_line.setText(f'{float(val):.5g}') diff --git a/nmreval/gui_qt/fit/result.py b/nmreval/gui_qt/fit/result.py index 3065742..08e727d 100644 --- a/nmreval/gui_qt/fit/result.py +++ b/nmreval/gui_qt/fit/result.py @@ -42,7 +42,7 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog): self.residplot = self.graphicsView.addPlot(row=0, col=0) self.resid_graph = PlotItem(x=[], y=[], - symbol='o', symbolPen=None, symbolBrush=mkBrush(color=(174, 199, 232)), + symbol='o', symbolPen=None, symbolBrush=mkBrush(color=(31, 119, 180)), pen=None) self.resid_graph_imag = PlotItem(x=[], y=[], symbol='s', symbolPen=None, symbolBrush=mkBrush(color=(255, 127, 14)), @@ -53,7 +53,7 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog): self.fitplot = self.graphicsView.addPlot(row=1, col=0) self.data_graph = PlotItem(x=[], y=[], - symbol='o', symbolPen=None, symbolBrush=mkBrush(color=(174, 199, 232)), + symbol='o', symbolPen=None, symbolBrush=mkBrush(color=(31, 119, 180)), pen=None) self.data_graph_imag = PlotItem(x=[], y=[], symbol='s', symbolPen=None, symbolBrush=mkBrush(color=(255, 127, 14)), @@ -83,6 +83,8 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog): self.graph_checkBox.stateChanged.connect(lambda x: self.graph_comboBox.setEnabled(x == QtCore.Qt.Unchecked)) self.logy_box.stateChanged.connect(lambda x: self.fitplot.setLogMode(y=bool(x))) + self.logx_box.stateChanged.connect(lambda x: self.fitplot.setLogMode(x=bool(x))) + self.residplot.setXLink(self.fitplot) def add_graphs(self, graphs: list): self.graph_comboBox.clear() diff --git a/nmreval/gui_qt/graphs/graphwindow.py b/nmreval/gui_qt/graphs/graphwindow.py index c0a03f9..fd4b6f9 100644 --- a/nmreval/gui_qt/graphs/graphwindow.py +++ b/nmreval/gui_qt/graphs/graphwindow.py @@ -228,7 +228,7 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow): if self.real_button.isChecked(): item = self.real_plots[a] - if item not in self.graphic.items(): + if (item is not None) and item not in self.graphic.items(): self.graphic.addItem(item) if self.error_button.isChecked(): @@ -256,12 +256,10 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow): def set_imag_visible(self, visible: bool): if self.sender() == self.real_button: plots = self.real_plots - other = self.imag_plots if self.error_button.isChecked() and not visible: self.error_button.setChecked(False) else: plots = self.imag_plots - other = self.real_plots if visible: func = self.graphic.addItem @@ -270,8 +268,7 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow): for a in self.active: item = plots[a] - other_item = other[a] - if (item is not None) and (other_item is not None): + if item is not None: func(item) self.show_legend() diff --git a/nmreval/gui_qt/lib/forms.py b/nmreval/gui_qt/lib/forms.py index cf4a3a2..f42bc00 100644 --- a/nmreval/gui_qt/lib/forms.py +++ b/nmreval/gui_qt/lib/forms.py @@ -117,15 +117,13 @@ class FormWidget(QtWidgets.QWidget): def _init_ui(self): layout = QtWidgets.QHBoxLayout(self) - layout.setContentsMargins(2, 2, 2, 2) - layout.setSpacing(2) + layout.setContentsMargins(1, 1, 1, 1) + layout.setSpacing(3) self.label = QtWidgets.QLabel(self) layout.addWidget(self.label) - layout.addSpacerItem(QtWidgets.QSpacerItem(20, 20, - QtWidgets.QSizePolicy.Expanding, - QtWidgets.QSizePolicy.Minimum)) + layout.addSpacerItem(QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)) self.vals = QtWidgets.QLineEdit(self) layout.addWidget(self.vals) diff --git a/resources/_ui/fitresult.ui b/resources/_ui/fitresult.ui index 0675b76..33e21c0 100644 --- a/resources/_ui/fitresult.ui +++ b/resources/_ui/fitresult.ui @@ -205,10 +205,7 @@ Plot - - - 3 - + 3 @@ -221,10 +218,10 @@ 3 - - - - + + 3 + + Qt::RightToLeft @@ -234,6 +231,19 @@ + + + + Qt::RightToLeft + + + logarithmic x axis + + + + + +