value tab plots complex selection; graphwindows shows last path for export; filedialog uses call not init

This commit is contained in:
dominik 2022-11-19 17:59:35 +01:00
parent a61dc40343
commit 4ca8f434aa
11 changed files with 206 additions and 157 deletions

View File

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Form implementation generated from reading ui file '_ui/asciidialog.ui' # Form implementation generated from reading ui file '/autohome/dominik/nmreval/src/resources/_ui/asciidialog.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 from PyQt5 import QtCore, QtGui, QtWidgets
@ -23,11 +24,11 @@ class Ui_ascii_reader(object):
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.tabWidgetPage1) self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.tabWidgetPage1)
self.verticalLayout_3.setContentsMargins(0, 0, 0, 0) self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_3.setObjectName("verticalLayout_3") self.verticalLayout_3.setObjectName("verticalLayout_3")
self.plainTextEdit_2 = QtWidgets.QPlainTextEdit(self.tabWidgetPage1) self.comment_textfield = QtWidgets.QPlainTextEdit(self.tabWidgetPage1)
self.plainTextEdit_2.setEnabled(False) self.comment_textfield.setEnabled(False)
self.plainTextEdit_2.setMaximumSize(QtCore.QSize(16777215, 180)) self.comment_textfield.setMaximumSize(QtCore.QSize(16777215, 180))
self.plainTextEdit_2.setObjectName("plainTextEdit_2") self.comment_textfield.setObjectName("comment_textfield")
self.verticalLayout_3.addWidget(self.plainTextEdit_2) self.verticalLayout_3.addWidget(self.comment_textfield)
self.ascii_table = QtWidgets.QTableWidget(self.tabWidgetPage1) self.ascii_table = QtWidgets.QTableWidget(self.tabWidgetPage1)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -49,9 +50,9 @@ class Ui_ascii_reader(object):
self.tabWidgetPage2.setObjectName("tabWidgetPage2") self.tabWidgetPage2.setObjectName("tabWidgetPage2")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.tabWidgetPage2) self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.tabWidgetPage2)
self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.plainTextEdit = QtWidgets.QPlainTextEdit(self.tabWidgetPage2) self.delay_textfield = QtWidgets.QPlainTextEdit(self.tabWidgetPage2)
self.plainTextEdit.setObjectName("plainTextEdit") self.delay_textfield.setObjectName("delay_textfield")
self.horizontalLayout_3.addWidget(self.plainTextEdit) self.horizontalLayout_3.addWidget(self.delay_textfield)
self.formLayout = QtWidgets.QFormLayout() self.formLayout = QtWidgets.QFormLayout()
self.formLayout.setFieldGrowthPolicy(QtWidgets.QFormLayout.ExpandingFieldsGrow) self.formLayout.setFieldGrowthPolicy(QtWidgets.QFormLayout.ExpandingFieldsGrow)
self.formLayout.setContentsMargins(0, -1, -1, -1) self.formLayout.setContentsMargins(0, -1, -1, -1)
@ -79,18 +80,18 @@ class Ui_ascii_reader(object):
self.end_lineedit = QtWidgets.QLineEdit(self.tabWidgetPage2) self.end_lineedit = QtWidgets.QLineEdit(self.tabWidgetPage2)
self.end_lineedit.setObjectName("end_lineedit") self.end_lineedit.setObjectName("end_lineedit")
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.end_lineedit) self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.end_lineedit)
self.checkBox = QtWidgets.QCheckBox(self.tabWidgetPage2) self.log_checkBox = QtWidgets.QCheckBox(self.tabWidgetPage2)
self.checkBox.setLayoutDirection(QtCore.Qt.LeftToRight) self.log_checkBox.setLayoutDirection(QtCore.Qt.LeftToRight)
self.checkBox.setObjectName("checkBox") self.log_checkBox.setObjectName("log_checkBox")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.SpanningRole, self.checkBox) self.formLayout.setWidget(3, QtWidgets.QFormLayout.SpanningRole, self.log_checkBox)
self.checkBox_2 = QtWidgets.QCheckBox(self.tabWidgetPage2) self.staggered_checkBox = QtWidgets.QCheckBox(self.tabWidgetPage2)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.checkBox_2.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.staggered_checkBox.sizePolicy().hasHeightForWidth())
self.checkBox_2.setSizePolicy(sizePolicy) self.staggered_checkBox.setSizePolicy(sizePolicy)
self.checkBox_2.setObjectName("checkBox_2") self.staggered_checkBox.setObjectName("staggered_checkBox")
self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.checkBox_2) self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.staggered_checkBox)
self.stag_lineEdit = QtWidgets.QLineEdit(self.tabWidgetPage2) self.stag_lineEdit = QtWidgets.QLineEdit(self.tabWidgetPage2)
self.stag_lineEdit.setEnabled(True) self.stag_lineEdit.setEnabled(True)
self.stag_lineEdit.setObjectName("stag_lineEdit") self.stag_lineEdit.setObjectName("stag_lineEdit")
@ -139,9 +140,9 @@ class Ui_ascii_reader(object):
self.label_5 = QtWidgets.QLabel(self.widget) self.label_5 = QtWidgets.QLabel(self.widget)
self.label_5.setObjectName("label_5") self.label_5.setObjectName("label_5")
self.horizontalLayout_4.addWidget(self.label_5) self.horizontalLayout_4.addWidget(self.label_5)
self.lineEdit = QtWidgets.QLineEdit(self.widget) self.deltay_lineEdit = QtWidgets.QLineEdit(self.widget)
self.lineEdit.setObjectName("lineEdit") self.deltay_lineEdit.setObjectName("deltay_lineEdit")
self.horizontalLayout_4.addWidget(self.lineEdit) self.horizontalLayout_4.addWidget(self.deltay_lineEdit)
self.horizontalLayout.addWidget(self.widget) self.horizontalLayout.addWidget(self.widget)
self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout.addLayout(self.horizontalLayout)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout() self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
@ -152,23 +153,23 @@ class Ui_ascii_reader(object):
self.horizontalLayout_2.addWidget(self.skippy_checkbox) self.horizontalLayout_2.addWidget(self.skippy_checkbox)
spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(spacerItem3) self.horizontalLayout_2.addItem(spacerItem3)
self.radioButton = QtWidgets.QRadioButton(ascii_reader) self.pts_radioButton = QtWidgets.QRadioButton(ascii_reader)
self.radioButton.setChecked(True) self.pts_radioButton.setChecked(True)
self.radioButton.setAutoExclusive(True) self.pts_radioButton.setAutoExclusive(True)
self.radioButton.setObjectName("radioButton") self.pts_radioButton.setObjectName("pts_radioButton")
self.buttonGroup = QtWidgets.QButtonGroup(ascii_reader) self.buttonGroup = QtWidgets.QButtonGroup(ascii_reader)
self.buttonGroup.setObjectName("buttonGroup") self.buttonGroup.setObjectName("buttonGroup")
self.buttonGroup.addButton(self.radioButton) self.buttonGroup.addButton(self.pts_radioButton)
self.horizontalLayout_2.addWidget(self.radioButton) self.horizontalLayout_2.addWidget(self.pts_radioButton)
self.radioButton_2 = QtWidgets.QRadioButton(ascii_reader) self.FID_radioButton = QtWidgets.QRadioButton(ascii_reader)
self.radioButton_2.setAutoExclusive(True) self.FID_radioButton.setAutoExclusive(True)
self.radioButton_2.setObjectName("radioButton_2") self.FID_radioButton.setObjectName("FID_radioButton")
self.buttonGroup.addButton(self.radioButton_2) self.buttonGroup.addButton(self.FID_radioButton)
self.horizontalLayout_2.addWidget(self.radioButton_2) self.horizontalLayout_2.addWidget(self.FID_radioButton)
self.radioButton_3 = QtWidgets.QRadioButton(ascii_reader) self.spectrum_radioButton = QtWidgets.QRadioButton(ascii_reader)
self.radioButton_3.setObjectName("radioButton_3") self.spectrum_radioButton.setObjectName("spectrum_radioButton")
self.buttonGroup.addButton(self.radioButton_3) self.buttonGroup.addButton(self.spectrum_radioButton)
self.horizontalLayout_2.addWidget(self.radioButton_3) self.horizontalLayout_2.addWidget(self.spectrum_radioButton)
self.verticalLayout.addLayout(self.horizontalLayout_2) self.verticalLayout.addLayout(self.horizontalLayout_2)
self.buttonbox = QtWidgets.QDialogButtonBox(ascii_reader) self.buttonbox = QtWidgets.QDialogButtonBox(ascii_reader)
self.buttonbox.setStandardButtons(QtWidgets.QDialogButtonBox.Apply|QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) self.buttonbox.setStandardButtons(QtWidgets.QDialogButtonBox.Apply|QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
@ -187,8 +188,8 @@ class Ui_ascii_reader(object):
self.label_2.setText(_translate("ascii_reader", "Number of delays")) self.label_2.setText(_translate("ascii_reader", "Number of delays"))
self.label_3.setText(_translate("ascii_reader", "Start value")) self.label_3.setText(_translate("ascii_reader", "Start value"))
self.label_4.setText(_translate("ascii_reader", "End value")) self.label_4.setText(_translate("ascii_reader", "End value"))
self.checkBox.setText(_translate("ascii_reader", "Logarithmic scale")) self.log_checkBox.setText(_translate("ascii_reader", "Logarithmic scale"))
self.checkBox_2.setText(_translate("ascii_reader", "Staggered range")) self.staggered_checkBox.setText(_translate("ascii_reader", "Staggered range"))
self.pushButton.setText(_translate("ascii_reader", "Calculate delays")) self.pushButton.setText(_translate("ascii_reader", "Calculate delays"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tabWidgetPage2), _translate("ascii_reader", "Delays")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tabWidgetPage2), _translate("ascii_reader", "Delays"))
self.x_label.setText(_translate("ascii_reader", "x")) self.x_label.setText(_translate("ascii_reader", "x"))
@ -198,6 +199,6 @@ class Ui_ascii_reader(object):
self.label_5.setText(_translate("ascii_reader", "<html><head/><body><p>Δy</p></body></html>")) self.label_5.setText(_translate("ascii_reader", "<html><head/><body><p>Δy</p></body></html>"))
self.skippy_checkbox.setToolTip(_translate("ascii_reader", "Use selection for next files. Deletes possible delay values.")) self.skippy_checkbox.setToolTip(_translate("ascii_reader", "Use selection for next files. Deletes possible delay values."))
self.skippy_checkbox.setText(_translate("ascii_reader", "Skip next dialogues?")) self.skippy_checkbox.setText(_translate("ascii_reader", "Skip next dialogues?"))
self.radioButton.setText(_translate("ascii_reader", "Points")) self.pts_radioButton.setText(_translate("ascii_reader", "Points"))
self.radioButton_2.setText(_translate("ascii_reader", "FID")) self.FID_radioButton.setText(_translate("ascii_reader", "FID"))
self.radioButton_3.setText(_translate("ascii_reader", "Spectrum")) self.spectrum_radioButton.setText(_translate("ascii_reader", "Spectrum"))

