dialog to create fit functions
This commit is contained in:
parent
f05d28f6e6
commit
71f8871445
@ -2,7 +2,7 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'src/resources/_ui/basewindow.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.7
|
||||
# Created by: PyQt5 UI code generator 5.15.2
|
||||
#
|
||||
# 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.
|
||||
@ -75,7 +75,7 @@ class Ui_BaseWindow(object):
|
||||
self.horizontalLayout.addWidget(self.splitter)
|
||||
BaseWindow.setCentralWidget(self.centralwidget)
|
||||
self.menubar = QtWidgets.QMenuBar(BaseWindow)
|
||||
self.menubar.setGeometry(QtCore.QRect(0, 0, 1386, 20))
|
||||
self.menubar.setGeometry(QtCore.QRect(0, 0, 1386, 24))
|
||||
self.menubar.setObjectName("menubar")
|
||||
self.menuFile = QtWidgets.QMenu(self.menubar)
|
||||
self.menuFile.setObjectName("menuFile")
|
||||
@ -413,7 +413,6 @@ class Ui_BaseWindow(object):
|
||||
self.menuFit.addAction(self.action_create_fit_function)
|
||||
self.menuFit.addAction(self.actionFunction_editor)
|
||||
self.menuFit.addSeparator()
|
||||
self.menuFit.addAction(self.actionShow_fit_parameter)
|
||||
self.menuFit.addAction(self.menuMethod.menuAction())
|
||||
self.menuFit.addAction(self.menuLimits.menuAction())
|
||||
self.menuOptions.addAction(self.actionMouse_behaviour)
|
||||
@ -480,7 +479,7 @@ class Ui_BaseWindow(object):
|
||||
|
||||
self.retranslateUi(BaseWindow)
|
||||
self.tabWidget.setCurrentIndex(0)
|
||||
self.action_close.triggered.connect(BaseWindow.close) # type: ignore
|
||||
self.action_close.triggered.connect(BaseWindow.close)
|
||||
QtCore.QMetaObject.connectSlotsByName(BaseWindow)
|
||||
|
||||
def retranslateUi(self, BaseWindow):
|
||||
|
@ -2,7 +2,8 @@ from __future__ import annotations
|
||||
|
||||
import inspect
|
||||
import numbers
|
||||
import textwrap
|
||||
import pathlib
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
import numpy as np
|
||||
@ -14,15 +15,18 @@ from gui_qt.lib.namespace import QNamespaceWidget
|
||||
__all__ = ['QUserFitCreator']
|
||||
|
||||
validator = QtGui.QRegExpValidator(QtCore.QRegExp('[A-Za-z]\S*'))
|
||||
pattern = re.compile(r'def func\(.*\):', flags=re.MULTILINE)
|
||||
|
||||
|
||||
class QUserFitCreator(QtWidgets.QDialog, Ui_Dialog):
|
||||
classCreated = QtCore.pyqtSignal(object)
|
||||
classCreated = QtCore.pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
def __init__(self, filepath: str|pathlib.Path, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.setupUi(self)
|
||||
|
||||
self.filepath = pathlib.Path(filepath)
|
||||
|
||||
self.description_widget = DescWidget(self)
|
||||
self.args_widget = ArgWidget(self)
|
||||
self.kwargs_widget = KwargsWidget(self)
|
||||
@ -44,10 +48,23 @@ class QUserFitCreator(QtWidgets.QDialog, Ui_Dialog):
|
||||
|
||||
self.update_function()
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
def __call__(self, filepath: str|pathlib.Path):
|
||||
self.filepath = pathlib.Path(filepath)
|
||||
|
||||
return self
|
||||
|
||||
def update_function(self):
|
||||
prev_text = self.plainTextEdit.toPlainText().split('\n')
|
||||
func_body = ''
|
||||
in_body = False
|
||||
for line in prev_text:
|
||||
if in_body:
|
||||
func_body += line
|
||||
continue
|
||||
|
||||
if pattern.search(line) is not None:
|
||||
in_body = True
|
||||
|
||||
try:
|
||||
var = self.args_widget.get_parameter()
|
||||
var += self.kwargs_widget.get_parameter()
|
||||
@ -67,7 +84,12 @@ class QUserFitCreator(QtWidgets.QDialog, Ui_Dialog):
|
||||
k += self.kwargs_widget.get_strings()
|
||||
|
||||
k += '\n @staticmethod\n'
|
||||
k += f" def func(x, {', '.join(var)}):\n"
|
||||
if var:
|
||||
k += f" def func(x, {', '.join(var)}):\n"
|
||||
else:
|
||||
k += f' def func(x):\n'
|
||||
|
||||
k += func_body
|
||||
|
||||
self.plainTextEdit.setPlainText(k)
|
||||
except Exception as e:
|
||||
@ -85,6 +107,7 @@ class QUserFitCreator(QtWidgets.QDialog, Ui_Dialog):
|
||||
ns = self.namespace_widget.namespace.namespace
|
||||
func_value = ns[invalue][0]
|
||||
ret_func = ''
|
||||
import_name = ''
|
||||
|
||||
if func_value is None:
|
||||
ret_func = invalue
|
||||
@ -99,15 +122,28 @@ class QUserFitCreator(QtWidgets.QDialog, Ui_Dialog):
|
||||
else:
|
||||
f_string = ns[invalue][-1]
|
||||
args = f_string[f_string.find('('):]
|
||||
|
||||
if inspect.ismethod(func_value):
|
||||
ret_func = func_value.__self__.__name__ + '.func'+args
|
||||
import_name = func_value.__self__.__name__
|
||||
|
||||
elif hasattr(func_value, '__qualname__'):
|
||||
ret_func = func_value.__qualname__.split('.')[0]
|
||||
self._imports.add((inspect.getmodule(func_value).__name__, ret_func))
|
||||
import_name = func_value.__qualname__.split('.')[0]
|
||||
ret_func = func_value.__qualname__ + args
|
||||
|
||||
self._imports.add((inspect.getmodule(func_value).__name__, import_name))
|
||||
|
||||
self.plainTextEdit.insertPlainText(ret_func)
|
||||
self.update_function()
|
||||
|
||||
def accept(self):
|
||||
# maybe add a check for correctness
|
||||
|
||||
with self.filepath.open('a') as f:
|
||||
f.write('\n\n')
|
||||
f.write(self.plainTextEdit.toPlainText())
|
||||
self.classCreated.emit()
|
||||
super().accept()
|
||||
|
||||
class KwargsWidget(QtWidgets.QWidget):
|
||||
Changed = QtCore.pyqtSignal()
|
||||
@ -363,7 +399,7 @@ class ArgWidget(QtWidgets.QWidget):
|
||||
|
||||
return var
|
||||
|
||||
def get_strings(self):
|
||||
def get_strings(self) -> str:
|
||||
args = []
|
||||
bnds = []
|
||||
for row in range(self.table.rowCount()):
|
||||
@ -434,7 +470,7 @@ class DescWidget(QtWidgets.QWidget):
|
||||
raise ValueError('Class name is empty')
|
||||
stringi = f'class {self.klass_lineedit.text()}:\n' \
|
||||
f' name = {self.name_lineedit.text()!r}\n' \
|
||||
f' group = {self.group_lineedit.text()!r}\n' \
|
||||
f' type = {self.group_lineedit.text()!r}\n' \
|
||||
f' equation = {self.eq_lineedit.text()!r}\n'
|
||||
|
||||
return stringi
|
||||
|
@ -13,7 +13,7 @@ import requests
|
||||
from numpy import linspace
|
||||
from scipy.interpolate import interp1d
|
||||
|
||||
from gui_qt.Qt import QtGui, QtWidgets, QtCore
|
||||
from ..Qt import QtGui, QtWidgets, QtCore
|
||||
|
||||
|
||||
@contextmanager
|
||||
|
@ -917,6 +917,16 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
|
||||
self.editor.setWindowModality(QtCore.Qt.ApplicationModal)
|
||||
self.editor.show()
|
||||
|
||||
@QtCore.pyqtSlot(name='on_action_create_fit_function_triggered')
|
||||
def open_fitmodel_wizard(self):
|
||||
from ..fit.function_creation_dialog import QUserFitCreator
|
||||
|
||||
helper = QUserFitCreator(config_paths() / 'usermodels.py', parent=self)
|
||||
helper.classCreated.connect(lambda: self.fit_dialog.read_and_load_functions())
|
||||
|
||||
helper.show()
|
||||
|
||||
|
||||
@QtCore.pyqtSlot(name='on_actionShift_triggered')
|
||||
def shift_dialog(self):
|
||||
s = QShift(self)
|
||||
|
@ -136,7 +136,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1386</width>
|
||||
<height>20</height>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
@ -251,7 +251,6 @@
|
||||
<addaction name="action_create_fit_function"/>
|
||||
<addaction name="actionFunction_editor"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionShow_fit_parameter"/>
|
||||
<addaction name="menuMethod"/>
|
||||
<addaction name="menuLimits"/>
|
||||
</widget>
|
||||
|
Loading…
Reference in New Issue
Block a user