work on ui

This commit is contained in:
Dominik Demuth 2023-09-11 18:09:08 +02:00
parent 5e55f06723
commit e4dbaf2b91
7 changed files with 62 additions and 164 deletions

View File

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'resources/_ui/fitmodelwidget.ui'
# Form implementation generated from reading ui file 'src/resources/_ui/fitmodelwidget.ui'
#
# Created by: PyQt5 UI code generator 5.12.3
# Created by: PyQt5 UI code generator 5.15.9
#
# 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_FitParameter(object):
def setupUi(self, FitParameter):
FitParameter.setObjectName("FitParameter")
FitParameter.resize(365, 78)
FitParameter.resize(365, 66)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -36,7 +37,7 @@ class Ui_FitParameter(object):
self.parametername.setObjectName("parametername")
self.horizontalLayout_2.addWidget(self.parametername)
self.parameter_line = LineEdit(FitParameter)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.parameter_line.sizePolicy().hasHeightForWidth())
@ -44,20 +45,12 @@ class Ui_FitParameter(object):
self.parameter_line.setText("")
self.parameter_line.setObjectName("parameter_line")
self.horizontalLayout_2.addWidget(self.parameter_line)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(spacerItem)
self.fixed_check = QtWidgets.QCheckBox(FitParameter)
self.fixed_check.setObjectName("fixed_check")
self.horizontalLayout_2.addWidget(self.fixed_check)
self.global_checkbox = QtWidgets.QCheckBox(FitParameter)
self.global_checkbox.setObjectName("global_checkbox")
self.horizontalLayout_2.addWidget(self.global_checkbox)
self.toolButton = QtWidgets.QToolButton(FitParameter)
self.toolButton.setText("")
self.toolButton.setPopupMode(QtWidgets.QToolButton.InstantPopup)
self.toolButton.setArrowType(QtCore.Qt.RightArrow)
self.toolButton.setObjectName("toolButton")
self.horizontalLayout_2.addWidget(self.toolButton)
self.verticalLayout.addLayout(self.horizontalLayout_2)
self.frame = QtWidgets.QFrame(FitParameter)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)

View File