View File

@ -2,7 +2,8 @@ from __future__ import annotations
from typing import Any from typing import Any
import numpy as np from numpy import ndarray, iscomplexobj, asarray
from pyqtgraph import PlotDataItem
from ..Qt import QtGui, QtCore, QtWidgets from ..Qt import QtGui, QtCore, QtWidgets
from .._py.valueeditor import Ui_MaskDialog from .._py.valueeditor import Ui_MaskDialog
@ -14,7 +15,7 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
itemChanged = QtCore.pyqtSignal(str, tuple, object) itemChanged = QtCore.pyqtSignal(str, tuple, object)
itemDeleted = QtCore.pyqtSignal(str, list) itemDeleted = QtCore.pyqtSignal(str, list)
itemAdded = QtCore.pyqtSignal(str) itemAdded = QtCore.pyqtSignal(str)
values_selected = QtCore.pyqtSignal(str, list, list) values_selected = QtCore.pyqtSignal(str, str)
split_signal = QtCore.pyqtSignal(str, int) split_signal = QtCore.pyqtSignal(str, int)
def __init__(self, parent=None): def __init__(self, parent=None):
@ -37,8 +38,10 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
self.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.tableView.customContextMenuRequested.connect(self.ctx) self.tableView.customContextMenuRequested.connect(self.ctx)
self.graph_combobox.currentIndexChanged.connect(self._populate_sets) self.selection_real = PlotDataItem(x=[], y=[], symbolSize=25, symbol='x',
self.set_combobox.currentIndexChanged.connect(self._populate_table) pen=None, symbolPen='#c9308e', symbolBrush='#c9308e')
self.selection_imag = PlotDataItem(x=[], y=[], symbolSize=25, symbol='+',
pen=None, symbolPen='#dcdcdc', symbolBrush='#dcdcdc')
def __call__(self, items: dict): def __call__(self, items: dict):
self.items = items self.items = items
@ -58,7 +61,7 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
return self return self
@QtCore.pyqtSlot(int) @QtCore.pyqtSlot(int, name='on_graph_combobox_currentIndexChanged')
def _populate_sets(self, idx: int): def _populate_sets(self, idx: int):
if idx == -1: if idx == -1:
self.graph_combobox.setCurrentIndex(0) self.graph_combobox.setCurrentIndex(0)
@ -66,6 +69,7 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
self.set_combobox.blockSignals(True) self.set_combobox.blockSignals(True)
self.set_combobox.clear() self.set_combobox.clear()
old_figure = self.connected_figure
self.connected_figure = self.graph_combobox.currentData() self.connected_figure = self.graph_combobox.currentData()
if self.items: if self.items:
@ -80,13 +84,15 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
self.set_combobox.setCurrentIndex(sidx) self.set_combobox.setCurrentIndex(sidx)
self.set_combobox.currentIndexChanged.emit(sidx) self.set_combobox.currentIndexChanged.emit(sidx)
@QtCore.pyqtSlot(int) self.values_selected.emit(old_figure, self.connected_figure)
@QtCore.pyqtSlot(int, name='on_set_combobox_currentIndexChanged')
def _populate_table(self, idx): def _populate_table(self, idx):
self.selection_model.clearSelection() self.selection_model.clearSelection()
self.shown_set = self.set_combobox.itemData(idx) self.shown_set = self.set_combobox.itemData(idx)
self.requestData.emit(self.set_combobox.itemData(idx)) self.requestData.emit(self.set_combobox.itemData(idx))
def set_data(self, data: list, mask: np.ndarray): def set_data(self, data: list, mask: ndarray):
self.selection_model.clearSelection() self.selection_model.clearSelection()
self.model.loadData(data, mask) self.model.loadData(data, mask)
self.spinBox.setMaximum(self.model.rowCount()) self.spinBox.setMaximum(self.model.rowCount())
@ -193,9 +199,16 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
try: try:
yvals.append(float(self.model.data(idx.sibling(idx.row(), 1)))) yvals.append(float(self.model.data(idx.sibling(idx.row(), 1))))
except ValueError: except ValueError:
yvals.append(complex(self.model.data(idx.sibling(idx.row(), 1))).real) yvals.append(complex(self.model.data(idx.sibling(idx.row(), 1))))
self.values_selected.emit(self.connected_figure, xvals, yvals) yvals = asarray(yvals)
if iscomplexobj(yvals):
self.selection_real.setData(x=xvals, y=yvals.real)
self.selection_imag.setData(x=xvals, y=yvals.imag)
else:
self.selection_real.setData(x=xvals, y=yvals)
self.selection_imag.setData(x=[], y=[])
@QtCore.pyqtSlot(name='on_toolButton_clicked') @QtCore.pyqtSlot(name='on_toolButton_clicked')
def goto(self): def goto(self):
@ -227,7 +240,7 @@ class ValueModel(QtCore.QAbstractTableModel):
def columnCount(self, *args, **kwargs) -> int: def columnCount(self, *args, **kwargs) -> int:
return len(self.headers) return len(self.headers)
def loadData(self, data: list[np.ndarray], mask: np.ndarray): def loadData(self, data: list[ndarray], mask: ndarray):
self.beginResetModel() self.beginResetModel()
self._data = [] self._data = []
for x, y, y_err in zip(*data): for x, y, y_err in zip(*data):

