style: Введен QMainWindow, окна настроек перенесены в QDockWidget

This commit is contained in:
Andrew 2024-12-23 18:51:17 +03:00
parent 9faa35f514
commit becb4764b4
17 changed files with 143 additions and 69 deletions

BIN
resources/operator_ico.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
resources/system_ico.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
resources/view_ico.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -2,7 +2,7 @@ from datetime import datetime as dt
from typing import Optional from typing import Optional
from PyQt5 import QtWidgets from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap from PyQt5.QtGui import QPixmap, QIcon
from utils.base.base import BaseMainWindow, BaseController from utils.base.base import BaseMainWindow, BaseController
from gui.settings_window import SystemSettings, OperatorSettings from gui.settings_window import SystemSettings, OperatorSettings
@ -14,6 +14,9 @@ class MainWindow(BaseMainWindow):
super().__init__() super().__init__()
self._controller = controller self._controller = controller
self._init_startUI() self._init_startUI()
self._init_dock_widgets()
self._init_menu()
def _init_startUI(self) -> None: def _init_startUI(self) -> None:
@ -21,6 +24,9 @@ class MainWindow(BaseMainWindow):
self.sysSettings = SystemSettings("params/system_params.json", 'System', self._transfer_settings) self.sysSettings = SystemSettings("params/system_params.json", 'System', self._transfer_settings)
self.repSettings = ReportSettings() self.repSettings = ReportSettings()
self.tabWidget = QtWidgets.QTabWidget() self.tabWidget = QtWidgets.QTabWidget()
self.tabWidget.setTabsClosable(True)
self.tabWidget.tabCloseRequested.connect(self._close_tab)
self.tabWidget.currentChanged.connect(self._on_tab_changed)
self._clear() self._clear()
seeking_mode_btn = QtWidgets.QPushButton("Real time folder scanning") seeking_mode_btn = QtWidgets.QPushButton("Real time folder scanning")
@ -37,7 +43,7 @@ class MainWindow(BaseMainWindow):
button_widget = QtWidgets.QWidget() button_widget = QtWidgets.QWidget()
button_widget.setLayout(button_layout) button_widget.setLayout(button_layout)
mainLayout = self.layout() mainLayout = self._central_layout
label = QtWidgets.QLabel("Select work mode") label = QtWidgets.QLabel("Select work mode")
label.setStyleSheet( label.setStyleSheet(
"""QLabel{ """QLabel{
@ -50,61 +56,121 @@ class MainWindow(BaseMainWindow):
mainLayout.addWidget(label, alignment=Qt.AlignCenter) mainLayout.addWidget(label, alignment=Qt.AlignCenter)
mainLayout.addWidget(button_widget) mainLayout.addWidget(button_widget)
def _init_dock_widgets(self) -> None:
"""
Инициализация док-виджетов для настроек.
"""
# Создаем док-виджет для OperatorSettings
self.operator_dock = QtWidgets.QDockWidget("Operator Settings", self)
self.operator_dock.setWidget(self.operSettings)
self.operator_dock.setObjectName("OperatorSettings")
self.addDockWidget(Qt.RightDockWidgetArea, self.operator_dock)
self.operator_dock.hide() # Скрываем по умолчанию
# Создаем док-виджет для SystemSettings
self.system_dock = QtWidgets.QDockWidget("System Settings", self)
self.system_dock.setWidget(self.sysSettings)
self.system_dock.setObjectName("SystemSettings")
self.addDockWidget(Qt.RightDockWidgetArea, self.system_dock)
self.system_dock.hide() # Скрываем по умолчанию
# Создаем док-виджет для ReportSettings
self.report_dock = QtWidgets.QDockWidget("Report Settings", self)
self.report_dock.setWidget(self.repSettings)
self.report_dock.setObjectName("ReportSettings")
self.addDockWidget(Qt.RightDockWidgetArea, self.report_dock)
self.report_dock.hide() # Скрываем по умолчанию
# Настройка док-виджетов
self._set_dock_features(self.operator_dock)
self._set_dock_features(self.system_dock)
self._set_dock_features(self.report_dock)
def _init_menu(self) -> None:
"""
Инициализация главного меню.
"""
# Создаем главное меню
menu_bar = self.menuBar()
# Создаем меню "Режимы"
modes_menu = menu_bar.addMenu("Mode")
settings_menu = menu_bar.addMenu("Settings")
# Создаем действия для меню
seeking_action = QtWidgets.QAction("Real time folder scanning", self)
seeking_action.triggered.connect(self._init_seekingUI)
raport_action = QtWidgets.QAction("Raport editor", self)
raport_action.triggered.connect(self._init_raportUI)
system_settings = QtWidgets.QAction("System settings", self)
system_settings.setIcon(QIcon('resources/system_ico.png'))
system_settings.triggered.connect(lambda: self._toggle_visibility(self.system_dock))
operator_settings = QtWidgets.QAction("Operator settings", self)
operator_settings.setIcon(QIcon('resources/operator_ico.png'))
operator_settings.triggered.connect(lambda: self._toggle_visibility(self.operator_dock))
view_settings = QtWidgets.QAction("View settings", self)
view_settings.setIcon(QIcon('resources/view_ico.png'))
view_settings.triggered.connect(lambda: self._toggle_visibility(self.report_dock))
# Добавляем действия в меню "Режимы"
modes_menu.addAction(seeking_action)
modes_menu.addAction(raport_action)
settings_menu.addAction(system_settings)
settings_menu.addAction(operator_settings)
settings_menu.addAction(view_settings)
def _toggle_visibility(self, body:QtWidgets.QDockWidget = None) -> None:
"""
Переключение видимости док-виджета.
"""
is_visible = body.isVisible()
body.setVisible(not is_visible)
def _set_dock_features(self, body:QtWidgets.QDockWidget = None) -> None:
"""
Настройка флагов док-виджета.
"""
flag_move = QtWidgets.QDockWidget.DockWidgetMovable
flag_close = QtWidgets.QDockWidget.DockWidgetClosable
flag_floating = QtWidgets.QDockWidget.DockWidgetFloatable
body.setFeatures(flag_move | flag_close | flag_floating)
def _clear(self) -> None: def _clear(self) -> None:
main = self.layout() if self._central_layout is not None:
if self.layout() is not None: while self._central_layout.count():
while main.count(): child = self._central_layout.takeAt(0)
child = main.takeAt(0)
if child.widget() is not None: if child.widget() is not None:
child.widget().deleteLater() child.widget().deleteLater()
else: self.setLayout(QtWidgets.QVBoxLayout())
def _init_seekingUI(self) -> None: def _init_seekingUI(self) -> None:
self._clear() self._clear()
self._transfer_settings() self._transfer_settings()
self.tabWidget = QtWidgets.QTabWidget()
self.tabWidget.setTabsClosable(True)
self.tabWidget.tabCloseRequested.connect(self._close_tab)
sys_settings_btn = QtWidgets.QPushButton("System settings")
sys_settings_btn.setFixedWidth(200)
sys_settings_btn.clicked.connect(lambda: self.sysSettings.show())
oper_settings_btn = QtWidgets.QPushButton("Operator settings")
oper_settings_btn.setFixedWidth(200)
oper_settings_btn.clicked.connect(lambda: self.operSettings.show())
button_layout = QtWidgets.QHBoxLayout() button_layout = QtWidgets.QHBoxLayout()
button_layout.setSpacing(2) button_layout.setSpacing(2)
button_layout.addWidget(sys_settings_btn)
button_layout.addWidget(oper_settings_btn)
button_widget = QtWidgets.QWidget() button_widget = QtWidgets.QWidget()
button_widget.setLayout(button_layout) button_widget.setLayout(button_layout)
title = QtWidgets.QLabel("online mode") title = QtWidgets.QLabel("online mode")
mainLayout = self.layout() self._central_layout.addWidget(self.tabWidget)
mainLayout.addWidget(self.tabWidget) self._central_layout.addWidget(button_widget)
mainLayout.addWidget(button_widget) self._central_layout.addWidget(title, alignment=Qt.AlignRight)
mainLayout.addWidget(title, alignment=Qt.AlignRight)
self.resize(800,800) self.resize(800,800)
self._controller.seeking_mode() self._controller.seeking_mode()
# TODO:push seeking to mediator
def _init_raportUI(self) -> None: def _init_raportUI(self) -> None:
self._clear() self._clear()
self._transfer_settings() self._transfer_settings()
self.tabWidget = QtWidgets.QTabWidget()
self.tabWidget.setTabsClosable(True)
self.tabWidget.tabCloseRequested.connect(self._close_tab)
sys_settings_btn = QtWidgets.QPushButton("System settings")
sys_settings_btn.setFixedWidth(185)
sys_settings_btn.clicked.connect(lambda: self.sysSettings.show())
oper_settings_btn = QtWidgets.QPushButton("Operator settings")
oper_settings_btn.setFixedWidth(185)
oper_settings_btn.clicked.connect(lambda: self.operSettings.show())
view_settings_btn = QtWidgets.QPushButton("Customize view")
view_settings_btn.setFixedWidth(185)
view_settings_btn.clicked.connect(self._customization_window)
save_screen_btn = QtWidgets.QPushButton("Save state") save_screen_btn = QtWidgets.QPushButton("Save state")
save_screen_btn.setFixedWidth(185) save_screen_btn.setFixedWidth(185)
save_screen_btn.clicked.connect(self._save_plots) save_screen_btn.clicked.connect(self._save_plots)
@ -114,25 +180,18 @@ class MainWindow(BaseMainWindow):
button_layout = QtWidgets.QHBoxLayout() button_layout = QtWidgets.QHBoxLayout()
button_layout.setSpacing(2) button_layout.setSpacing(2)
button_layout.addWidget(sys_settings_btn)
button_layout.addWidget(oper_settings_btn)
button_layout.addWidget(view_settings_btn)
button_layout.addWidget(save_screen_btn) button_layout.addWidget(save_screen_btn)
button_layout.addWidget(open_file_btn) button_layout.addWidget(open_file_btn)
button_widget = QtWidgets.QWidget() button_widget = QtWidgets.QWidget()
button_widget.setLayout(button_layout) button_widget.setLayout(button_layout)
title = QtWidgets.QLabel("raport mode") title = QtWidgets.QLabel("raport mode")
mainLayout = self.layout() self._central_layout.addWidget(self.tabWidget)
mainLayout.addWidget(self.tabWidget) self._central_layout.addWidget(button_widget)
mainLayout.addWidget(button_widget) self._central_layout.addWidget(title, alignment=Qt.AlignRight)
mainLayout.addWidget(title, alignment=Qt.AlignRight)
self.resize(800,800) self.resize(800,800)
self._controller.raport_mode(None) self._controller.raport_mode(None)
#self._controller.raport_mode(path)
# TODO: push only one dir to monitor
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:
@ -149,7 +208,7 @@ class MainWindow(BaseMainWindow):
tab_count = self.tabWidget.count() tab_count = self.tabWidget.count()
if tab_count > 10: if tab_count > 10:
for i in range(0, tab_count-2): for i in range(0, tab_count-10):
self._close_tab(i) self._close_tab(i)
def keyPressEvent(self, a0) -> None: def keyPressEvent(self, a0) -> None:
@ -164,10 +223,6 @@ class MainWindow(BaseMainWindow):
self.repSettings.close() self.repSettings.close()
super().closeEvent(a0) super().closeEvent(a0)
def _show_settings(self) -> None:
self.operSettings.show()
self.sysSettings.show()
def _transfer_settings(self) -> None: def _transfer_settings(self) -> None:
self.tabWidget.clear() self.tabWidget.clear()
operator_params = self.operSettings.getParams() operator_params = self.operSettings.getParams()
@ -188,18 +243,20 @@ class MainWindow(BaseMainWindow):
return CSV_path return CSV_path
return None return None
def _customization_window(self) -> None: def _on_tab_changed(self, index):
tab = self.tabWidget.currentWidget() tab = self.tabWidget.currentWidget()
reg_items = tab.property("reg_items") if tab is not None and self.report_dock.isVisible():
curve_items = tab.property("curve_items") reg_items = tab.property("reg_items")
self.repSettings.build(reg_items, curve_items) curve_items = tab.property("curve_items")
self.repSettings.build(index, reg_items, curve_items)
def _save_plots(self) -> None: def _save_plots(self) -> None:
filepath, _ = QtWidgets.QFileDialog.getSaveFileName(self, "Save file", "", "Image Files (*.png *.jpeg)") filepath, _ = QtWidgets.QFileDialog.getSaveFileName(self, "Save file", "", "Image Files (*.png *.jpeg)")
tab = self.tabWidget.currentWidget() tab = self.tabWidget.currentWidget()
pixmap = QPixmap(tab.size()) if tab is not None:
tab.render(pixmap) pixmap = QPixmap(tab.size())
pixmap.save(filepath) tab.render(pixmap)
pixmap.save(filepath)

View File

@ -2,28 +2,38 @@ import pyqtgraph as pg
from pyqtgraph.parametertree import Parameter, ParameterTree from pyqtgraph.parametertree import Parameter, ParameterTree
from typing import Union from typing import Union
from PyQt5 import QtWidgets from PyQt5 import QtWidgets
from cachetools import LRUCache
class ReportSettings(QtWidgets.QWidget): class ReportSettings(QtWidgets.QWidget):
def __init__(self, parent = None):
super().__init__(parent)
#self._tab_cashe = LRUCache(maxsize=1000)
def build(self, reg_items: dict, curve_items: dict) -> None: def build(self, index, reg_items: dict, curve_items: dict) -> None:
"""Создает ParameterTree для элементов всех графиков выбранной вкладки""" """Создает ParameterTree для элементов всех графиков выбранной вкладки"""
self._clear() self._clear()
param_tree = ParameterTree() param_tree = ParameterTree()
layout = self.layout() layout = self.layout()
layout.addWidget(param_tree) layout.addWidget(param_tree)
"""if index in self._tab_cashe:
body = self._tab_cashe[index]
else:
body= [
self._generate_reg_params(reg_items),
self._generate_curve_params(curve_items)
]
self._tab_cashe[index] = body"""
body= [ body= [
self._generate_reg_params(reg_items), self._generate_reg_params(reg_items),
self._generate_curve_params(curve_items) self._generate_curve_params(curve_items)
] ]
# Добавляем параметры в дерево # Добавляем параметры в дерево
params = Parameter.create(name='params', type='group', children=body) params = Parameter.create(name='params', type='group', children=body)
params.sigTreeStateChanged.connect( params.sigTreeStateChanged.connect(
lambda: self._update_settings(reg_items, curve_items, params) lambda: self._update_settings(reg_items, curve_items, params)
) )
param_tree.setParameters(params, showTop=False) param_tree.setParameters(params, showTop=False)
self.show()
def _clear(self) -> None: def _clear(self) -> None:
""" """

View File

@ -6,7 +6,7 @@ from cachetools import LRUCache
import pandas as pd import pandas as pd
from PyQt5.QtCore import QObject, QTimer from PyQt5.QtCore import QObject, QTimer
from PyQt5.QtWidgets import QWidget, QTabWidget from PyQt5.QtWidgets import QWidget, QTabWidget, QMainWindow, QVBoxLayout
from OptAlgorithm import OptAlgorithm from OptAlgorithm import OptAlgorithm
import numpy as np import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
@ -393,13 +393,20 @@ class BaseIdealDataBuilder(OptAlgorithm):
result = sum(self.get_ideal_timings()) result = sum(self.get_ideal_timings())
return result return result
class BaseMainWindow(QWidget): class BaseMainWindow(QMainWindow):
def __init__(self, def __init__(self,
controller: Optional[BaseController] = None): controller: Optional[BaseController] = None):
super().__init__() super().__init__()
self.set_style(self)
self.resize(200,200) self.resize(200,200)
self._controller = controller self._controller = controller
# Создаем центральный виджет и устанавливаем его
self._central_widget = QWidget()
self.setCentralWidget(self._central_widget)
# Устанавливаем основной вертикальный макет для центрального виджета
self._central_layout = QVBoxLayout()
self._central_widget.setLayout(self._central_layout)
self.set_style(self._central_widget)
... ...
@property @property