@ -19,16 +19,16 @@ class FitModelWidget(QtWidgets.QWidget, Ui_FitParameter):
self.parametername.setText(label + ' ')
# self.parameter_line.setValidator(validator)
self.parameter_line.setText('1')
self.parameter_line.setMaximumWidth(60)
self.lineEdit.setMaximumWidth(60)
self.lineEdit_2.setMaximumWidth(60)
self.parameter_line.setMaximumWidth(160)
self.lineEdit.setMaximumWidth(100)
self.lineEdit_2.setMaximumWidth(100)
self.label_3.setText(f'< {label} <')
self.checkBox.stateChanged.connect(self.enableBounds)
self.global_checkbox.stateChanged.connect(lambda: self.state_changed.emit())
self.parameter_line.editingFinished.connect(self.update_parameter)
self.parameter_line.values_requested.connect(lambda: self.value_requested.emit(self))
self.parameter_line.editingFinished.connect(lambda: self.value_changed.emit(self.parameter_line.text()))
self.fixed_check.toggled.connect(self.set_fixed)
@ -36,20 +36,12 @@ class FitModelWidget(QtWidgets.QWidget, Ui_FitParameter):
if fixed:
self.fixed_check.hide()
self.is_linked = None
self.parameter_pos = None
self.func_idx = None
self._linetext = '1'
self.completer = QtWidgets.QCompleter()
self.completer.setCompletionMode(QtWidgets.QCompleter.UnfilteredPopupCompletion)
self.parameter_hint_model = QtGui.QStandardItemModel()
self.completer.setModel(self.parameter_hint_model)
self.parameter_line.setCompleter(self.completer)
self.menu = QtWidgets.QMenu(self)
self.add_links()
@property
def name(self):
@ -73,39 +65,24 @@ class FitModelWidget(QtWidgets.QWidget, Ui_FitParameter):
def set_parameter(self, p: float | None, bds: tuple[float, float, bool] = None,
fixed: bool = None, glob: bool = None):
if p is None:
# bad hack: linked parameter return (None, linked parameter)
# if p is None -> parameter is linked to argument given by bds
self.link_parameter(linkto=bds)
else:
ptext = f'{p:.4g}'
ptext = f'{p:.4g}'
self.set_parameter_string(ptext)
self.set_parameter_string(ptext)
if bds is not None:
self.set_bounds(*bds)
if bds is not None:
self.set_bounds(*bds)
if fixed is not None:
self.fixed_check.setCheckState(QtCore.Qt.Unchecked if fixed else QtCore.Qt.Checked)
if fixed is not None:
self.fixed_check.setCheckState(QtCore.Qt.Unchecked if fixed else QtCore.Qt.Checked)
if glob is not None:
self.global_checkbox.setCheckState(QtCore.Qt.Checked if glob else QtCore.Qt.Unchecked)
if glob is not None:
self.global_checkbox.setCheckState(QtCore.Qt.Checked if glob else QtCore.Qt.Unchecked)
def get_parameter(self):
if self.is_linked:
try:
p = float(self._linetext)
except ValueError:
p = 1.0
else:
try:
p = float(self.parameter_line.text().replace(',', '.'))
except ValueError:
p = self.parameter_line.text().replace(',', '.')
# _ = QtWidgets.QMessageBox().warning(self, 'Invalid value',
# f'{self.parametername.text()} contains invalid values',
# QtWidgets.QMessageBox.Cancel)
# return None
try:
p = float(self.parameter_line.text().replace(',', '.'))
except ValueError:
p = self.parameter_line.text().replace(',', '.')
if self.checkBox.isChecked():
try:
@ -122,84 +99,26 @@ class FitModelWidget(QtWidgets.QWidget, Ui_FitParameter):
bounds = (lb, rb)
return p, bounds, not self.fixed_check.isChecked(), self.global_checkbox.isChecked(), self.is_linked
return p, bounds, not self.fixed_check.isChecked(), self.global_checkbox.isChecked()
@QtCore.pyqtSlot(bool)
def set_fixed(self, state: bool):
# self.global_checkbox.setVisible(not state)
self.frame.setVisible(not state)
def add_links(self, parameter: dict = None):
if parameter is None:
parameter = {}
self.menu.clear()
self.parameter_hint_model.clear()
ac = QtWidgets.QAction('Link to...', self)
ac.triggered.connect(self.link_parameter)
self.menu.addAction(ac)
for model_key, model_funcs in parameter.items():
m = QtWidgets.QMenu('Model ' + model_key, self)
hint_key = model_key
for func_name, func_params in model_funcs.items():
m2 = QtWidgets.QMenu(func_name, m)
hint_key += f'.{func_name}'
for p_name, idx in func_params:
ac = QtWidgets.QAction(p_name, m2)
hint_key += f'.{p_name}'
item = QtGui.QStandardItem(hint_key)
item.setData((model_key, *idx))
self.parameter_hint_model.appendRow(item)
ac.setData((model_key, *idx))
ac.triggered.connect(self.link_parameter)
m2.addAction(ac)
m.addMenu(m2)
self.menu.addMenu(m)
self.toolButton.setMenu(self.menu)
@QtCore.pyqtSlot()
def link_parameter(self, linkto=None):
if linkto is None:
action = self.sender()
else:
action = False
for m in self.menu.actions():
if m.menu():
for a in m.menu().actions():
if a.data() == linkto:
action = a
break
if action:
break
if (self.func_idx, self.parameter_pos) == action.data():
return
def update_parameter(self):
new_value = self.parameter_line.text()
if not new_value:
self.parameter_line.setText('1')
try:
new_text = f'Linked to {action.parentWidget().title()}.{action.text()}'
self._linetext = self.parameter_line.text()
self.parameter_line.setText(new_text)
self.parameter_line.setEnabled(False)
self.global_checkbox.hide()
self.global_checkbox.blockSignals(True)
self.global_checkbox.setCheckState(QtCore.Qt.Checked)
self.global_checkbox.blockSignals(False)
self.frame.hide()
self.is_linked = action.data()
float(new_value)
is_text = False
except ValueError:
is_text = True
except AttributeError:
self.parameter_line.setText(self._linetext)
self.parameter_line.setEnabled(True)
if self.fixed_check.isEnabled():
self.global_checkbox.show()
self.frame.show()
self.is_linked = None
self.state_changed.emit()
self.set_fixed(is_text)
class QSaveModelDialog(QtWidgets.QDialog, Ui_SaveDialog):
@ -294,8 +213,17 @@ class FitModelTree(QtWidgets.QTreeWidget):
idx = item.data(0, self.counterRole)
self.itemRemoved.emit(idx)
def add_function(self, idx: int, cnt: int, op: int, name: str, color: QtGui.QColor | str | tuple,
parent: QtWidgets.QTreeWidgetItem = None, children: list = None, active: bool = True, **kwargs):
def add_function(self,
idx: int,
cnt: int,
op: int,
name: str,
color: QtGui.QColor | str | tuple,
parent: QtWidgets.QTreeWidgetItem = None,
children: list = None,
active: bool = True,
param_names: list[str] = None,
**kwargs):
"""
Add function to tree and dictionary of functions.
"""
@ -310,6 +238,10 @@ class FitModelTree(QtWidgets.QTreeWidget):
it.setData(0, self.counterRole, cnt)
it.setData(0, self.operatorRole, op)
it.setText(0, name)
if param_names is not None:
it.setToolTip(0,
'Parameter names:\n' +
'\n'.join(f'{pn}({cnt})' for pn in param_names))
it.setForeground(0, QtGui.QBrush(color))
it.setIcon(0, get_icon(self.icons[op]))

