dev: добавлено окно, отображающее параметры каждого элемента графика
This commit is contained in:
parent
365118bc22
commit
eaec12d3ff
@ -81,19 +81,19 @@
|
|||||||
],
|
],
|
||||||
"distance_l_2": [
|
"distance_l_2": [
|
||||||
0.0275,
|
0.0275,
|
||||||
0.03,
|
0.0255,
|
||||||
0.033,
|
0.0242,
|
||||||
0.033,
|
0.0245,
|
||||||
0.033,
|
0.0228,
|
||||||
0.033,
|
0.0236,
|
||||||
0.033,
|
0.0229,
|
||||||
0.033,
|
0.0248,
|
||||||
0.033,
|
0.024,
|
||||||
0.033,
|
0.0235,
|
||||||
0.033,
|
0.025,
|
||||||
0.033,
|
0.0276,
|
||||||
0.033,
|
0.0234,
|
||||||
0.033
|
0.0215
|
||||||
],
|
],
|
||||||
"distance_h_end1": [
|
"distance_h_end1": [
|
||||||
0.003,
|
0.003,
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -17,4 +17,5 @@ class Controller(BaseController):
|
|||||||
self.signal_settings.emit(settings)
|
self.signal_settings.emit(settings)
|
||||||
|
|
||||||
def open_custom_file (self, filepath: str) -> None:
|
def open_custom_file (self, filepath: str) -> None:
|
||||||
self.signal_monitor.emit(filepath)
|
self.signal_monitor.emit(filepath)
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
BIN
src/gui/__pycache__/reportGui.cpython-310.pyc
Normal file
BIN
src/gui/__pycache__/reportGui.cpython-310.pyc
Normal file
Binary file not shown.
@ -5,6 +5,7 @@ from PyQt5 import QtWidgets
|
|||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt
|
||||||
from utils.base.base import BaseMainWindow, BaseController
|
from utils.base.base import BaseMainWindow, BaseController
|
||||||
from gui.settings_window import settingsWindow
|
from gui.settings_window import settingsWindow
|
||||||
|
from gui.reportGui import ReportSettings
|
||||||
|
|
||||||
class MainWindow(BaseMainWindow):
|
class MainWindow(BaseMainWindow):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
@ -15,8 +16,10 @@ class MainWindow(BaseMainWindow):
|
|||||||
self.set_style(self)
|
self.set_style(self)
|
||||||
self.settings_button.clicked.connect(self._show_settings)
|
self.settings_button.clicked.connect(self._show_settings)
|
||||||
self.select_dir_button.clicked.connect(self._select_dir)
|
self.select_dir_button.clicked.connect(self._select_dir)
|
||||||
|
self.report_button.clicked.connect(self._report_window)
|
||||||
self.operSettings = settingsWindow("params/operator_params.json", 'Operator', self._updater_trigger)
|
self.operSettings = settingsWindow("params/operator_params.json", 'Operator', self._updater_trigger)
|
||||||
self.sysSettings = settingsWindow("params/system_params.json", 'System', self._updater_trigger)
|
self.sysSettings = settingsWindow("params/system_params.json", 'System', self._updater_trigger)
|
||||||
|
self.repSettings = ReportSettings()
|
||||||
|
|
||||||
def initUI(self) -> None:
|
def initUI(self) -> None:
|
||||||
self.tabWidget = QtWidgets.QTabWidget()
|
self.tabWidget = QtWidgets.QTabWidget()
|
||||||
@ -29,19 +32,30 @@ class MainWindow(BaseMainWindow):
|
|||||||
self.settings_button.setFixedWidth(160)
|
self.settings_button.setFixedWidth(160)
|
||||||
self.select_dir_button = QtWidgets.QPushButton("Open directory")
|
self.select_dir_button = QtWidgets.QPushButton("Open directory")
|
||||||
self.select_dir_button.setFixedWidth(175)
|
self.select_dir_button.setFixedWidth(175)
|
||||||
|
self.report_button = QtWidgets.QPushButton("Generate report")
|
||||||
|
self.report_button.setFixedWidth(175)
|
||||||
|
self.rep_settings_button = QtWidgets.QPushButton("Report settings")
|
||||||
|
self.rep_settings_button.setFixedWidth(175)
|
||||||
|
self.rep_settings_button.setVisible(False)
|
||||||
button_layout = QtWidgets.QHBoxLayout()
|
button_layout = QtWidgets.QHBoxLayout()
|
||||||
button_layout.setSpacing(2)
|
button_layout.setSpacing(2)
|
||||||
button_layout.addWidget(self.settings_button)
|
button_layout.addWidget(self.settings_button)
|
||||||
button_layout.addWidget(self.select_dir_button)
|
button_layout.addWidget(self.select_dir_button)
|
||||||
|
button_layout.addWidget(self.report_button)
|
||||||
|
button_layout.addWidget(self.rep_settings_button)
|
||||||
|
|
||||||
layout.addLayout(button_layout)
|
layout.addLayout(button_layout)
|
||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|
||||||
def show_plot_tabs(self, plot_widgets: list[QtWidgets.QWidget]) -> None:
|
def show_plot_tabs(self, plot_widgets: list[QtWidgets.QWidget]) -> None:
|
||||||
for plot_widget in plot_widgets:
|
for plot_widget in plot_widgets:
|
||||||
|
widget, reg_items, curve_items = plot_widget
|
||||||
|
|
||||||
tab = QtWidgets.QWidget()
|
tab = QtWidgets.QWidget()
|
||||||
|
tab.setProperty("reg_items", reg_items)
|
||||||
|
tab.setProperty("curve_items", curve_items)
|
||||||
grid = QtWidgets.QGridLayout()
|
grid = QtWidgets.QGridLayout()
|
||||||
grid.addWidget(plot_widget)
|
grid.addWidget(widget)
|
||||||
tab.setLayout(grid)
|
tab.setLayout(grid)
|
||||||
self.tabWidget.addTab(tab, "SF_trace_" + dt.now().strftime('%Y_%m_%d-%H_%M_%S'))
|
self.tabWidget.addTab(tab, "SF_trace_" + dt.now().strftime('%Y_%m_%d-%H_%M_%S'))
|
||||||
self.tabWidget.setCurrentWidget(tab)
|
self.tabWidget.setCurrentWidget(tab)
|
||||||
@ -51,7 +65,6 @@ class MainWindow(BaseMainWindow):
|
|||||||
for i in range(0, tab_count-2):
|
for i in range(0, tab_count-2):
|
||||||
self._close_tab(i)
|
self._close_tab(i)
|
||||||
|
|
||||||
|
|
||||||
def keyPressEvent(self, a0):
|
def keyPressEvent(self, a0):
|
||||||
if a0.key() == Qt.Key_F5:
|
if a0.key() == Qt.Key_F5:
|
||||||
pass
|
pass
|
||||||
@ -77,5 +90,22 @@ class MainWindow(BaseMainWindow):
|
|||||||
if folder_path:
|
if folder_path:
|
||||||
self._controller.open_custom_file(folder_path)
|
self._controller.open_custom_file(folder_path)
|
||||||
|
|
||||||
|
def _report_window(self):
|
||||||
|
tab = self.tabWidget.currentWidget()
|
||||||
|
reg_items = tab.property("reg_items")
|
||||||
|
curve_items = tab.property("curve_items")
|
||||||
|
print(curve_items)
|
||||||
|
print(reg_items)
|
||||||
|
|
||||||
|
self.rep_settings_button.setVisible(True)
|
||||||
|
self.rep_settings_button.clicked.connect(lambda:self.repSettings.build(reg_items, curve_items))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -59,6 +59,7 @@ class PlotWidget(BasePlotWidget):
|
|||||||
plot_widget: pg.PlotWidget,
|
plot_widget: pg.PlotWidget,
|
||||||
point_events: dict[str, list[float]],
|
point_events: dict[str, list[float]],
|
||||||
dataframe_headers: list[str],
|
dataframe_headers: list[str],
|
||||||
|
reg_items: dict,
|
||||||
transparency: int = 75) -> None:
|
transparency: int = 75) -> None:
|
||||||
"""
|
"""
|
||||||
Добавляет регионы для реальных этапов, если все стадии есть в заголовках датафрейма.
|
Добавляет регионы для реальных этапов, если все стадии есть в заголовках датафрейма.
|
||||||
@ -71,11 +72,14 @@ class PlotWidget(BasePlotWidget):
|
|||||||
if region is not None:
|
if region is not None:
|
||||||
region.setZValue(-20)
|
region.setZValue(-20)
|
||||||
plot_widget.addItem(region)
|
plot_widget.addItem(region)
|
||||||
|
reg_items["real"].setdefault(stage, [])
|
||||||
|
reg_items["real"][stage].append(region)
|
||||||
|
|
||||||
def _add_ideal_stage_regions(self,
|
def _add_ideal_stage_regions(self,
|
||||||
plot_widget: pg.PlotWidget,
|
plot_widget: pg.PlotWidget,
|
||||||
ideal_data: dict[str, Any],
|
ideal_data: dict[str, Any],
|
||||||
point_events: dict[str, list[float]],
|
point_events: dict[str, list[float]],
|
||||||
|
reg_items: dict,
|
||||||
transparency: int = 125) -> None:
|
transparency: int = 125) -> None:
|
||||||
"""
|
"""
|
||||||
Добавляет регионы для идеальных этапов.
|
Добавляет регионы для идеальных этапов.
|
||||||
@ -89,12 +93,15 @@ class PlotWidget(BasePlotWidget):
|
|||||||
if region:
|
if region:
|
||||||
region.setZValue(-10)
|
region.setZValue(-10)
|
||||||
plot_widget.addItem(region)
|
plot_widget.addItem(region)
|
||||||
|
reg_items["ideal"].setdefault(stage, [])
|
||||||
|
reg_items["ideal"][stage].append(region)
|
||||||
|
|
||||||
def _add_ideal_signals(self,
|
def _add_ideal_signals(self,
|
||||||
plot_widget: pg.PlotWidget,
|
plot_widget: pg.PlotWidget,
|
||||||
ideal_data: dict[str, Any],
|
ideal_data: dict[str, Any],
|
||||||
point_events: dict[str, list[float]],
|
point_events: dict[str, list[float]],
|
||||||
ideal_signals: list[dict[str, Any]]) -> None:
|
ideal_signals: list[dict[str, Any]],
|
||||||
|
curve_items: dict) -> None:
|
||||||
"""
|
"""
|
||||||
Добавляет идеальные сигналы для каждого этапа.
|
Добавляет идеальные сигналы для каждого этапа.
|
||||||
"""
|
"""
|
||||||
@ -109,12 +116,15 @@ class PlotWidget(BasePlotWidget):
|
|||||||
if curve:
|
if curve:
|
||||||
curve.setZValue(10)
|
curve.setZValue(10)
|
||||||
plot_widget.addItem(curve)
|
plot_widget.addItem(curve)
|
||||||
|
curve_items["ideal"].setdefault(signal["name"], {})
|
||||||
|
curve_items["ideal"][signal["name"]][stage] = curve
|
||||||
|
|
||||||
def _add_real_signals(self,
|
def _add_real_signals(self,
|
||||||
plot_widget: pg.PlotWidget,
|
plot_widget: pg.PlotWidget,
|
||||||
dataframe: pd.DataFrame,
|
dataframe: pd.DataFrame,
|
||||||
real_signals: list[dict[str, Any]],
|
real_signals: list[dict[str, Any]],
|
||||||
legend: pg.LegendItem) -> None:
|
legend: pg.LegendItem,
|
||||||
|
curve_items: dict) -> None:
|
||||||
"""
|
"""
|
||||||
Добавляет реальные сигналы из dataframe на виджет.
|
Добавляет реальные сигналы из dataframe на виджет.
|
||||||
"""
|
"""
|
||||||
@ -124,6 +134,8 @@ class PlotWidget(BasePlotWidget):
|
|||||||
plot = plot_widget.plot(dataframe["time"], dataframe[signal["name"]], pen=signal["pen"], fast=True)
|
plot = plot_widget.plot(dataframe["time"], dataframe[signal["name"]], pen=signal["pen"], fast=True)
|
||||||
plot.setZValue(0)
|
plot.setZValue(0)
|
||||||
legend.addItem(plot, signal["name"])
|
legend.addItem(plot, signal["name"])
|
||||||
|
curve_items["real"].setdefault(signal["name"], {})
|
||||||
|
curve_items["real"][signal["name"]] = plot
|
||||||
|
|
||||||
def _add_performance_label(self,
|
def _add_performance_label(self,
|
||||||
layout: QVBoxLayout,
|
layout: QVBoxLayout,
|
||||||
@ -152,6 +164,8 @@ class PlotWidget(BasePlotWidget):
|
|||||||
"""
|
"""
|
||||||
widget = QWidget()
|
widget = QWidget()
|
||||||
layout = QVBoxLayout(widget)
|
layout = QVBoxLayout(widget)
|
||||||
|
reg_items = {"real":{}, "ideal":{}}
|
||||||
|
curve_items = {"real":{}, "ideal":{}}
|
||||||
|
|
||||||
dataframe, points_pocket, useful_data = data
|
dataframe, points_pocket, useful_data = data
|
||||||
tesla_time = useful_data["tesla_time"]
|
tesla_time = useful_data["tesla_time"]
|
||||||
@ -192,7 +206,7 @@ class PlotWidget(BasePlotWidget):
|
|||||||
|
|
||||||
# Добавляем реальные стадии
|
# Добавляем реальные стадии
|
||||||
if settings["stages"]:
|
if settings["stages"]:
|
||||||
self._add_stage_regions(plot_widget, point_events, dataframe_headers, 75)
|
self._add_stage_regions(plot_widget, point_events, dataframe_headers, reg_items, 75)
|
||||||
|
|
||||||
# TODO: подобрать не вырвеглазные цвета, возможно ограничить зону
|
# TODO: подобрать не вырвеглазные цвета, возможно ограничить зону
|
||||||
if settings["workpiece"]:
|
if settings["workpiece"]:
|
||||||
@ -209,8 +223,8 @@ class PlotWidget(BasePlotWidget):
|
|||||||
|
|
||||||
# Добавляем идеальные стадии и идеальные сигналы
|
# Добавляем идеальные стадии и идеальные сигналы
|
||||||
if settings["ideals"]:
|
if settings["ideals"]:
|
||||||
self._add_ideal_stage_regions(plot_widget, ideal_data, point_events, 100)
|
self._add_ideal_stage_regions(plot_widget, ideal_data, point_events, reg_items, 100)
|
||||||
self._add_ideal_signals(plot_widget, ideal_data, point_events, description["Ideal_signals"])
|
self._add_ideal_signals(plot_widget, ideal_data, point_events, description["Ideal_signals"], curve_items)
|
||||||
|
|
||||||
# Подсчёт производительности
|
# Подсчёт производительности
|
||||||
if settings["performance"]:
|
if settings["performance"]:
|
||||||
@ -229,7 +243,7 @@ class PlotWidget(BasePlotWidget):
|
|||||||
worst_timeframe = point_timeframe
|
worst_timeframe = point_timeframe
|
||||||
|
|
||||||
# Добавляем реальные сигналы
|
# Добавляем реальные сигналы
|
||||||
self._add_real_signals(plot_widget, dataframe, description["Real_signals"], legend)
|
self._add_real_signals(plot_widget, dataframe, description["Real_signals"], legend, curve_items)
|
||||||
if widget_num == 0:
|
if widget_num == 0:
|
||||||
main_plot = plot_widget
|
main_plot = plot_widget
|
||||||
else:
|
else:
|
||||||
@ -248,7 +262,7 @@ class PlotWidget(BasePlotWidget):
|
|||||||
main_plot.sigXRangeChanged.connect(lambda _, plot=main_plot, region=ROI_region: self._sync_navigator_with_main(main_plot=plot, region=region))
|
main_plot.sigXRangeChanged.connect(lambda _, plot=main_plot, region=ROI_region: self._sync_navigator_with_main(main_plot=plot, region=region))
|
||||||
|
|
||||||
widget.setLayout(layout)
|
widget.setLayout(layout)
|
||||||
return widget
|
return widget, reg_items, curve_items
|
||||||
|
|
||||||
def build(self, data: list[list[Any]]) -> None:
|
def build(self, data: list[list[Any]]) -> None:
|
||||||
"""
|
"""
|
||||||
@ -260,6 +274,8 @@ class PlotWidget(BasePlotWidget):
|
|||||||
...
|
...
|
||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
widgets = [self._build_widget(data_sample) for data_sample in data]
|
widgets_datapack = [self._build_widget(data_sample) for data_sample in data]
|
||||||
self._mediator.notify(self, widgets)
|
self._mediator.notify(self, widgets_datapack)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
77
src/gui/reportGui.py
Normal file
77
src/gui/reportGui.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import pyqtgraph as pg
|
||||||
|
from pyqtgraph.parametertree import Parameter, ParameterTree
|
||||||
|
from typing import Union
|
||||||
|
from PyQt5 import QtWidgets
|
||||||
|
from PyQt5.QtCore import Qt
|
||||||
|
|
||||||
|
|
||||||
|
class ReportSettings(QtWidgets.QWidget):
|
||||||
|
|
||||||
|
def build(self, reg_items: dict, curve_items: dict) -> None:
|
||||||
|
param_tree = ParameterTree()
|
||||||
|
layout = QtWidgets.QVBoxLayout()
|
||||||
|
layout.addWidget(param_tree)
|
||||||
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
body= [
|
||||||
|
self._generate_reg_params(reg_items),
|
||||||
|
self._generate_curve_params(curve_items)
|
||||||
|
]
|
||||||
|
# Добавляем параметры в дерево
|
||||||
|
params = Parameter.create(name='params', type='group', children=body)
|
||||||
|
param_tree.setParameters(params, showTop=False)
|
||||||
|
self.show()
|
||||||
|
|
||||||
|
def _generate_reg_params(self, reg_items: dict) -> dict:
|
||||||
|
|
||||||
|
res = {'name': 'Sectors', 'type': 'group', 'children': [
|
||||||
|
{'name': 'Real sectors', 'type': 'group', 'children': self._create_samples(reg_items["real"])},
|
||||||
|
{'name': 'Ideal sectors', 'type': 'group', 'children': self._create_samples(reg_items["ideal"])},
|
||||||
|
]}
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _generate_curve_params(self, curve_items: dict) -> dict:
|
||||||
|
|
||||||
|
res = {'name': 'Plots', 'type': 'group', 'children': [
|
||||||
|
{'name': 'Real plots', 'type': 'group', 'children': self._create_samples(curve_items["real"])},
|
||||||
|
{'name': 'Ideal plots', 'type': 'group', 'children': self._create_ideal_curves(curve_items["ideal"])},
|
||||||
|
]}
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _create_ideal_curves(self, curve: dict) -> list[dict]:
|
||||||
|
"""Создаем секторы с этапами циклограммы"""
|
||||||
|
res = []
|
||||||
|
for key, item in curve.items():
|
||||||
|
param = {'name': key, 'type': 'group', 'children': self._create_samples(item)}
|
||||||
|
res.append(param)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _create_samples(self, sector: dict) -> list[dict]:
|
||||||
|
res = []
|
||||||
|
for key, item in sector.items():
|
||||||
|
sample = item[0] if type(item) == list else item
|
||||||
|
param = {'name': key, 'type': 'group', 'children': self._create_settings(sample)}
|
||||||
|
res.append(param)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _create_settings(self, item: Union[pg.LinearRegionItem, pg.PlotDataItem]) -> list[dict]:
|
||||||
|
"""Настройки для элемента"""
|
||||||
|
if type(item) == pg.LinearRegionItem:
|
||||||
|
pen = item.lines[0].pen
|
||||||
|
brush = item.brush
|
||||||
|
fill_color = brush.color().getRgb()
|
||||||
|
else:
|
||||||
|
pen = pg.mkPen(item.opts.get("pen"))
|
||||||
|
fill_color = None
|
||||||
|
line_color = pen.color().getRgb()
|
||||||
|
line_thickness = pen.width()
|
||||||
|
visibility = item.isVisible()
|
||||||
|
|
||||||
|
return [
|
||||||
|
{'name': 'Line color', 'type': 'color', 'value': line_color},
|
||||||
|
{'name': 'Line thickness', 'type': 'int', 'value': line_thickness, 'limits': (1, 10)},
|
||||||
|
{'name': 'Visibility', 'type': 'bool', 'value': visibility},
|
||||||
|
{'name': 'Fill color', 'type': 'color', 'value': fill_color},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
@ -123,7 +123,7 @@ class BasePlotWidget:
|
|||||||
"zoom": False,
|
"zoom": False,
|
||||||
"stages": True,
|
"stages": True,
|
||||||
"performance": True,
|
"performance": True,
|
||||||
"ideals": True,
|
"ideals": False,
|
||||||
"mirror ME": False,
|
"mirror ME": False,
|
||||||
"workpiece": False,
|
"workpiece": False,
|
||||||
"force compensation FE": False
|
"force compensation FE": False
|
||||||
@ -154,7 +154,7 @@ class BasePlotWidget:
|
|||||||
"zoom": False,
|
"zoom": False,
|
||||||
"stages": True,
|
"stages": True,
|
||||||
"performance": False,
|
"performance": False,
|
||||||
"ideals": True,
|
"ideals": False,
|
||||||
"mirror ME": True,
|
"mirror ME": True,
|
||||||
"workpiece": True,
|
"workpiece": True,
|
||||||
"force compensation FE": True
|
"force compensation FE": True
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user