From a746afadffc105ad1d4dcc262f735218b6b7bc77 Mon Sep 17 00:00:00 2001 From: dominik Date: Mon, 7 Nov 2022 20:44:18 +0100 Subject: [PATCH] interactive integration; new user-defined fit functions reloads model list; fixed requirements.txt --- pyproject.toml | 1 + requirements.txt | 2 +- src/gui_qt/_py/basewindow.py | 26 +- src/gui_qt/_py/guidelinewidget.py | 247 +++++++---- src/gui_qt/_py/integral_widget.py | 9 +- src/gui_qt/data/integral_widget.py | 98 +++-- src/gui_qt/fit/fitfunction.py | 55 ++- src/gui_qt/fit/fitwindow.py | 2 + .../graphs/{guide_lines.py => drawings.py} | 28 +- src/gui_qt/graphs/graphwindow.py | 6 +- src/gui_qt/lib/pg_objects.py | 1 - src/gui_qt/main/mainwindow.py | 45 +- src/gui_qt/main/management.py | 9 +- src/nmreval/data/points.py | 16 +- src/resources/_ui/basewindow.ui | 35 +- src/resources/_ui/guidelinewidget.ui | 402 ++++++++++-------- src/resources/_ui/integral_widget.ui | 2 +- 17 files changed, 626 insertions(+), 358 deletions(-) rename src/gui_qt/graphs/{guide_lines.py => drawings.py} (90%) diff --git a/pyproject.toml b/pyproject.toml index ff2d408..707dbaa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,6 +41,7 @@ scripts = bin/evaluate.py [tool.setuptools.packages.find] include =[ 'nmreval*', + 'gui_qt*', 'resources*', ] diff --git a/requirements.txt b/requirements.txt index c035f4f..5f1ccc6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ matplotlib numpy scipy -pyqt +PyQt5 h5py pyqtgraph bsddb3 diff --git a/src/gui_qt/_py/basewindow.py b/src/gui_qt/_py/basewindow.py index 40b2100..9574c57 100644 --- a/src/gui_qt/_py/basewindow.py +++ b/src/gui_qt/_py/basewindow.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'resources/_ui/basewindow.ui' +# Form implementation generated from reading ui file '/autohome/dominik/nmreval/src/resources/_ui/basewindow.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 @@ -13,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets class Ui_BaseWindow(object): def setupUi(self, BaseWindow): BaseWindow.setObjectName("BaseWindow") - BaseWindow.resize(1388, 735) + BaseWindow.resize(1386, 827) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(":/logo.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) BaseWindow.setWindowIcon(icon) @@ -63,12 +64,18 @@ class Ui_BaseWindow(object): icon5 = QtGui.QIcon() icon5.addPixmap(QtGui.QPixmap(":/eval_t1_dock"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.tabWidget.addTab(self.t1tauwidget, icon5, "") + self.drawingswidget = DrawingsWidget() + self.drawingswidget.setObjectName("drawingswidget") + self.tabWidget.addTab(self.drawingswidget, "") + self.integralwidget = IntegralWidget() + self.integralwidget.setObjectName("integralwidget") + self.tabWidget.addTab(self.integralwidget, "") self.area = QtWidgets.QMdiArea(self.splitter) self.area.setObjectName("area") self.horizontalLayout.addWidget(self.splitter) BaseWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(BaseWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 1388, 30)) + self.menubar.setGeometry(QtCore.QRect(0, 0, 1386, 30)) self.menubar.setObjectName("menubar") self.menuFile = QtWidgets.QMenu(self.menubar) self.menuFile.setObjectName("menuFile") @@ -359,6 +366,8 @@ class Ui_BaseWindow(object): self.actionUpdate.setObjectName("actionUpdate") self.actionMine = QtWidgets.QAction(BaseWindow) self.actionMine.setObjectName("actionMine") + self.action_draw_object = QtWidgets.QAction(BaseWindow) + self.action_draw_object.setObjectName("action_draw_object") self.menuSave.addAction(self.actionSave) self.menuSave.addAction(self.actionExportGraphic) self.menuSave.addAction(self.action_save_fit_parameter) @@ -434,6 +443,8 @@ class Ui_BaseWindow(object): self.menuWindow.addAction(self.menuView.menuAction()) self.menuWindow.addSeparator() self.menuWindow.addAction(self.actionRefresh) + self.menuWindow.addSeparator() + self.menuWindow.addAction(self.action_draw_object) self.menuNMR.addAction(self.t1action) self.menuNMR.addAction(self.actionCalculateT1) self.menuNMR.addAction(self.action_coup_calc) @@ -492,6 +503,8 @@ class Ui_BaseWindow(object): self.tabWidget.setTabText(self.tabWidget.indexOf(self.editsignalwidget), _translate("BaseWindow", "Signals")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.ptsselectwidget), _translate("BaseWindow", "Pick points")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.t1tauwidget), _translate("BaseWindow", "SLR")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.drawingswidget), _translate("BaseWindow", "Drawings")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.integralwidget), _translate("BaseWindow", "Integrate")) self.menuFile.setTitle(_translate("BaseWindow", "&File")) self.menuSave.setTitle(_translate("BaseWindow", "&Save...")) self.menuData.setTitle(_translate("BaseWindow", "&Data")) @@ -605,9 +618,12 @@ class Ui_BaseWindow(object): self.actionTetris.setText(_translate("BaseWindow", "Not Tetris")) self.actionUpdate.setText(_translate("BaseWindow", "Look for updates")) self.actionMine.setText(_translate("BaseWindow", "Mine")) + self.action_draw_object.setText(_translate("BaseWindow", "Draw objects...")) from ..data.datawidget.datawidget import DataWidget +from ..data.integral_widget import IntegralWidget from ..data.point_select import PointSelectWidget from ..data.signaledit.editsignalwidget import EditSignalWidget from ..data.valueeditwidget import ValueEditWidget from ..fit.fitwindow import QFitDialog +from ..graphs.drawings import DrawingsWidget from ..nmr.t1widget import QT1Widget diff --git a/src/gui_qt/_py/guidelinewidget.py b/src/gui_qt/_py/guidelinewidget.py index a69a325..10df080 100644 --- a/src/gui_qt/_py/guidelinewidget.py +++ b/src/gui_qt/_py/guidelinewidget.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'resources/_ui/guidelinewidget.ui' +# Form implementation generated from reading ui file '/autohome/dominik/nmreval/src/resources/_ui/guidelinewidget.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 @@ -13,109 +14,173 @@ from PyQt5 import QtCore, QtGui, QtWidgets class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") - Form.resize(431, 799) - self.gridLayout_2 = QtWidgets.QGridLayout(Form) - self.gridLayout_2.setContentsMargins(3, 3, 3, 3) - self.gridLayout_2.setSpacing(3) - self.gridLayout_2.setObjectName("gridLayout_2") - self.mode_comboBox = QtWidgets.QComboBox(Form) + Form.resize(459, 830) + self.verticalLayout_2 = QtWidgets.QVBoxLayout(Form) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.graph_comboBox = QtWidgets.QComboBox(Form) + self.graph_comboBox.setObjectName("graph_comboBox") + self.verticalLayout_2.addWidget(self.graph_comboBox) + self.listWidget_2 = QtWidgets.QListWidget(Form) + self.listWidget_2.setObjectName("listWidget_2") + self.verticalLayout_2.addWidget(self.listWidget_2) + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.pushButton = QtWidgets.QPushButton(Form) + self.pushButton.setObjectName("pushButton") + self.horizontalLayout.addWidget(self.pushButton) + self.pushButton_2 = QtWidgets.QPushButton(Form) + self.pushButton_2.setObjectName("pushButton_2") + self.horizontalLayout.addWidget(self.pushButton_2) + self.pushButton_3 = QtWidgets.QPushButton(Form) + self.pushButton_3.setObjectName("pushButton_3") + self.horizontalLayout.addWidget(self.pushButton_3) + self.verticalLayout_2.addLayout(self.horizontalLayout) + self.frame = QtWidgets.QFrame(Form) + self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame.setObjectName("frame") + self.formLayout = QtWidgets.QFormLayout(self.frame) + self.formLayout.setObjectName("formLayout") + self.mode_comboBox = QtWidgets.QComboBox(self.frame) self.mode_comboBox.setObjectName("mode_comboBox") self.mode_comboBox.addItem("") self.mode_comboBox.addItem("") - self.gridLayout_2.addWidget(self.mode_comboBox, 2, 0, 1, 2) - self.graph_comboBox = QtWidgets.QComboBox(Form) - self.graph_comboBox.setObjectName("graph_comboBox") - self.gridLayout_2.addWidget(self.graph_comboBox, 0, 0, 1, 2) - self.horizontalLayout_2 = QtWidgets.QHBoxLayout() - self.horizontalLayout_2.setObjectName("horizontalLayout_2") - self.diagonal_widget = QtWidgets.QWidget(Form) - self.diagonal_widget.setObjectName("diagonal_widget") - self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.diagonal_widget) - self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0) - self.horizontalLayout_4.setObjectName("horizontalLayout_4") - self.horizontalLayout_2.addWidget(self.diagonal_widget) - self.vh_widget = QtWidgets.QWidget(Form) - self.vh_widget.setObjectName("vh_widget") - self.horizontalLayout = QtWidgets.QHBoxLayout(self.vh_widget) - self.horizontalLayout.setContentsMargins(0, 0, 0, 0) - self.horizontalLayout.setObjectName("horizontalLayout") - self.label = QtWidgets.QLabel(self.vh_widget) - self.label.setObjectName("label") - self.horizontalLayout.addWidget(self.label) - self.vh_pos_lineEdit = QtWidgets.QLineEdit(self.vh_widget) - self.vh_pos_lineEdit.setObjectName("vh_pos_lineEdit") - self.horizontalLayout.addWidget(self.vh_pos_lineEdit) - self.horizontalLayout_2.addWidget(self.vh_widget) - self.drag_checkBox = QtWidgets.QCheckBox(Form) - self.drag_checkBox.setChecked(True) - self.drag_checkBox.setObjectName("drag_checkBox") - self.horizontalLayout_2.addWidget(self.drag_checkBox) - self.gridLayout_2.addLayout(self.horizontalLayout_2, 3, 0, 1, 2) - self.color_comboBox = ColorListEditor(Form) - self.color_comboBox.setObjectName("color_comboBox") - self.gridLayout_2.addWidget(self.color_comboBox, 6, 1, 1, 1) - self.pushButton = QtWidgets.QPushButton(Form) - self.pushButton.setObjectName("pushButton") - self.gridLayout_2.addWidget(self.pushButton, 7, 0, 1, 2) - self.label_6 = QtWidgets.QLabel(Form) + self.mode_comboBox.addItem("") + self.mode_comboBox.addItem("") + self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.mode_comboBox) + self.label_12 = QtWidgets.QLabel(self.frame) + self.label_12.setObjectName("label_12") + self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_12) + self.label_6 = QtWidgets.QLabel(self.frame) self.label_6.setObjectName("label_6") - self.gridLayout_2.addWidget(self.label_6, 5, 0, 1, 1) - self.comment_lineEdit = QtWidgets.QLineEdit(Form) + self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_6) + self.comment_lineEdit = QtWidgets.QLineEdit(self.frame) self.comment_lineEdit.setObjectName("comment_lineEdit") - self.gridLayout_2.addWidget(self.comment_lineEdit, 5, 1, 1, 1) - self.label_2 = QtWidgets.QLabel(Form) + self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.comment_lineEdit) + self.label_2 = QtWidgets.QLabel(self.frame) self.label_2.setObjectName("label_2") - self.gridLayout_2.addWidget(self.label_2, 6, 0, 1, 1) - self.tableWidget = QtWidgets.QTableWidget(Form) - self.tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) - self.tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) - self.tableWidget.setColumnCount(2) - self.tableWidget.setObjectName("tableWidget") - self.tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.tableWidget.setHorizontalHeaderItem(0, item) - item = QtWidgets.QTableWidgetItem() - self.tableWidget.setHorizontalHeaderItem(1, item) - self.tableWidget.horizontalHeader().setVisible(True) - self.tableWidget.horizontalHeader().setStretchLastSection(True) - self.gridLayout_2.addWidget(self.tableWidget, 8, 0, 1, 2) - self.line = QtWidgets.QFrame(Form) - self.line.setFrameShape(QtWidgets.QFrame.HLine) - self.line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.line.setObjectName("line") - self.gridLayout_2.addWidget(self.line, 1, 0, 1, 2) - self.line_2 = QtWidgets.QFrame(Form) - self.line_2.setFrameShape(QtWidgets.QFrame.HLine) - self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken) - self.line_2.setObjectName("line_2") - self.gridLayout_2.addWidget(self.line_2, 4, 0, 1, 2) - self.label.setBuddy(self.vh_pos_lineEdit) + self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_2) + self.color_comboBox = ColorListEditor(self.frame) + self.color_comboBox.setObjectName("color_comboBox") + self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.color_comboBox) + self.stackedWidget = QtWidgets.QStackedWidget(self.frame) + self.stackedWidget.setObjectName("stackedWidget") + self.page = QtWidgets.QWidget() + self.page.setObjectName("page") + self.formLayout_2 = QtWidgets.QFormLayout(self.page) + self.formLayout_2.setObjectName("formLayout_2") + self.label_13 = QtWidgets.QLabel(self.page) + self.label_13.setObjectName("label_13") + self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_13) + self.lineEdit_8 = QtWidgets.QLineEdit(self.page) + self.lineEdit_8.setObjectName("lineEdit_8") + self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.lineEdit_8) + self.label = QtWidgets.QLabel(self.page) + self.label.setObjectName("label") + self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label) + self.infiniteline_angle_spinbox = QtWidgets.QSpinBox(self.page) + self.infiniteline_angle_spinbox.setWrapping(True) + self.infiniteline_angle_spinbox.setMaximum(179) + self.infiniteline_angle_spinbox.setObjectName("infiniteline_angle_spinbox") + self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.infiniteline_angle_spinbox) + self.stackedWidget.addWidget(self.page) + self.page_2 = QtWidgets.QWidget() + self.page_2.setObjectName("page_2") + self.verticalLayout = QtWidgets.QVBoxLayout(self.page_2) + self.verticalLayout.setObjectName("verticalLayout") + self.listWidget = QtWidgets.QListWidget(self.page_2) + self.listWidget.setObjectName("listWidget") + self.verticalLayout.addWidget(self.listWidget) + self.stackedWidget.addWidget(self.page_2) + self.page_3 = QtWidgets.QWidget() + self.page_3.setObjectName("page_3") + self.formLayout_3 = QtWidgets.QFormLayout(self.page_3) + self.formLayout_3.setObjectName("formLayout_3") + self.label_5 = QtWidgets.QLabel(self.page_3) + self.label_5.setObjectName("label_5") + self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_5) + self.lineEdit = QtWidgets.QLineEdit(self.page_3) + self.lineEdit.setObjectName("lineEdit") + self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.lineEdit) + self.label_3 = QtWidgets.QLabel(self.page_3) + self.label_3.setObjectName("label_3") + self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_3) + self.lineEdit_2 = QtWidgets.QLineEdit(self.page_3) + self.lineEdit_2.setObjectName("lineEdit_2") + self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.lineEdit_2) + self.label_9 = QtWidgets.QLabel(self.page_3) + self.label_9.setObjectName("label_9") + self.formLayout_3.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_9) + self.lineEdit_3 = QtWidgets.QLineEdit(self.page_3) + self.lineEdit_3.setObjectName("lineEdit_3") + self.formLayout_3.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.lineEdit_3) + self.label_4 = QtWidgets.QLabel(self.page_3) + self.label_4.setObjectName("label_4") + self.formLayout_3.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_4) + self.spinBox = QtWidgets.QSpinBox(self.page_3) + self.spinBox.setObjectName("spinBox") + self.formLayout_3.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.spinBox) + self.stackedWidget.addWidget(self.page_3) + self.page_4 = QtWidgets.QWidget() + self.page_4.setObjectName("page_4") + self.formLayout_4 = QtWidgets.QFormLayout(self.page_4) + self.formLayout_4.setObjectName("formLayout_4") + self.label_7 = QtWidgets.QLabel(self.page_4) + self.label_7.setObjectName("label_7") + self.formLayout_4.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_7) + self.lineEdit_4 = QtWidgets.QLineEdit(self.page_4) + self.lineEdit_4.setObjectName("lineEdit_4") + self.formLayout_4.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.lineEdit_4) + self.label_8 = QtWidgets.QLabel(self.page_4) + self.label_8.setObjectName("label_8") + self.formLayout_4.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_8) + self.lineEdit_5 = QtWidgets.QLineEdit(self.page_4) + self.lineEdit_5.setObjectName("lineEdit_5") + self.formLayout_4.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.lineEdit_5) + self.label_10 = QtWidgets.QLabel(self.page_4) + self.label_10.setObjectName("label_10") + self.formLayout_4.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_10) + self.lineEdit_6 = QtWidgets.QLineEdit(self.page_4) + self.lineEdit_6.setObjectName("lineEdit_6") + self.formLayout_4.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.lineEdit_6) + self.label_11 = QtWidgets.QLabel(self.page_4) + self.label_11.setObjectName("label_11") + self.formLayout_4.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_11) + self.lineEdit_7 = QtWidgets.QLineEdit(self.page_4) + self.lineEdit_7.setObjectName("lineEdit_7") + self.formLayout_4.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.lineEdit_7) + self.stackedWidget.addWidget(self.page_4) + self.formLayout.setWidget(3, QtWidgets.QFormLayout.SpanningRole, self.stackedWidget) + self.verticalLayout_2.addWidget(self.frame) self.label_6.setBuddy(self.comment_lineEdit) self.label_2.setBuddy(self.color_comboBox) self.retranslateUi(Form) + self.stackedWidget.setCurrentIndex(3) QtCore.QMetaObject.connectSlotsByName(Form) - Form.setTabOrder(self.graph_comboBox, self.mode_comboBox) - Form.setTabOrder(self.mode_comboBox, self.vh_pos_lineEdit) - Form.setTabOrder(self.vh_pos_lineEdit, self.drag_checkBox) - Form.setTabOrder(self.drag_checkBox, self.comment_lineEdit) - Form.setTabOrder(self.comment_lineEdit, self.color_comboBox) - Form.setTabOrder(self.color_comboBox, self.pushButton) - Form.setTabOrder(self.pushButton, self.tableWidget) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) - self.mode_comboBox.setItemText(0, _translate("Form", "Vertical")) - self.mode_comboBox.setItemText(1, _translate("Form", "Horizontal")) - self.label.setText(_translate("Form", "Position")) - self.vh_pos_lineEdit.setText(_translate("Form", "0")) - self.drag_checkBox.setText(_translate("Form", "Drag enabled")) - self.pushButton.setText(_translate("Form", "Create line")) + self.pushButton.setText(_translate("Form", "New object")) + self.pushButton_2.setText(_translate("Form", "Edit")) + self.pushButton_3.setText(_translate("Form", "Delete")) + self.mode_comboBox.setItemText(0, _translate("Form", "Infinite Line")) + self.mode_comboBox.setItemText(1, _translate("Form", "Multiple points")) + self.mode_comboBox.setItemText(2, _translate("Form", "Rectangle")) + self.mode_comboBox.setItemText(3, _translate("Form", "Ellipse")) + self.label_12.setText(_translate("Form", "Type")) self.label_6.setText(_translate("Form", "Comment")) self.label_2.setText(_translate("Form", "Color")) - item = self.tableWidget.horizontalHeaderItem(0) - item.setText(_translate("Form", "Pos.")) - item = self.tableWidget.horizontalHeaderItem(1) - item.setText(_translate("Form", "Comment")) + self.label_13.setText(_translate("Form", "Position")) + self.label.setText(_translate("Form", "Angle")) + self.infiniteline_angle_spinbox.setSuffix(_translate("Form", "°")) + self.label_5.setText(_translate("Form", "Lower left")) + self.label_3.setText(_translate("Form", "Width")) + self.label_9.setText(_translate("Form", "Height")) + self.label_4.setText(_translate("Form", "Angle")) + self.label_7.setText(_translate("Form", "Centre")) + self.label_8.setText(_translate("Form", "Axis")) + self.label_10.setText(_translate("Form", "Axis")) + self.label_11.setText(_translate("Form", "Angle")) from ..lib.delegates import ColorListEditor diff --git a/src/gui_qt/_py/integral_widget.py b/src/gui_qt/_py/integral_widget.py index 4f16d93..81ba165 100644 --- a/src/gui_qt/_py/integral_widget.py +++ b/src/gui_qt/_py/integral_widget.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'resources/_ui/integral_widget.ui' +# Form implementation generated from reading ui file '/autohome/dominik/nmreval/src/resources/_ui/integral_widget.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 @@ -49,5 +50,5 @@ class Ui_Form(object): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.label_2.setText(_translate("Form", "TextLabel")) - self.label.setText(_translate("Form", "Save integrals as dataset")) + self.label.setText(_translate("Form", "Save area as datasets")) self.pushButton.setText(_translate("Form", "Apply")) diff --git a/src/gui_qt/data/integral_widget.py b/src/gui_qt/data/integral_widget.py index 19272bb..baeaa90 100644 --- a/src/gui_qt/data/integral_widget.py +++ b/src/gui_qt/data/integral_widget.py @@ -2,6 +2,10 @@ from itertools import cycle import pyqtgraph as pg from numpy import nanmax, nanmin, inf, argsort, where + +from nmreval.lib.colors import Tab10 +from ..lib.pg_objects import PlotItem, RegionItem + try: # numpy > 1.19 renamed some integration functions from scipy.integrate import cumulative_trapezoid @@ -13,31 +17,33 @@ from .._py.integral_widget import Ui_Form class IntegralWidget(QtWidgets.QWidget, Ui_Form): - colors = cycle(['red', 'green', 'blue', 'cyan', 'magenta', - 'darkRed', 'darkGreen', 'darkBlue', 'darkCyan', 'darkMagenta']) + colors = cycle(Tab10) requestData = QtCore.pyqtSignal(str) item_deleted = QtCore.pyqtSignal(pg.GraphicsObject) - newData = QtCore.pyqtSignal(str, list) def __init__(self, parent=None): super().__init__(parent=parent) self.setupUi(self) self.connected_figure = '' + self.management = None + self.graph_shown = None self.shown_set = None - self._data = None self.ranges = [] self.lines = [] + self.areas = [] + self._x = None + self._y = None self.max_area = 0 self.max_y = inf self.min_y = -inf def __call__(self, graph_name, items): - self.label_2.setText(f'Connected to {graph_name}') + self.label_2.setText(f'Connected to {graph_name}\nChanging tab will remove all integration limits.') self.clear() @@ -50,7 +56,7 @@ class IntegralWidget(QtWidgets.QWidget, Ui_Form): self.set_combobox.blockSignals(False) self.set_combobox.setCurrentIndex(0) - self.set_combobox.currentIndexChanged.emit(0) + self.change_set(0) return self @@ -61,26 +67,29 @@ class IntegralWidget(QtWidgets.QWidget, Ui_Form): super().keyPressEvent(e) @QtCore.pyqtSlot(int, name='on_set_combobox_currentIndexChanged') - def change_set(self, idx: int): - key = self.set_combobox.itemData(idx) - self.requestData.emit(key) + def change_set(self, _: int): + # key = self.set_combobox.itemData(idx) + key = self.set_combobox.currentData() - def set_data(self, ptr): - self._data = ptr + self._data = self.management[key] self.max_y = nanmax(self._data.y.real) self.min_y = nanmin(self._data.y.real) for idx, rnge in enumerate(self.ranges): self._update_values(idx, rnge) + def add(self, pos): x = pos[0] - self.ranges.append((x, x * 1.1)) + self.ranges.append((x, x*1.1)) c = next(IntegralWidget.colors) - qc = QtGui.QColor(c) + qc = QtGui.QColor(c.hex()) qc.setAlpha(40) - region = pg.LinearRegionItem(values=[x, x*1.1], brush=QtGui.QBrush(qc), pen=pg.mkPen(QtGui.QColor(c))) - integral_plot = pg.PlotDataItem(x=[], y=[]) + pen = pg.mkPen({f'color': c.rgb()}) + + region = RegionItem(values=[x, x*1.1], mode='mid', brush=QtGui.QBrush(qc), pen=pen) + integral_plot = PlotItem(x=[], y=[], pen=pen) + region.sigRegionChanged.connect(self._update_integral) self.lines.append((region, integral_plot)) @@ -93,7 +102,7 @@ class IntegralWidget(QtWidgets.QWidget, Ui_Form): item = QtWidgets.QTreeWidgetItem() item.setText(0, f'Integral {len(self.ranges)}') - item.setForeground(0, QtGui.QBrush(QtGui.QColor(c))) + item.setForeground(0, QtGui.QBrush(QtGui.QColor(c.hex()))) pts_i = self.ranges[-1] item_list = [] @@ -127,7 +136,8 @@ class IntegralWidget(QtWidgets.QWidget, Ui_Form): def _update_values(self, idx, new_range): self.ranges[idx] = new_range - area = self.calc_integral(idx, *new_range) + + area = self.make_integral(idx, *new_range) item = self.treeWidget.topLevelItem(idx) item.child(0).setText(0, f'Start: {new_range[0]:.5g}') @@ -157,18 +167,18 @@ class IntegralWidget(QtWidgets.QWidget, Ui_Form): scale = (self.max_y - self.min_y) / y_i[-1] * (area_i / max_value) integral_line.setData(x=x_i, y=y_i * scale) - def calc_integral(self, idx, x_min, x_max): - int_range = where((self._data.x >= x_min) & (self._data.x <= x_max))[0] - if len(int_range) > 1: - x_int = self._data.x[int_range] - y_int = self._data.y[int_range].real - order = argsort(x_int) + def make_integral(self, idx, x_min, x_max): + if self._data is None: + self.change_set(0) - integral = cumulative_trapezoid(y=y_int[order], x=x_int[order], initial=0) - scale = (self.max_y-self.min_y) / integral[-1] - self.lines[idx][1].setData(x=x_int[order], y=integral*scale + self.min_y) + integral = self._data.data.integrate(limits=(x_min, x_max), asarray=True) - return integral[-1] + if integral.size != 0: + area = integral[-1, 1] + scale = (self.max_y-self.min_y) / area + self.lines[idx][1].setData(x=integral[:, 0], y=integral[:, 1]*scale + self.min_y) + + return area else: self.lines[idx][1].setData(x=[], y=[]) @@ -179,24 +189,36 @@ class IntegralWidget(QtWidgets.QWidget, Ui_Form): for item in self.treeWidget.selectedItems(): idx = root.indexOfChild(item) - self.ranges.pop(idx) self.item_deleted.emit(self.lines[idx][0]) self.item_deleted.emit(self.lines[idx][1]) + + self.ranges.pop(idx) self.lines.pop(idx) self.areas.pop(idx) + self.treeWidget.takeTopLevelItem(idx) @QtCore.pyqtSlot(name='on_pushButton_clicked') def convert_to_datasets(self): - set_id = self.set_combobox.currentData() - values = [] - for i in range(len(self.ranges)): - x_i, y_i = self.lines[i][1].getData() - start_i, stop_i = self.ranges[i] - area_i = self.areas[i] - values.append((x_i, y_i, start_i, stop_i, area_i)) + set_values = [] + areas = [] - self.newData.emit(set_id, values) + new_sets = True + + for r in self.ranges: + area_i = [] + for idx in range(self.set_combobox.count()): + set_id = self.set_combobox.itemData(idx) + d = self.management[set_id] + if new_sets: + set_values.append(d.value) + integration = d.data.integrate(limits=r, asarray=True) + area_i.append(integration[-1, 1]) + + areas.append(area_i) + new_sets = False + + self.management.integral_datasets(self.ranges, set_values, areas) def clear(self): self.connected_figure = '' @@ -204,6 +226,7 @@ class IntegralWidget(QtWidgets.QWidget, Ui_Form): self.shown_set = None self._data = None + self.areas = [] self.ranges = [] self.lines = [] @@ -211,3 +234,6 @@ class IntegralWidget(QtWidgets.QWidget, Ui_Form): self.max_y = inf self.min_y = -inf + self.treeWidget.clear() + + diff --git a/src/gui_qt/fit/fitfunction.py b/src/gui_qt/fit/fitfunction.py index 9eab41f..f1c85fa 100644 --- a/src/gui_qt/fit/fitfunction.py +++ b/src/gui_qt/fit/fitfunction.py @@ -28,22 +28,9 @@ class QFunctionWidget(QtWidgets.QWidget, Ui_Form): self.setupUi(self) self._types = [] + self.user_functions = {} self.functions = find_models(models) - try: - self.functions += find_models(config_paths() / 'usermodels.py') - except FileNotFoundError: - pass - - for m in self.functions: - try: - m.type - except AttributeError: - m.type = 'Other' - - if m.type not in self._types: - self._types.append(m.type) - - self.typecomboBox.addItems(sorted(self._types)) + self.read_and_load_functions() self.functree.treeChanged.connect(lambda: self.treeChanged.emit()) self.functree.itemRemoved.connect(self.remove_function) @@ -54,6 +41,44 @@ class QFunctionWidget(QtWidgets.QWidget, Ui_Form): for i, op_icon in enumerate(self.op_names): self.operator_combobox.setItemIcon(i, get_icon(op_icon)) + def read_and_load_functions(self): + """ + Reads user-defined fit functions from usermodels.py and adds them to list of fit function. + Previous class definitions are replaced. + """ + user_defined = [] + try: + user_defined = find_models(config_paths() / 'usermodels.py') + except FileNotFoundError: + pass + + for model in user_defined: + name = model.__name__ + if name not in self.user_functions: + self.functions.append(model) + self.user_functions[name] = model + else: + idx = self.functions.index(self.user_functions[name]) + self.functions[idx] = model + self.user_functions[name] = model + + self._types = [] + for m in self.functions: + try: + m.type + except AttributeError: + m.type = 'Other' + + if m.type not in self._types: + self._types.append(m.type) + + self.typecomboBox.blockSignals(True) + self.typecomboBox.clear() + self.typecomboBox.addItems(sorted(self._types)) + self.typecomboBox.blockSignals(False) + + self.change_group(0) + def __len__(self) -> int: num = 0 iterator = QtWidgets.QTreeWidgetItemIterator(self.functree) diff --git a/src/gui_qt/fit/fitwindow.py b/src/gui_qt/fit/fitwindow.py index 3535f4c..bc5b650 100644 --- a/src/gui_qt/fit/fitwindow.py +++ b/src/gui_qt/fit/fitwindow.py @@ -61,6 +61,8 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog): self.functionwidget.showFunction.connect(self.show_function_parameter) self.functionwidget.itemRemoved.connect(self.remove_function) + self.read_and_load_functions = self.functionwidget.read_and_load_functions + @QtCore.pyqtSlot(int, int) def add_function(self, function_idx: int, function_id: int): self.show_function_parameter(function_id, function_idx) diff --git a/src/gui_qt/graphs/guide_lines.py b/src/gui_qt/graphs/drawings.py similarity index 90% rename from src/gui_qt/graphs/guide_lines.py rename to src/gui_qt/graphs/drawings.py index b4b95fc..cd62db4 100644 --- a/src/gui_qt/graphs/guide_lines.py +++ b/src/gui_qt/graphs/drawings.py @@ -1,18 +1,31 @@ -from pyqtgraph import InfiniteLine - -from ..Qt import QtWidgets, QtCore, QtGui +from ..Qt import QtWidgets, QtCore from .._py.guidelinewidget import Ui_Form -from ..lib.pg_objects import LogInfiniteLine -class LineWidget(QtWidgets.QWidget, Ui_Form): - line_created = QtCore.pyqtSignal(object, str) - line_deleted = QtCore.pyqtSignal(object, str) +class DrawingsWidget(QtWidgets.QWidget, Ui_Form): def __init__(self, parent=None): super().__init__(parent=parent) + + self.connected_figure=None + self.setupUi(self) + def __call__(self, graphs): + for gid, name in graphs: + self.graph_comboBox.addItem(name, userData=gid) + + def clear(self): + self.graph_comboBox.clear() + + @QtCore.pyqtSlot(int, name='on_mode_comboBox_currentIndexChanged') + def change_draw_type(self, idx: int): + self.stackedWidget.setCurrentIndex(idx) + + + +""" + self.lines = {} self.comments = {} @@ -145,3 +158,4 @@ class LineWidget(QtWidgets.QWidget, Ui_Form): pos = line.value() text_item = self.tableWidget.item(i, 0) text_item.setText(text_item.text()[:4]+f'{pos:.4g}') +""" \ No newline at end of file diff --git a/src/gui_qt/graphs/graphwindow.py b/src/gui_qt/graphs/graphwindow.py index de97254..8ae796e 100644 --- a/src/gui_qt/graphs/graphwindow.py +++ b/src/gui_qt/graphs/graphwindow.py @@ -605,7 +605,11 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow): dic['items'].append(item_dic) for item in self._external_items: - dic['items'].append(item.get_data_opts()) + try: + dic['items'].append(item.get_data_opts()) + except AttributeError: + print(f'{item} is missing "get_data_opts()"') + continue in_legend.append(False) dic['in_legend'] = in_legend diff --git a/src/gui_qt/lib/pg_objects.py b/src/gui_qt/lib/pg_objects.py index d352277..0b4cf0b 100644 --- a/src/gui_qt/lib/pg_objects.py +++ b/src/gui_qt/lib/pg_objects.py @@ -274,7 +274,6 @@ class PlotItem(PlotDataItem): self.scatter.hide() def set_symbol(self, symbol=None, size=None, color=None): - print(symbol, type(symbol), isinstance(symbol, SymbolStyle)) if symbol is not None: if isinstance(symbol, int): self.setSymbol(SymbolStyle(symbol).to_str()) diff --git a/src/gui_qt/main/mainwindow.py b/src/gui_qt/main/mainwindow.py index ef860fc..4b7717b 100644 --- a/src/gui_qt/main/mainwindow.py +++ b/src/gui_qt/main/mainwindow.py @@ -110,6 +110,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): self.size(), QtWidgets.qApp.desktop().availableGeometry())) self.datawidget.management = self.management + self.integralwidget.management = self.management self.ac_group = QtWidgets.QActionGroup(self) self.ac_group.addAction(self.action_lm_fit) @@ -121,6 +122,8 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): self.ac_group2.addAction(self.action_x_range) self.ac_group2.addAction(self.action_custom_range) + self.action_draw_object.setVisible(False) + def _init_signals(self): self.actionRedo = self.management.undostack.createRedoAction(self) icon = QtGui.QIcon.fromTheme("edit-redo") @@ -142,9 +145,9 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): self.t1action.triggered.connect(lambda: self._show_tab('t1_temp')) self.action_edit.triggered.connect(lambda: self._show_tab('signal')) self.actionPick_position.triggered.connect(lambda: self._show_tab('pick')) - self.actionIntegrate.triggered.connect(lambda: self._show_tab('integrate')) + self.actionIntegration.triggered.connect(lambda: self._show_tab('integrate')) self.action_FitWidget.triggered.connect(lambda: self._show_tab('fit')) - # self.action_draw_object.triggered.connect(lambda: self._show_tab('drawing')) + self.action_draw_object.triggered.connect(lambda: self._show_tab('drawing')) self.action_new_set.triggered.connect(self.management.create_empty) @@ -462,7 +465,8 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): 'signal': (self.editsignalwidget, 'Signals'), 'pick': (self.ptsselectwidget, 'Pick points'), 'fit': (self.fit_dialog, 'Fit'), - # 'drawing': (self.drawingswidget, 'Draw'), + 'drawing': (self.drawingswidget, 'Draw'), + 'integrate': (self.integralwidget, 'Integrate'), }[mode] for idx in range(self.tabWidget.count()): @@ -497,6 +501,8 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): self._select_valuewidget(widget == self.valuewidget) pick_required, block_window = self._select_t1tauwidget(widget == self.t1tauwidget, pick_required, block_window) block_window = self._select_fitwidget(widget == self.fit_dialog, block_window) + self._select_drawingswidget(widget == self.drawingswidget) + pick_required = self._select_integralwidget(widget == self.integralwidget, pick_required, block_window) self._set_pick_block(pick_required, block_window) @@ -529,9 +535,9 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): if self.valuewidget.connected_figure is not None: self.management.graphs[self.valuewidget.connected_figure].remove_external(self._values_plot) - def _select_integralwidget(self, onoff: bool, pick_required: bool): + def _select_integralwidget(self, onoff: bool, pick_required: bool, block_window: bool) -> tuple[bool, bool]: if self.current_graph_widget is None: - return pick_required + return pick_required, block_window if onoff: self.integralwidget(self.current_graph_widget.title, @@ -539,6 +545,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): self.integralwidget.item_deleted.connect(self.current_graph_widget.remove_external) self.integralwidget.connected_figure = self.management.current_graph pick_required = True + block_window = True else: if self.integralwidget.connected_figure: g = self.management.graphs[self.integralwidget.connected_figure] @@ -547,7 +554,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): g.remove_external(line[1]) self.integralwidget.clear() - return pick_required + return pick_required, block_window def _select_t1tauwidget(self, onoff: bool, pick_required: bool, block_window: bool): if onoff: # tau from t1 @@ -580,6 +587,13 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): return pick_required, block_window + def _select_drawingswidget(self, onoff): + if onoff: + self.drawingswidget(self.management.graphs.list()) + self.drawingswidget.connected_figure = self.management.current_graph + else: + self.drawingswidget.clear() + @QtCore.pyqtSlot(str) def get_data(self, key: str): self.sender().set_data(self.management[key]) @@ -657,13 +671,14 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): self.eval.exec() @QtCore.pyqtSlot(name='on_actionDerivation_triggered') - @QtCore.pyqtSlot(name='on_actionIntegration_triggered') + # @QtCore.pyqtSlot(name='on_actionIntegration_triggered') @QtCore.pyqtSlot(name='on_actionFilon_triggered') def int_diff_ft(self): sets = self.management.active_sets - mode = {self.actionIntegration: 'int', - self.actionDerivation: 'diff', - self.actionFilon: 'logft'}[self.sender()] + mode = { + # self.actionIntegration: 'int', + self.actionDerivation: 'diff', + self.actionFilon: 'logft'}[self.sender()] if sets: from ..math.integrate_derive import QDeriveIntegrate @@ -803,6 +818,11 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): elif w == self.t1tauwidget: self.t1tauwidget.t1min_picked(pos) + elif w == self.integralwidget: + region, integral_plot = self.integralwidget.add(pos) + self.current_graph_widget.add_external(region) + self.current_graph_widget.add_external(integral_plot) + def _select_fitwidget(self, onoff: bool, block_window: bool): if self.current_graph_widget is not None: pass @@ -886,7 +906,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): from ..lib.usermodeleditor import QUsermodelEditor self.editor = QUsermodelEditor(config_paths() / 'usermodels.py', parent=self) - self.editor.modelsChanged.connect(self.update_fitmodels) + self.editor.modelsChanged.connect(lambda: self.fit_dialog.read_and_load_functions()) self.editor.setWindowModality(QtCore.Qt.ApplicationModal) self.editor.show() @@ -900,9 +920,6 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): s.valuesChanged.connect(self.management.shift_scale) s.show() - def update_fitmodels(self): - pass - @staticmethod @QtCore.pyqtSlot(name='on_actionDocumentation_triggered') def open_doc(): diff --git a/src/gui_qt/main/management.py b/src/gui_qt/main/management.py index bfbde4d..4eaa869 100644 --- a/src/gui_qt/main/management.py +++ b/src/gui_qt/main/management.py @@ -321,7 +321,7 @@ class UpperManagement(QtCore.QObject): self.newData.emit([self.add(joined)], self.current_graph) - def get_data(self, sid: str, xy_only=False): + def get_data(self, sid: str, xy_only: bool = False): """ Return data for a given id. Return value is tuple of [x, y, y_err] and mask if xy_only is False, [x, y] if true. @@ -930,6 +930,13 @@ class UpperManagement(QtCore.QObject): self.newData.emit(new_sets, kwargs['graph']) + def integral_datasets(self, ranges: list, x_vals: list, y_vals: np.ndarry): + new_sets = [] + for range_i, y_val_i in zip(ranges, y_vals): + new_sets.append(self.add(Points(x=x_vals, y=y_val_i, name=f'{range_i[0]:.4g}-{range_i[1]:.4g}'))) + + self.newData.emit(new_sets, '') + def bds_deriv(self): new_sets = [] diff --git a/src/nmreval/data/points.py b/src/nmreval/data/points.py index 31c8f13..f118a97 100644 --- a/src/nmreval/data/points.py +++ b/src/nmreval/data/points.py @@ -390,20 +390,25 @@ class Points: return self - def integrate(self, log: bool = False, limits: tuple[float, float] = None) -> PointLike: + def integrate(self, log: bool = False, limits: tuple[float, float] = None, asarray: bool = False) -> PointLike: new_data = self.copy() if limits != (None, None): new_data.cut(*limits) + new_data.sort() + if log: new_data.y = cumulative_trapezoid(y=new_data.y, x=np.log(new_data.x), initial=0) else: new_data.y = cumulative_trapezoid(y=new_data.y, x=new_data.x, initial=0) - return new_data + if asarray: + return new_data.toarray(err=False) + else: + return new_data - def diff(self, log: bool = False, limits: tuple[float, float] = None) -> PointLike: + def diff(self, log: bool = False, limits: tuple[float, float] = None, asarray: bool = False) -> PointLike: """ Calculate first derivate :math:`dy/dx` or :math:`dy/d(\ln x)`. @@ -430,7 +435,10 @@ class Points: new_data.remove(np.argwhere(np.isnan(new_data.y))) - return new_data + if asarray: + return new_data.toarray() + else: + return new_data def magnitude(self) -> PointLike: new_data = self.copy() diff --git a/src/resources/_ui/basewindow.ui b/src/resources/_ui/basewindow.ui index 431cc71..12ea544 100644 --- a/src/resources/_ui/basewindow.ui +++ b/src/resources/_ui/basewindow.ui @@ -6,8 +6,8 @@ 0 0 - 1388 - 735 + 1386 + 827 @@ -114,6 +114,16 @@ SLR + + + Drawings + + + + + Integrate + + @@ -125,7 +135,7 @@ 0 0 - 1388 + 1386 30 @@ -274,6 +284,8 @@ + + @@ -999,6 +1011,11 @@ Mine + + + Draw objects... + + @@ -1037,6 +1054,18 @@
..fit.fitwindow
1
+ + DrawingsWidget + QWidget +
..graphs.drawings
+ 1 +
+ + IntegralWidget + QWidget +
..data.integral_widget
+ 1 +
diff --git a/src/resources/_ui/guidelinewidget.ui b/src/resources/_ui/guidelinewidget.ui index 85d5d6b..f302336 100644 --- a/src/resources/_ui/guidelinewidget.ui +++ b/src/resources/_ui/guidelinewidget.ui @@ -6,187 +6,248 @@ 0 0 - 431 - 799 + 459 + 830 Form - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - Vertical - - - - - Horizontal - - - - - + + - - + + + + + - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Position - - - vh_pos_lineEdit - - - - - - - 0 - - - - - - - - + - Drag enabled + New object - - true + + + + + + Edit + + + + + + + Delete - - - - - - - Create line + + + + QFrame::StyledPanel - - - - - - Comment - - - comment_lineEdit - - - - - - - - - - Color - - - color_comboBox - - - - - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - 2 - - - true - - - true - - - - Pos. - - - - - Comment - - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal + + QFrame::Raised + + + + + + Infinite Line + + + + + Multiple points + + + + + Rectangle + + + + + Ellipse + + + + + + + + Type + + + + + + + Comment + + + comment_lineEdit + + + + + + + + + + Color + + + color_comboBox + + + + + + + + + + 3 + + + + + + + Position + + + + + + + + + + Angle + + + + + + + true + + + ° + + + 179 + + + + + + + + + + + + + + + + + + Lower left + + + + + + + + + + Width + + + + + + + + + + Height + + + + + + + + + + Angle + + + + + + + + + + + + + + Centre + + + + + + + + + + Axis + + + + + + + + + + Axis + + + + + + + + + + Angle + + + + + + + + + + + @@ -198,16 +259,9 @@
..lib.delegates
- - graph_comboBox - mode_comboBox - vh_pos_lineEdit - drag_checkBox - comment_lineEdit - color_comboBox - pushButton - tableWidget - + + + diff --git a/src/resources/_ui/integral_widget.ui b/src/resources/_ui/integral_widget.ui index 70c78ed..9569a7e 100644 --- a/src/resources/_ui/integral_widget.ui +++ b/src/resources/_ui/integral_widget.ui @@ -65,7 +65,7 @@ - Save integrals as dataset + Save area as datasets