View File

@ -114,10 +114,10 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit):
self.scrollwidget.layout().addStretch(1)
self.scrollwidget2.layout().addStretch(1)
def set_links(self, parameter):
for w in self.global_parameter:
if isinstance(w, FitModelWidget):
w.add_links(parameter)
# def set_links(self, parameter):
# for w in self.global_parameter:
# if isinstance(w, FitModelWidget):
# w.add_links(parameter)
@QtCore.pyqtSlot(str)
def change_global_parameter(self, value: str, idx: int = None):
@ -203,17 +203,15 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit):
is_global = []
is_fixed = []
globs = []
is_linked = []
for g in self.global_parameter:
if isinstance(g, FitModelWidget):
p_i, bds_i, fixed_i, global_i, link_i = g.get_parameter()
p_i, bds_i, fixed_i, global_i = g.get_parameter()
globs.append(p_i)
bds.append(bds_i)
is_fixed.append(fixed_i)
is_global.append(global_i)
is_linked.append(link_i)
lb, ub = list(zip(*bds))
@ -267,7 +265,7 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit):
data_parameter[sid] = (p, kw_p)
return data_parameter, lb, ub, is_fixed, global_p, is_linked
return data_parameter, lb, ub, is_fixed, global_p
def set_parameter(self, set_id: str | None, parameter: list[float]) -> int:
num_parameter = list(filter(lambda g: not isinstance(g, SelectionWidget), self.global_parameter))

View File

@ -128,7 +128,7 @@ class QFunctionWidget(QtWidgets.QWidget, Ui_Form):
self.newFunction.emit(idx, cnt)
self.add_function(idx, cnt, op, name, col)
self.add_function(idx, cnt, op, name, col, param_names=self.functions[idx].params)
def add_function(self, idx: int, cnt: int, op: int,
name: str, color: str | tuple[float, float, float] | BaseColor, **kwargs):
@ -141,6 +141,7 @@ class QFunctionWidget(QtWidgets.QWidget, Ui_Form):
qcolor = QtGui.QColor.fromRgbF(*color)
else:
qcolor = QtGui.QColor(color)
self.functree.add_function(idx, cnt, op, name, qcolor, **kwargs)
f = self.functions[idx]

View File

@ -116,7 +116,7 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
# collect parameter names etc. to allow linkage
self._func_list[self._current_model] = self.functionwidget.get_parameter_list()
dialog.set_links(self._func_list)
# dialog.set_links(self._func_list)
# show same tab (general parameter/Data parameter)
tab_idx = 0
@ -229,7 +229,7 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
continue
try:
p, lb, ub, var, glob, links = self.param_widgets[f['cnt']].get_parameter(function_use)
p, lb, ub, var, glob = self.param_widgets[f['cnt']].get_parameter(function_use)
except ValueError as e:
_ = QtWidgets.QMessageBox().warning(self, 'Invalid value', str(e),
QtWidgets.QMessageBox.Ok)
@ -240,7 +240,6 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
parameter['lb'] += lb
parameter['ub'] += ub
parameter['var'] += var
parameter['links'] += links
parameter['color'] += [f['color']]
cnt = f['cnt']

View File

@ -223,8 +223,6 @@ class FitRoutine(object):
def run(self, mode: str = 'lsq'):
self._abort = False
print('run')
fit_groups, linked_parameter = self.prepare_links()
for data_groups in fit_groups:
if len(data_groups) == 1 and not self.linked:
@ -256,6 +254,9 @@ class FitRoutine(object):
self.unprep_run()
for r in self.result:
r.pprint()
return self.result
def _prep_data(self, data):

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>365</width>
<height>78</height>
<height>66</height>
</rect>
</property>
<property name="sizePolicy">
@ -62,7 +62,7 @@
<item>
<widget class="LineEdit" name="parameter_line">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -78,19 +78,6 @@
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="fixed_check">
<property name="text">
@ -105,19 +92,6 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton">
<property name="text">
<string/>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="arrowType">
<enum>Qt::RightArrow</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>