View File

@ -5,11 +5,13 @@ import os
import uuid import uuid
from math import isnan from math import isnan
from pathlib import Path
from numpy import errstate, floor, log10 from numpy import errstate, floor, log10
from pyqtgraph import GraphicsObject, getConfigOption, mkColor from pyqtgraph import GraphicsObject, getConfigOption, mkColor
from nmreval.utils.text import convert from nmreval.utils.text import convert
from ..io.filedialog import FileDialog
from ..lib.pg_objects import LegendItemBlock, RegionItem from ..lib.pg_objects import LegendItemBlock, RegionItem
from ..Qt import QtCore, QtWidgets, QtGui from ..Qt import QtCore, QtWidgets, QtGui
@ -524,64 +526,67 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow):
str_format = imgformat.data().decode('utf-8') str_format = imgformat.data().decode('utf-8')
filters += ';;' + str_format.upper() + ' (*.' + str_format + ')' filters += ';;' + str_format.upper() + ' (*.' + str_format + ')'
outfile, _ = QtWidgets.QFileDialog.getSaveFileName(self, caption='Export graphic', filter=filters, outfile = None
options=QtWidgets.QFileDialog.DontConfirmOverwrite) f = FileDialog(caption='Export graphic', filters=filters)
mode = f.exec()
if mode == QtWidgets.QDialog.Accepted:
outfile = f.save_file()
if outfile: if outfile:
self.export(outfile) self.export(outfile)
def export(self, outfile: str): def export(self, outfile: Path):
_, suffix = os.path.splitext(outfile) suffix = outfile.suffix
if suffix == '': if suffix == '':
QtWidgets.QMessageBox.warning(self, 'No file extension', QtWidgets.QMessageBox.warning(self, 'No file extension',
'No file extension found, graphic was not saved.') 'No file extension found, graphic was not saved.')
return return
if suffix == '.agr': if suffix == '.agr':
res = 0 res = 0
if os.path.exists(outfile): if outfile.exists():
res = GraceMsgBox(outfile, parent=self).exec() res = GraceMsgBox(outfile, parent=self).exec()
if res == -1: if res == -1:
return return
opts = self.export_graphics() opts = self.export_graphics()
from ..io.exporters import GraceExporter from ..io.exporters import GraceExporter
if res == 0: if res == 0:
mode = 'w' mode = 'w'
elif res == 1: elif res == 1:
mode = 'a' mode = 'a'
else: else:
mode = res-2 mode = res-2
GraceExporter(opts).export(outfile, mode=mode) GraceExporter(opts).export(outfile, mode=mode)
else:
if os.path.exists(outfile):
if QtWidgets.QMessageBox.warning(self, 'Export graphic',
f'{os.path.split(outfile)[1]} already exists.\n'
f'Do you REALLY want to replace it?',
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No:
return
bg_color = self._bgcolor
fg_color = self._fgcolor
self.set_color(foreground='k', background='w')
if suffix == '.pdf':
from ..io.exporters import PDFPrintExporter
PDFPrintExporter(self.graphic).export(outfile)
elif suffix == '.svg':
from pyqtgraph.exporters import SVGExporter
SVGExporter(self.scene).export(outfile)
else: else:
if os.path.exists(outfile): from pyqtgraph.exporters import ImageExporter
if QtWidgets.QMessageBox.warning(self, 'Export graphic',
f'{os.path.split(outfile)[1]} already exists.\n'
f'Do you REALLY want to replace it?',
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No:
return
bg_color = self._bgcolor ImageExporter(self.scene).export(outfile)
fg_color = self._fgcolor
self.set_color(foreground='k', background='w')
if suffix == '.pdf': self.set_color(foreground=fg_color, background=bg_color)
from ..io.exporters import PDFPrintExporter
PDFPrintExporter(self.graphic).export(outfile)
elif suffix == '.svg':
from pyqtgraph.exporters import SVGExporter
SVGExporter(self.scene).export(outfile)
else:
from pyqtgraph.exporters import ImageExporter
ImageExporter(self.scene).export(outfile)
self.set_color(foreground=fg_color, background=bg_color)
def export_graphics(self) -> dict: def export_graphics(self) -> dict:
dic = self.get_state() dic = self.get_state()

View File

@ -18,7 +18,7 @@ class QAsciiReader(QtWidgets.QDialog, Ui_ascii_reader):
pal = QtWidgets.QApplication.instance().palette() pal = QtWidgets.QApplication.instance().palette()
rgb = pal.color(pal.Base).getRgb()[:3] rgb = pal.color(pal.Base).getRgb()[:3]
rgb2 = pal.color(pal.Text).getRgb()[:3] rgb2 = pal.color(pal.Text).getRgb()[:3]
self.plainTextEdit_2.setStyleSheet(f'QPlainTextEdit {{ background-color: rgb{rgb} ; color: rgb{rgb2}; }}') self.comment_textfield.setStyleSheet(f'Qdelay_textfield {{ background-color: rgb{rgb} ; color: rgb{rgb2}; }}')
self.ascii_table.horizontalHeader().setStretchLastSection(True) self.ascii_table.horizontalHeader().setStretchLastSection(True)
self.buttonbox.button(QtWidgets.QDialogButtonBox.Apply).clicked.connect(self.apply) self.buttonbox.button(QtWidgets.QDialogButtonBox.Apply).clicked.connect(self.apply)
@ -31,13 +31,12 @@ class QAsciiReader(QtWidgets.QDialog, Ui_ascii_reader):
self.ascii_table.horizontalHeader().customContextMenuRequested.connect(self.ctx_table) self.ascii_table.horizontalHeader().customContextMenuRequested.connect(self.ctx_table)
def __call__(self, fname, *args, **kwargs): def __call__(self, fname, *args, **kwargs):
for i in [self.stag_lineEdit, self.start_lineedit, self.end_lineedit, for i in [self.stag_lineEdit, self.start_lineedit, self.end_lineedit,
self.plainTextEdit_2, self.ascii_table, self.delay_lineedit]: self.comment_textfield, self.ascii_table, self.delay_lineedit]:
i.clear() i.clear()
self.checkBox_2.setChecked(False) self.staggered_checkBox.setChecked(False)
self.checkBox.setChecked(False) self.log_checkBox.setChecked(False)
self.plainTextEdit_2.show() self.comment_textfield.show()
self.reader = AsciiReader(fname) self.reader = AsciiReader(fname)
self.set_gui() self.set_gui()
@ -53,7 +52,7 @@ class QAsciiReader(QtWidgets.QDialog, Ui_ascii_reader):
def set_gui(self): def set_gui(self):
for text in self.reader.header: for text in self.reader.header:
self.plainTextEdit_2.appendPlainText(text) self.comment_textfield.appendPlainText(text)
self.ascii_table.setRowCount(self.reader.shape[0]) self.ascii_table.setRowCount(self.reader.shape[0])
self.ascii_table.setColumnCount(self.reader.shape[1]) self.ascii_table.setColumnCount(self.reader.shape[1])
@ -62,7 +61,7 @@ class QAsciiReader(QtWidgets.QDialog, Ui_ascii_reader):
if len(last_header_line) == self.reader.shape[1]: if len(last_header_line) == self.reader.shape[1]:
self.ascii_table.setHorizontalHeaderLabels(last_header_line) self.ascii_table.setHorizontalHeaderLabels(last_header_line)
except IndexError: except IndexError:
self.plainTextEdit_2.hide() self.comment_textfield.hide()
for i, line in enumerate(self.reader.data): for i, line in enumerate(self.reader.data):
for j, field in enumerate(line): for j, field in enumerate(line):
@ -73,7 +72,7 @@ class QAsciiReader(QtWidgets.QDialog, Ui_ascii_reader):
if self.reader.delays is not None: if self.reader.delays is not None:
set_string = ''.join(str(d) + '\n' for d in self.reader.delays) set_string = ''.join(str(d) + '\n' for d in self.reader.delays)
self.plainTextEdit.setPlainText(set_string) self.delay_textfield.setPlainText(set_string)
self.delay_lineedit.setText(str(len(self.reader.delays))) self.delay_lineedit.setText(str(len(self.reader.delays)))
def ctx_table(self, _): def ctx_table(self, _):
@ -92,7 +91,7 @@ class QAsciiReader(QtWidgets.QDialog, Ui_ascii_reader):
def set_columns(self, mode): def set_columns(self, mode):
cols = ' '.join([str(s.column()+1) for s in self.ascii_table.selectionModel().selectedColumns()]) cols = ' '.join([str(s.column()+1) for s in self.ascii_table.selectionModel().selectedColumns()])
try: try:
lineedit = {'x': self.x_lineedit, 'y': self.y_lineedit, 'yerr': self.lineEdit}[mode] lineedit = {'x': self.x_lineedit, 'y': self.y_lineedit, 'yerr': self.deltay_lineEdit}[mode]
lineedit.setText(cols) lineedit.setText(cols)
except KeyError: except KeyError:
pass pass
@ -109,19 +108,19 @@ class QAsciiReader(QtWidgets.QDialog, Ui_ascii_reader):
@QtCore.pyqtSlot(name='on_pushButton_clicked') @QtCore.pyqtSlot(name='on_pushButton_clicked')
def calc_delays(self): def calc_delays(self):
self.reader.calc_delays(float(self.start_lineedit.text()), float(self.end_lineedit.text()), self.reader.calc_delays(float(self.start_lineedit.text()), float(self.end_lineedit.text()),
int(self.delay_lineedit.text()), log=self.checkBox.isChecked(), int(self.delay_lineedit.text()), log=self.log_checkBox.isChecked(),
stagg=self.checkBox_2.isChecked(), stag_size=int(self.stag_lineEdit.text())) stagg=self.staggered_checkBox.isChecked(), stag_size=int(self.stag_lineEdit.text()))
set_string = ''.join(str(d) + '\n' for d in self.reader.delays) set_string = ''.join(str(d) + '\n' for d in self.reader.delays)
self.plainTextEdit.setPlainText(set_string) self.delay_textfield.setPlainText(set_string)
def update_header(self, text, comment='#'): def update_header(self, text, comment='#'):
text = text.replace(comment, '').lstrip().rstrip() text = text.replace(comment, '').lstrip().rstrip()
self.plainTextEdit_2.appendPlainText(text) self.comment_textfield.appendPlainText(text)
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def on_plainTextEdit_textChanged(self): def on_delay_textfield_textChanged(self):
new_delays = str(self.plainTextEdit.toPlainText()).rstrip('\n').split('\n') new_delays = str(self.delay_textfield.toPlainText()).rstrip('\n').split('\n')
self.delay_lineedit.setText(str(len(new_delays))) self.delay_lineedit.setText(str(len(new_delays)))
if new_delays[0] == '': if new_delays[0] == '':
new_delays = None new_delays = None
@ -150,7 +149,7 @@ class QAsciiReader(QtWidgets.QDialog, Ui_ascii_reader):
except ValueError: except ValueError:
y = None y = None
try: try:
y_err = [int(t)-1 for t in str(self.lineEdit.text()).split(' ')] y_err = [int(t)-1 for t in str(self.deltay_lineEdit.text()).split(' ')]
except ValueError: except ValueError:
y_err = None y_err = None
@ -179,7 +178,7 @@ class QAsciiReader(QtWidgets.QDialog, Ui_ascii_reader):
if val == -2: if val == -2:
self.widget.show() self.widget.show()
else: else:
self.lineEdit.setText('') self.deltay_lineEdit.setText('')
self.widget.hide() self.widget.hide()
@QtCore.pyqtSlot(int, name='on_skippy_checkbox_stateChanged') @QtCore.pyqtSlot(int, name='on_skippy_checkbox_stateChanged')

View File

@ -1,5 +1,7 @@
from __future__ import annotations from __future__ import annotations
from pathlib import Path
from numpy import c_ from numpy import c_
from nmreval.io.graceeditor import GraceEditor from nmreval.io.graceeditor import GraceEditor
@ -13,7 +15,7 @@ class GraceExporter:
self.__agr = None self.__agr = None
self.__opts = kwargs self.__opts = kwargs
def export(self, outfile: str, mode: int | str = 'w'): def export(self, outfile: str | Path, mode: int | str = 'w'):
if mode == 'w': if mode == 'w':
self.__agr = GraceEditor() self.__agr = GraceEditor()
else: else:

View File

@ -5,14 +5,17 @@ import pathlib
from ..Qt import QtWidgets, QtCore from ..Qt import QtWidgets, QtCore
class _FileDialog(QtWidgets.QFileDialog): class FileDialog(QtWidgets.QFileDialog):
last_path = None
def __init__(self, directory=None, caption=None, filters='', parent=None): def __init__(self, directory=None, caption=None, filters='', parent=None):
super().__init__(parent=parent) super().__init__(parent=parent)
self.setOption(QtWidgets.QFileDialog.DontUseNativeDialog, True) self.setOption(QtWidgets.QFileDialog.DontUseNativeDialog, True)
self.setWindowTitle(caption) self.setWindowTitle(caption)
self.setDirectory(str(directory)) if directory is not None:
self.setDirectory(str(directory))
self.setNameFilters(filters.split(';;')) self.setNameFilters(filters.split(';;'))
file_tree = self.findChild(QtWidgets.QTreeView, 'treeView') file_tree = self.findChild(QtWidgets.QTreeView, 'treeView')
@ -29,8 +32,14 @@ class _FileDialog(QtWidgets.QFileDialog):
line.setFrameShadow(line.Sunken) line.setFrameShadow(line.Sunken)
self.layout().addWidget(line, self.layout().rowCount(), 0, 1, self.layout().columnCount()) self.layout().addWidget(line, self.layout().rowCount(), 0, 1, self.layout().columnCount())
def save_file(self) -> pathlib.Path | None:
outfile = self.selectedFiles()
if outfile:
return pathlib.Path(outfile[0])
return
class OpenFileDialog(_FileDialog):
class OpenFileDialog(FileDialog):
def __init__(self, directory=None, caption=None, filters='', parent=None): def __init__(self, directory=None, caption=None, filters='', parent=None):
super().__init__(directory=directory, caption=caption, filters=filters, parent=parent) super().__init__(directory=directory, caption=caption, filters=filters, parent=parent)
@ -71,7 +80,7 @@ class OpenFileDialog(_FileDialog):
self.add_to_graph = self.comboBox.itemData(idx) self.add_to_graph = self.comboBox.itemData(idx)
class SaveDirectoryDialog(_FileDialog): class SaveDirectoryDialog(FileDialog):
def __init__(self, directory=None, filters='', parent=None): def __init__(self, directory=None, filters='', parent=None):
super().__init__(directory=directory, filters=filters, parent=parent) super().__init__(directory=directory, filters=filters, parent=parent)
@ -115,8 +124,3 @@ class SaveDirectoryDialog(_FileDialog):
self.setNameFilters(['All files (*.*)', 'Session file (*.nmr)', 'Text file (*.dat)', self.setNameFilters(['All files (*.*)', 'Session file (*.nmr)', 'Text file (*.dat)',
'HDF file (*.h5)', 'Grace files (*.agr)']) 'HDF file (*.h5)', 'Grace files (*.agr)'])
def save_file(self) -> pathlib.Path | None:
outfile = self.selectedFiles()
if outfile:
return pathlib.Path(outfile[0])
return

View File

@ -101,9 +101,6 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
self.statusBar.addWidget(self.mousepos) self.statusBar.addWidget(self.mousepos)
self.fitregion = RegionItem() self.fitregion = RegionItem()
self._values_plot = PlotDataItem(x=[], y=[], symbolSize=30, symbol='x',
pen=None, symbolPen='#d526b5', symbolBrush='#d526b5')
self._fit_plot_id = None self._fit_plot_id = None
self.setGeometry(QtWidgets.QStyle.alignedRect(QtCore.Qt.LeftToRight, QtCore.Qt.AlignCenter, self.setGeometry(QtWidgets.QStyle.alignedRect(QtCore.Qt.LeftToRight, QtCore.Qt.AlignCenter,
@ -530,12 +527,14 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
def _select_valuewidget(self, onoff: bool): def _select_valuewidget(self, onoff: bool):
if onoff: # Values if onoff: # Values
self.valuewidget(self.management.graphs.tree()) self.valuewidget(self.management.graphs.tree())
self.valuewidget.connected_figure = self.management.current_graph current_graph = self.valuewidget.connected_figure
if self.valuewidget.connected_figure is not None: if current_graph is not None:
self.management.graphs[self.valuewidget.connected_figure].add_external(self._values_plot) self.management.graphs[current_graph].add_external(self.valuewidget.selection_real)
self.management.graphs[current_graph].add_external(self.valuewidget.selection_imag)
else: else:
if self.valuewidget.connected_figure is not None: if self.valuewidget.connected_figure is not None:
self.management.graphs[self.valuewidget.connected_figure].remove_external(self._values_plot) self.management.graphs[self.valuewidget.connected_figure].remove_external(self.valuewidget.selection_real)
self.management.graphs[self.valuewidget.connected_figure].remove_external(self.valuewidget.selection_imag)
def _select_integralwidget(self, onoff: bool, pick_required: bool, block_window: bool) -> tuple[bool, bool]: def _select_integralwidget(self, onoff: bool, pick_required: bool, block_window: bool) -> tuple[bool, bool]:
if self.current_graph_widget is None: if self.current_graph_widget is None:
@ -777,12 +776,12 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
data, mask = self.management.get_data(sid) data, mask = self.management.get_data(sid)
self.valuewidget.set_data(data, mask) self.valuewidget.set_data(data, mask)
def plot_selected_values(self, gid: str, x: list, y: list): def plot_selected_values(self, old_gid: str, new_gid: str):
self._values_plot.setData(x=x, y=y) for pts in (self.valuewidget.selection_real, self.valuewidget.selection_imag):
if gid != self.valuewidget.connected_figure and self.valuewidget.connected_figure is not None: if old_gid:
self.management.graphs[self.valuewidget.connected_figure].remove_external(self._values_plot) self.management.graphs[old_gid].remove_external(pts)
self.management.graphs[gid].add_external(self._values_plot) if new_gid:
self.valuewidget.connected_figure = gid self.management.graphs[new_gid].add_external(pts)
@QtCore.pyqtSlot(object, str) @QtCore.pyqtSlot(object, str)
def item_to_graph(self, item, graph_id): def item_to_graph(self, item, graph_id):

View File

@ -9,12 +9,13 @@ from nmreval.fit import data as fit_d
from nmreval.fit.model import Model from nmreval.fit.model import Model
from nmreval.fit.result import FitResult from nmreval.fit.result import FitResult
from nmreval.fit.minimizer import FitRoutine from nmreval.fit.minimizer import FitRoutine
from nmreval.lib.colors import TUColorsC, available_cycles from nmreval.lib.colors import available_cycles
from nmreval.math.interpol import interpolate from nmreval.math.interpol import interpolate
from nmreval.math.logfourier import logft from nmreval.math.logfourier import logft
from nmreval.math.smooth import smooth from nmreval.math.smooth import smooth
from nmreval.nmr.relaxation import Relaxation from nmreval.nmr.relaxation import Relaxation
from ..Qt import QtCore, QtWidgets
from ..lib.undos import * from ..lib.undos import *
from ..data.container import * from ..data.container import *
from ..io.filereaders import QFileReader from ..io.filereaders import QFileReader
@ -112,6 +113,8 @@ class UpperManagement(QtCore.QObject):
self.undostack = QtWidgets.QUndoStack() self.undostack = QtWidgets.QUndoStack()
self.deleteData.connect(self.plot_from_graph) self.deleteData.connect(self.plot_from_graph)
self._filereader = None
def __setitem__(self, key: str, value, **kwargs): def __setitem__(self, key: str, value, **kwargs):
if isinstance(value, ExperimentContainer): if isinstance(value, ExperimentContainer):
item = value item = value
@ -148,7 +151,9 @@ class UpperManagement(QtCore.QObject):
return _id return _id
def load_files(self, fname: List[str], new_plot: str = None): def load_files(self, fname: List[str], new_plot: str = None):
ret_dic = QFileReader(manager=self).readfiles(fname) if self._filereader is None:
self._filereader = QFileReader(manager=self)
ret_dic = self._filereader.readfiles(fname)
self.add_new_data(ret_dic, new_plot) self.add_new_data(ret_dic, new_plot)
def _load_session(self, sets: dict, graphs: dict): def _load_session(self, sets: dict, graphs: dict):
@ -1000,9 +1005,9 @@ class UpperManagement(QtCore.QObject):
if opts['axis1'] in ['t', 'invt1000']: if opts['axis1'] in ['t', 'invt1000']:
t_p = opts['t_param'] t_p = opts['t_param']
if len(t_p) == 2: if len(t_p) == 2:
from ...models import Arrhenius as Func from nmreval.models import Arrhenius as Func
else: else:
from ...models import VFT as Func from nmreval.models import VFT as Func
_x = Func.func(x1, *t_p, invt=opts['axis1']) _x = Func.func(x1, *t_p, invt=opts['axis1'])
@ -1078,7 +1083,7 @@ class UpperManagement(QtCore.QObject):
raise ValueError('No file extension detected') raise ValueError('No file extension detected')
if suffix == '.nmr': if suffix == '.nmr':
from ...io.sessionwriter import NMRWriter from nmreval.io.sessionwriter import NMRWriter
NMRWriter(self.graphs, self.data).export(path) NMRWriter(self.graphs, self.data).export(path)
return return

View File

@ -105,6 +105,7 @@ class AsciiReader:
if mode == 'Points': if mode == 'Points':
try: try:
# TODO read errors correctly
for k in range(1, raw_data.shape[2]): for k in range(1, raw_data.shape[2]):
if raw_data.shape[2] < 3: if raw_data.shape[2] < 3:
name = only_f name = only_f

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pathlib import pathlib
import re import re
from io import StringIO from io import StringIO
@ -93,7 +95,7 @@ class GraceEditor:
return s return s
def parse(self, filename): def parse(self, filename: str | pathlib.Path):
self.file = pathlib.Path(filename) self.file = pathlib.Path(filename)
# we start always with the header # we start always with the header

View File

@ -24,11 +24,20 @@
<string>Data</string> <string>Data</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
<property name="margin"> <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> <number>0</number>
</property> </property>
<item> <item>
<widget class="QPlainTextEdit" name="plainTextEdit_2"> <widget class="QPlainTextEdit" name="comment_textfield">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -76,7 +85,7 @@
</attribute> </attribute>
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<item> <item>
<widget class="QPlainTextEdit" name="plainTextEdit"/> <widget class="QPlainTextEdit" name="delay_textfield"/>
</item> </item>
<item> <item>
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
@ -123,7 +132,7 @@
<widget class="QLineEdit" name="end_lineedit"/> <widget class="QLineEdit" name="end_lineedit"/>
</item> </item>
<item row="3" column="0" colspan="2"> <item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="checkBox"> <widget class="QCheckBox" name="log_checkBox">
<property name="layoutDirection"> <property name="layoutDirection">
<enum>Qt::LeftToRight</enum> <enum>Qt::LeftToRight</enum>
</property> </property>
@ -133,7 +142,7 @@
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="4" column="0">
<widget class="QCheckBox" name="checkBox_2"> <widget class="QCheckBox" name="staggered_checkBox">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred"> <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -243,7 +252,16 @@
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
<property name="margin"> <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> <number>0</number>
</property> </property>
<item> <item>
@ -267,7 +285,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLineEdit" name="lineEdit"/> <widget class="QLineEdit" name="deltay_lineEdit"/>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -303,7 +321,7 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QRadioButton" name="radioButton"> <widget class="QRadioButton" name="pts_radioButton">
<property name="text"> <property name="text">
<string>Points</string> <string>Points</string>
</property> </property>
@ -319,7 +337,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QRadioButton" name="radioButton_2"> <widget class="QRadioButton" name="FID_radioButton">
<property name="text"> <property name="text">
<string>FID</string> <string>FID</string>
</property> </property>
@ -332,7 +350,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QRadioButton" name="radioButton_3"> <widget class="QRadioButton" name="spectrum_radioButton">
<property name="text"> <property name="text">
<string>Spectrum</string> <string>Spectrum</string>
</property> </property>