BUGFIX: VFT;
change to src layout
This commit is contained in:
196
src/gui_qt/data/point_select.py
Normal file
196
src/gui_qt/data/point_select.py
Normal file
@@ -0,0 +1,196 @@
|
||||
import re
|
||||
|
||||
from ..Qt import QtCore, QtWidgets
|
||||
from .._py.ptstab import Ui_Form
|
||||
from ..lib.pg_objects import LogInfiniteLine, RegionItem
|
||||
|
||||
__all__ = ['PointSelectWidget']
|
||||
|
||||
|
||||
REGION_RE = re.compile(r'(?P<first>[+-]*\d+(?:\.\d*)*(?:[eE][+-]*\d+)*)'
|
||||
r'(?: ?- ?(?P<second>[+-]*\d+(?:\.\d*)*(?:[eE][+-]*\d+)*))*')
|
||||
|
||||
|
||||
class PointSelectWidget(QtWidgets.QWidget, Ui_Form):
|
||||
widget_closed = QtCore.pyqtSignal()
|
||||
points_selected = QtCore.pyqtSignal(dict, str)
|
||||
point_removed = QtCore.pyqtSignal(LogInfiniteLine)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.setupUi(self)
|
||||
|
||||
self.pts = []
|
||||
self.pts_lines = []
|
||||
self.nop = 0
|
||||
self._prev_pos = ''
|
||||
self._last_item = None
|
||||
self.connected_figure = ''
|
||||
|
||||
self.okButton.clicked.connect(self.apply)
|
||||
self.deleteButton.clicked.connect(self.remove_points)
|
||||
self.peaktable.itemChanged.connect(self.editing_finished)
|
||||
self.peaktable.itemDoubleClicked.connect(self.editing_started)
|
||||
|
||||
def keyPressEvent(self, e):
|
||||
if e.key() == QtCore.Qt.Key_Delete:
|
||||
self.remove_points()
|
||||
elif e.key() == QtCore.Qt.Key_F2:
|
||||
self.editing_started()
|
||||
else:
|
||||
super().keyPressEvent(e)
|
||||
|
||||
def clear(self):
|
||||
self.pts = []
|
||||
self.nop = 0
|
||||
self.peaktable.clear()
|
||||
self.pts_lines = []
|
||||
|
||||
@QtCore.pyqtSlot(tuple, bool)
|
||||
def add(self, pos: tuple, double: bool):
|
||||
x = pos[0]
|
||||
if double:
|
||||
self.removepoint(-1)
|
||||
|
||||
self.pts.append((x, x*1.1))
|
||||
item = RegionItem(values=[x, x*1.1], mode='mid')
|
||||
item.sigRegionChanged.connect(self._update_region)
|
||||
else:
|
||||
self.pts.append(x)
|
||||
item = LogInfiniteLine(pos=x, movable=True)
|
||||
item.sigPositionChanged.connect(self._update_line)
|
||||
|
||||
self.pts_lines.append(item)
|
||||
self.nop += 1
|
||||
self._makerow()
|
||||
|
||||
return item
|
||||
|
||||
def remove_points(self):
|
||||
for i in sorted(self.peaktable.selectedIndexes(), key=lambda x: x.row(), reverse=True):
|
||||
self.removepoint(pos=i.row())
|
||||
|
||||
def removepoint(self, pos=0):
|
||||
if pos == -1:
|
||||
pos = len(self.pts) - 1
|
||||
|
||||
try:
|
||||
self.pts.pop(pos)
|
||||
self.nop -= 1
|
||||
item = self.peaktable.takeItem(pos)
|
||||
del item
|
||||
|
||||
del_line = self.pts_lines.pop(pos)
|
||||
self.point_removed.emit(del_line)
|
||||
del del_line
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
def _makerow(self):
|
||||
if isinstance(self.pts[-1], tuple):
|
||||
item = QtWidgets.QListWidgetItem(f'{self.pts[-1][0]:.5g} - {self.pts[-1][1]:.5g}')
|
||||
else:
|
||||
item = QtWidgets.QListWidgetItem(f'{self.pts[-1]:.5g}')
|
||||
item.setFlags(item.flags() ^ QtCore.Qt.ItemIsEditable)
|
||||
self.peaktable.blockSignals(True)
|
||||
self.peaktable.addItem(item)
|
||||
self.peaktable.blockSignals(False)
|
||||
|
||||
def closeEvent(self, evt):
|
||||
self.widget_closed.emit()
|
||||
super().closeEvent(evt)
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def apply(self) -> dict:
|
||||
ret_dic = {'avg_range': [self.left_pt.value(), self.right_pt.value()],
|
||||
'avg_mode': {0: 'mean', 1: 'sum', 2: 'integral'}[self.average_combobox.currentIndex()],
|
||||
'special': None, 'idx': None,
|
||||
'xy': (self.xbutton.isChecked(), self.ybutton.isChecked())}
|
||||
|
||||
if self.groupBox_2.isChecked():
|
||||
ret_dic['special'] = {0: 'max', 1: 'absmax', 2: 'min', 3: 'absmin'}[self.special_comboBox.currentIndex()]
|
||||
|
||||
if len(self.pts) != 0:
|
||||
ret_dic['idx'] = self.pts
|
||||
|
||||
if self.graph_checkbox.isChecked():
|
||||
gid = ''
|
||||
else:
|
||||
gid = self.graph_combobox.currentData()
|
||||
|
||||
self.points_selected.emit(ret_dic, gid)
|
||||
|
||||
return ret_dic
|
||||
|
||||
def _update_region(self):
|
||||
try:
|
||||
idx = self.pts_lines.index(self.sender())
|
||||
except ValueError:
|
||||
return
|
||||
|
||||
self.pts[idx] = self.sender().getRegion()
|
||||
self.peaktable.blockSignals(True)
|
||||
self.peaktable.item(idx).setText('{:.5g} - {:.5g}'.format(*self.pts[idx]))
|
||||
self.peaktable.blockSignals(False)
|
||||
|
||||
def _update_line(self):
|
||||
try:
|
||||
idx = self.pts_lines.index(self.sender())
|
||||
except ValueError:
|
||||
return
|
||||
|
||||
self.pts[idx] = self.sender().value()
|
||||
self.peaktable.blockSignals(True)
|
||||
self.peaktable.item(idx).setText(f'{self.pts[idx]:.5g}')
|
||||
self.peaktable.blockSignals(False)
|
||||
|
||||
@QtCore.pyqtSlot(QtWidgets.QListWidgetItem)
|
||||
def editing_started(self, item=None):
|
||||
if item is None:
|
||||
item = self.peaktable.selectedItems()[0]
|
||||
self._prev_pos = item.text()
|
||||
self.peaktable.editItem(item)
|
||||
|
||||
@QtCore.pyqtSlot(QtWidgets.QListWidgetItem)
|
||||
def editing_finished(self, it: QtWidgets.QListWidgetItem):
|
||||
m = re.match(REGION_RE, it.text()).groupdict()
|
||||
undo = True
|
||||
if m:
|
||||
start, stop = m['first'], m['second']
|
||||
row = self.peaktable.row(it)
|
||||
it_pts = self.pts_lines[row]
|
||||
if ((stop is None) and isinstance(it_pts, RegionItem)) or \
|
||||
((stop is not None) and isinstance(it_pts, LogInfiniteLine)):
|
||||
QtWidgets.QMessageBox().information(self, 'Invalid type',
|
||||
'Conversion between point and region is not possible.')
|
||||
else:
|
||||
if stop is None:
|
||||
it_pts.blockSignals(True)
|
||||
it_pts.setValue(float(start))
|
||||
it_pts.blockSignals(False)
|
||||
self.pts[row] = float(start)
|
||||
else:
|
||||
start, stop = float(start), float(stop)
|
||||
pos = (min(start, stop), max(start, stop))
|
||||
self.pts[row] = pos
|
||||
self.peaktable.blockSignals(True)
|
||||
it.setText(f'{pos[0]:.5g} - {pos[1]:.5g}')
|
||||
self.peaktable.blockSignals(False)
|
||||
it_pts.blockSignals(True)
|
||||
it_pts.setRegion(pos)
|
||||
it_pts.blockSignals(False)
|
||||
undo = False
|
||||
|
||||
if undo:
|
||||
self.peaktable.blockSignals(True)
|
||||
it.setText(self._prev_pos)
|
||||
self.peaktable.blockSignals(False)
|
||||
|
||||
def set_graphs(self, graphs: list):
|
||||
self.graph_combobox.clear()
|
||||
for g in graphs:
|
||||
self.graph_combobox.addItem(g[1], userData=g[0])
|
||||
|
||||
@QtCore.pyqtSlot(int, name='on_graph_checkbox_stateChanged')
|
||||
def changed_state(self, checked):
|
||||
self.graph_combobox.setEnabled(checked!=QtCore.Qt.Checked)
|
Reference in New Issue
Block a user