diff --git a/params/operator_params.json b/params/operator_params.json index 16046d2..7be03f3 100644 --- a/params/operator_params.json +++ b/params/operator_params.json @@ -81,19 +81,19 @@ ], "distance_l_2": [ 0.0275, - 0.03, - 0.033, - 0.033, - 0.033, - 0.033, - 0.033, - 0.033, - 0.033, - 0.033, - 0.033, - 0.033, - 0.033, - 0.033 + 0.0255, + 0.0242, + 0.0245, + 0.0228, + 0.0236, + 0.0229, + 0.0248, + 0.024, + 0.0235, + 0.025, + 0.0276, + 0.0234, + 0.0215 ], "distance_h_end1": [ 0.003, diff --git a/src/controller/__pycache__/controller.cpython-310.pyc b/src/controller/__pycache__/controller.cpython-310.pyc index f7576ab..bab4ee2 100644 Binary files a/src/controller/__pycache__/controller.cpython-310.pyc and b/src/controller/__pycache__/controller.cpython-310.pyc differ diff --git a/src/controller/__pycache__/mediator.cpython-310.pyc b/src/controller/__pycache__/mediator.cpython-310.pyc index 6717f3d..d79c205 100644 Binary files a/src/controller/__pycache__/mediator.cpython-310.pyc and b/src/controller/__pycache__/mediator.cpython-310.pyc differ diff --git a/src/controller/controller.py b/src/controller/controller.py index 651fdaf..4d6362f 100644 --- a/src/controller/controller.py +++ b/src/controller/controller.py @@ -17,4 +17,5 @@ class Controller(BaseController): self.signal_settings.emit(settings) def open_custom_file (self, filepath: str) -> None: - self.signal_monitor.emit(filepath) \ No newline at end of file + self.signal_monitor.emit(filepath) + \ No newline at end of file diff --git a/src/gui/__pycache__/mainGui.cpython-310.pyc b/src/gui/__pycache__/mainGui.cpython-310.pyc index 01f6071..fb783bc 100644 Binary files a/src/gui/__pycache__/mainGui.cpython-310.pyc and b/src/gui/__pycache__/mainGui.cpython-310.pyc differ diff --git a/src/gui/__pycache__/plotter.cpython-310.pyc b/src/gui/__pycache__/plotter.cpython-310.pyc index d4c52ba..26ac3c3 100644 Binary files a/src/gui/__pycache__/plotter.cpython-310.pyc and b/src/gui/__pycache__/plotter.cpython-310.pyc differ diff --git a/src/gui/__pycache__/reportGui.cpython-310.pyc b/src/gui/__pycache__/reportGui.cpython-310.pyc new file mode 100644 index 0000000..8aea989 Binary files /dev/null and b/src/gui/__pycache__/reportGui.cpython-310.pyc differ diff --git a/src/gui/mainGui.py b/src/gui/mainGui.py index 804986e..a50a127 100644 --- a/src/gui/mainGui.py +++ b/src/gui/mainGui.py @@ -5,6 +5,7 @@ from PyQt5 import QtWidgets from PyQt5.QtCore import Qt from utils.base.base import BaseMainWindow, BaseController from gui.settings_window import settingsWindow +from gui.reportGui import ReportSettings class MainWindow(BaseMainWindow): def __init__(self, @@ -15,8 +16,10 @@ class MainWindow(BaseMainWindow): self.set_style(self) self.settings_button.clicked.connect(self._show_settings) 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.sysSettings = settingsWindow("params/system_params.json", 'System', self._updater_trigger) + self.repSettings = ReportSettings() def initUI(self) -> None: self.tabWidget = QtWidgets.QTabWidget() @@ -29,19 +32,30 @@ class MainWindow(BaseMainWindow): self.settings_button.setFixedWidth(160) self.select_dir_button = QtWidgets.QPushButton("Open directory") 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.setSpacing(2) button_layout.addWidget(self.settings_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) self.setLayout(layout) def show_plot_tabs(self, plot_widgets: list[QtWidgets.QWidget]) -> None: for plot_widget in plot_widgets: + widget, reg_items, curve_items = plot_widget + tab = QtWidgets.QWidget() + tab.setProperty("reg_items", reg_items) + tab.setProperty("curve_items", curve_items) grid = QtWidgets.QGridLayout() - grid.addWidget(plot_widget) + grid.addWidget(widget) tab.setLayout(grid) self.tabWidget.addTab(tab, "SF_trace_" + dt.now().strftime('%Y_%m_%d-%H_%M_%S')) self.tabWidget.setCurrentWidget(tab) @@ -51,7 +65,6 @@ class MainWindow(BaseMainWindow): for i in range(0, tab_count-2): self._close_tab(i) - def keyPressEvent(self, a0): if a0.key() == Qt.Key_F5: pass @@ -77,5 +90,22 @@ class MainWindow(BaseMainWindow): if 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)) + + + + + + + + diff --git a/src/gui/plotter.py b/src/gui/plotter.py index 29e99c5..4b51da3 100644 --- a/src/gui/plotter.py +++ b/src/gui/plotter.py @@ -59,6 +59,7 @@ class PlotWidget(BasePlotWidget): plot_widget: pg.PlotWidget, point_events: dict[str, list[float]], dataframe_headers: list[str], + reg_items: dict, transparency: int = 75) -> None: """ Добавляет регионы для реальных этапов, если все стадии есть в заголовках датафрейма. @@ -71,11 +72,14 @@ class PlotWidget(BasePlotWidget): if region is not None: region.setZValue(-20) plot_widget.addItem(region) + reg_items["real"].setdefault(stage, []) + reg_items["real"][stage].append(region) def _add_ideal_stage_regions(self, plot_widget: pg.PlotWidget, ideal_data: dict[str, Any], point_events: dict[str, list[float]], + reg_items: dict, transparency: int = 125) -> None: """ Добавляет регионы для идеальных этапов. @@ -89,12 +93,15 @@ class PlotWidget(BasePlotWidget): if region: region.setZValue(-10) plot_widget.addItem(region) + reg_items["ideal"].setdefault(stage, []) + reg_items["ideal"][stage].append(region) def _add_ideal_signals(self, plot_widget: pg.PlotWidget, ideal_data: dict[str, Any], 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: curve.setZValue(10) plot_widget.addItem(curve) - + curve_items["ideal"].setdefault(signal["name"], {}) + curve_items["ideal"][signal["name"]][stage] = curve + def _add_real_signals(self, plot_widget: pg.PlotWidget, dataframe: pd.DataFrame, real_signals: list[dict[str, Any]], - legend: pg.LegendItem) -> None: + legend: pg.LegendItem, + curve_items: dict) -> None: """ Добавляет реальные сигналы из dataframe на виджет. """ @@ -124,6 +134,8 @@ class PlotWidget(BasePlotWidget): plot = plot_widget.plot(dataframe["time"], dataframe[signal["name"]], pen=signal["pen"], fast=True) plot.setZValue(0) legend.addItem(plot, signal["name"]) + curve_items["real"].setdefault(signal["name"], {}) + curve_items["real"][signal["name"]] = plot def _add_performance_label(self, layout: QVBoxLayout, @@ -152,6 +164,8 @@ class PlotWidget(BasePlotWidget): """ widget = QWidget() layout = QVBoxLayout(widget) + reg_items = {"real":{}, "ideal":{}} + curve_items = {"real":{}, "ideal":{}} dataframe, points_pocket, useful_data = data tesla_time = useful_data["tesla_time"] @@ -192,7 +206,7 @@ class PlotWidget(BasePlotWidget): # Добавляем реальные стадии 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: подобрать не вырвеглазные цвета, возможно ограничить зону if settings["workpiece"]: @@ -209,8 +223,8 @@ class PlotWidget(BasePlotWidget): # Добавляем идеальные стадии и идеальные сигналы if settings["ideals"]: - self._add_ideal_stage_regions(plot_widget, ideal_data, point_events, 100) - self._add_ideal_signals(plot_widget, ideal_data, point_events, description["Ideal_signals"]) + 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"], curve_items) # Подсчёт производительности if settings["performance"]: @@ -229,7 +243,7 @@ class PlotWidget(BasePlotWidget): 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: main_plot = plot_widget 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)) widget.setLayout(layout) - return widget + return widget, reg_items, curve_items 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] - self._mediator.notify(self, widgets) + widgets_datapack = [self._build_widget(data_sample) for data_sample in data] + self._mediator.notify(self, widgets_datapack) + + \ No newline at end of file diff --git a/src/gui/reportGui.py b/src/gui/reportGui.py new file mode 100644 index 0000000..c4ccf49 --- /dev/null +++ b/src/gui/reportGui.py @@ -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}, + ] + + diff --git a/src/utils/base/__pycache__/base.cpython-310.pyc b/src/utils/base/__pycache__/base.cpython-310.pyc index 5a76e8b..9d579a8 100644 Binary files a/src/utils/base/__pycache__/base.cpython-310.pyc and b/src/utils/base/__pycache__/base.cpython-310.pyc differ diff --git a/src/utils/base/base.py b/src/utils/base/base.py index 8d499e6..ae3bbbf 100644 --- a/src/utils/base/base.py +++ b/src/utils/base/base.py @@ -123,7 +123,7 @@ class BasePlotWidget: "zoom": False, "stages": True, "performance": True, - "ideals": True, + "ideals": False, "mirror ME": False, "workpiece": False, "force compensation FE": False @@ -154,7 +154,7 @@ class BasePlotWidget: "zoom": False, "stages": True, "performance": False, - "ideals": True, + "ideals": False, "mirror ME": True, "workpiece": True, "force compensation FE": True