interactive integration; new user-defined fit functions reloads model list; fixed requirements.txt

This commit is contained in:
dominik 2022-11-07 20:44:18 +01:00
parent 47f11a073c
commit a746afadff
17 changed files with 626 additions and 358 deletions

View File

@ -41,6 +41,7 @@ scripts = bin/evaluate.py
[tool.setuptools.packages.find]
include =[
'nmreval*',
'gui_qt*',
'resources*',
]

View File

@ -1,7 +1,7 @@
matplotlib
numpy
scipy
pyqt
PyQt5
h5py
pyqtgraph
bsddb3

View File

@ -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

View File

@ -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

View File

@ -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"))

View File

@ -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 <b>{graph_name}</b>')
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()

View File

@ -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)

View File

@ -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)

View File

@ -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}')
"""

View File

@ -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

View File

@ -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())

View File

@ -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():

View File

@ -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 = []

View File

@ -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()

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1388</width>
<height>735</height>
<width>1386</width>
<height>827</height>
</rect>
</property>
<property name="windowTitle">
@ -114,6 +114,16 @@
<string>SLR</string>
</attribute>
</widget>
<widget class="DrawingsWidget" name="drawingswidget">
<attribute name="title">
<string>Drawings</string>
</attribute>
</widget>
<widget class="IntegralWidget" name="integralwidget">
<attribute name="title">
<string>Integrate</string>
</attribute>
</widget>
</widget>
<widget class="QMdiArea" name="area"/>
</widget>
@ -125,7 +135,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>1388</width>
<width>1386</width>
<height>30</height>
</rect>
</property>
@ -274,6 +284,8 @@
<addaction name="menuView"/>
<addaction name="separator"/>
<addaction name="actionRefresh"/>
<addaction name="separator"/>
<addaction name="action_draw_object"/>
</widget>
<widget class="QMenu" name="menuNMR">
<property name="title">
@ -999,6 +1011,11 @@
<string>Mine</string>
</property>
</action>
<action name="action_draw_object">
<property name="text">
<string>Draw objects...</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
@ -1037,6 +1054,18 @@
<header>..fit.fitwindow</header>
<container>1</container>
</customwidget>
<customwidget>
<class>DrawingsWidget</class>
<extends>QWidget</extends>
<header>..graphs.drawings</header>
<container>1</container>
</customwidget>
<customwidget>
<class>IntegralWidget</class>
<extends>QWidget</extends>
<header>..data.integral_widget</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>

View File

@ -6,187 +6,248 @@
<rect>
<x>0</x>
<y>0</y>
<width>431</width>
<height>799</height>
<width>459</width>
<height>830</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="2" column="0" colspan="2">
<widget class="QComboBox" name="mode_comboBox">
<item>
<property name="text">
<string>Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Horizontal</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0" colspan="2">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QComboBox" name="graph_comboBox"/>
</item>
<item row="3" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QListWidget" name="listWidget_2"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QWidget" name="diagonal_widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="vh_widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Position</string>
</property>
<property name="buddy">
<cstring>vh_pos_lineEdit</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="vh_pos_lineEdit">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="drag_checkBox">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Drag enabled</string>
<string>New object</string>
</property>
<property name="checked">
<bool>true</bool>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_3">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="1">
<widget class="ColorListEditor" name="color_comboBox"/>
</item>
<item row="7" column="0" colspan="2">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Create line</string>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Comment</string>
</property>
<property name="buddy">
<cstring>comment_lineEdit</cstring>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="comment_lineEdit"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Color</string>
</property>
<property name="buddy">
<cstring>color_comboBox</cstring>
</property>
</widget>
</item>
<item row="8" column="0" colspan="2">
<widget class="QTableWidget" name="tableWidget">
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="columnCount">
<number>2</number>
</property>
<attribute name="horizontalHeaderVisible">
<bool>true</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<column>
<property name="text">
<string>Pos.</string>
</property>
</column>
<column>
<property name="text">
<string>Comment</string>
</property>
</column>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="1">
<widget class="QComboBox" name="mode_comboBox">
<item>
<property name="text">
<string>Infinite Line</string>
</property>
</item>
<item>
<property name="text">
<string>Multiple points</string>
</property>
</item>
<item>
<property name="text">
<string>Rectangle</string>
</property>
</item>
<item>
<property name="text">
<string>Ellipse</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Type</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Comment</string>
</property>
<property name="buddy">
<cstring>comment_lineEdit</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="comment_lineEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Color</string>
</property>
<property name="buddy">
<cstring>color_comboBox</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="ColorListEditor" name="color_comboBox"/>
</item>
<item row="3" column="0" colspan="2">
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>3</number>
</property>
<widget class="QWidget" name="page">
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Position</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_8"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Angle</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="infiniteline_angle_spinbox">
<property name="wrapping">
<bool>true</bool>
</property>
<property name="suffix">
<string>°</string>
</property>
<property name="maximum">
<number>179</number>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="listWidget"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_3">
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Lower left</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Width</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_2"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Height</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_3"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Angle</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="spinBox"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_4">
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Centre</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_4"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Axis</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_5"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Axis</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_6"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Angle</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_7"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
@ -198,16 +259,9 @@
<header>..lib.delegates</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>graph_comboBox</tabstop>
<tabstop>mode_comboBox</tabstop>
<tabstop>vh_pos_lineEdit</tabstop>
<tabstop>drag_checkBox</tabstop>
<tabstop>comment_lineEdit</tabstop>
<tabstop>color_comboBox</tabstop>
<tabstop>pushButton</tabstop>
<tabstop>tableWidget</tabstop>
</tabstops>
<resources/>
<connections/>
<buttongroups>
<buttongroup name="buttonGroup"/>
</buttongroups>
</ui>

View File

@ -65,7 +65,7 @@
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Save integrals as dataset</string>
<string>Save area as datasets</string>
</property>
</widget>
</item>