chore: добавлено описание модуля start_widget

This commit is contained in:
Andrew 2025-02-11 13:34:56 +03:00
parent 04fb9eb673
commit ba0f8818bb
2 changed files with 300 additions and 189 deletions

View File

@ -54,9 +54,9 @@ class MainWindow(BaseMainWindow):
self._init_menu()
self._init_status_bar()
start_widget = StartWidget()
start_widget.seeking_mode_btn.clicked.connect(self._init_seekingUI)
start_widget.raport_mode_btn.clicked.connect(self._init_raportUI)
start_widget.client_mode_btn.clicked.connect(self._init_client_UI)
start_widget.btn_scanning.clicked.connect(self._init_seekingUI)
start_widget.btn_report.clicked.connect(self._init_raportUI)
start_widget.btn_client.clicked.connect(self._init_client_UI)
self.setCentralWidget(start_widget.get_widget())
def _init_settings(self) -> None:
@ -67,10 +67,10 @@ class MainWindow(BaseMainWindow):
def _init_menu(self) -> None:
self.menu = CustomMenuBar(self.sysSettings, self.repSettings, self.operSettings, self.filterSettings)
self.menu.seeking_action.triggered.connect(self._init_seekingUI)
self.menu.raport_action.triggered.connect(self._init_raportUI)
self.menu.client_action.triggered.connect(self._init_client_UI)
self.menu.view_settings.triggered.connect(lambda: self._on_tab_changed(0))
self.menu.action_scanning.triggered.connect(self._init_seekingUI)
self.menu.action_report.triggered.connect(self._init_raportUI)
self.menu.action_client.triggered.connect(self._init_client_UI)
self.menu.action_view_settings.triggered.connect(lambda: self._on_tab_changed(0))
self.menu.setup(self)
def _init_status_bar(self) -> None:
@ -102,8 +102,8 @@ class MainWindow(BaseMainWindow):
self._clear()
self._set_mode(1)
raport_widget = RaportWidget(self._tab_widget)
raport_widget.open_file_btn.clicked.connect(self._open_file)
raport_widget.save_screen_btn.clicked.connect(self._save_plots)
raport_widget.btn_open_file.clicked.connect(self._open_file)
raport_widget.btn_save_state.clicked.connect(self._save_plots)
self.setCentralWidget(raport_widget.get_widget())
def _init_seekingUI(self) -> None:
@ -117,9 +117,9 @@ class MainWindow(BaseMainWindow):
self._set_mode(3)
client_widget = ClientAnalyzerWidget(self._tab_widget)
#TODO: привязать действия к кнопкам
client_widget.open_folder_btn.clicked.connect(self._open_folder)
client_widget.save_screen_btn.clicked.connect(self._save_plots)
client_widget.build_TCW_btn.clicked.connect(self._build_TCW_for_client)
client_widget.btn_open_folder.clicked.connect(self._open_folder)
client_widget.btn_save_state.clicked.connect(self._save_plots)
client_widget.btn_calc_tcw.clicked.connect(self._build_TCW_for_client)
self.setCentralWidget(client_widget.get_widget())
def _build_TCW_for_client(self):

View File

@ -1,11 +1,9 @@
from datetime import datetime as dt
from PyQt5.QtWidgets import (QWidget, QPushButton,
QMenuBar, QHBoxLayout,
QVBoxLayout, QLabel,
QDockWidget, QTabWidget,
QProgressBar, QAction,
QMainWindow, QGridLayout)
from PyQt5.QtWidgets import (
QWidget, QPushButton, QMenuBar, QHBoxLayout, QVBoxLayout, QLabel,
QDockWidget, QTabWidget, QProgressBar, QAction, QMainWindow, QGridLayout
)
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QSizePolicy as QSP
@ -16,79 +14,125 @@ from base.base import PlotItems
class StartWidget(QWidget):
"""
Виджет выбора режима работы приложения.
Содержит кнопки для перехода в различные режимы:
- Сканирование папки в реальном времени
- Редактор отчётов
- Обработка клиентских трейсов
"""
def __init__(self) -> None:
super().__init__()
self._build_main_layout()
def get_widget(self) -> QWidget:
"""
Возвращает текущий виджет.
"""
return self
def _build_main_layout(self) -> None:
self.resize(800,800)
self.seeking_mode_btn = QPushButton("Real time folder scanning")
self.seeking_mode_btn.setFixedWidth(350)
self.raport_mode_btn = QPushButton("Raport editor")
self.raport_mode_btn.setFixedWidth(350)
self.client_mode_btn = QPushButton("Client trace processor")
self.client_mode_btn.setFixedWidth(350)
"""
Строит макет виджета с заголовком и кнопками выбора режима.
"""
self.resize(800, 800)
# Создаем кнопки для различных режимов работы
self.btn_scanning = QPushButton("Real time folder scanning")
self.btn_scanning.setFixedWidth(350)
self.btn_report = QPushButton("Raport editor")
self.btn_report.setFixedWidth(350)
self.btn_client = QPushButton("Client trace processor")
self.btn_client.setFixedWidth(350)
# Размещение кнопок в горизонтальном макете
button_layout = QHBoxLayout()
button_layout.setSpacing(2)
button_layout.addWidget(self.seeking_mode_btn)
button_layout.addWidget(self.raport_mode_btn)
button_layout.addWidget(self.client_mode_btn)
button_widget = QWidget()
button_widget.setLayout(button_layout)
button_layout.addWidget(self.btn_scanning)
button_layout.addWidget(self.btn_report)
button_layout.addWidget(self.btn_client)
button_container = QWidget()
button_container.setLayout(button_layout)
mainLayout = QVBoxLayout()
label = QLabel("Select work mode")
label.setStyleSheet(
# Создаем основной вертикальный макет с заголовком и кнопками
main_layout = QVBoxLayout()
title_label = QLabel("Select work mode")
title_label.setStyleSheet(
"""QLabel{
color: #ffffff;
font-size: 40px;
font-weight: bold;
font-family: "Segoe UI", sans-serif;
}"""
)
mainLayout.addWidget(label, alignment=Qt.AlignCenter)
mainLayout.addWidget(button_widget)
self.setLayout(mainLayout)
)
main_layout.addWidget(title_label, alignment=Qt.AlignCenter)
main_layout.addWidget(button_container)
self.setLayout(main_layout)
class CustomStatusBar(QWidget):
"""
Кастомный виджет для статус-бара, отображающий режим, заметку и прогресс.
"""
def __init__(self) -> None:
super().__init__()
self._build_status_bar()
def get_widget(self) -> QWidget:
"""
Возвращает виджет статус-бара.
"""
return self
def set_mode(self, msg:str = '') -> None:
if not isinstance(msg, str): msg = str(msg)
def set_mode(self, msg: str = '') -> None:
"""
Устанавливает текст режима в статус-баре.
:param msg: Сообщение для отображения.
"""
if not isinstance(msg, str):
msg = str(msg)
self._mode_label.setText(msg)
self._mode_label.adjustSize()
def set_note(self, msg:str = '') -> None:
if not isinstance(msg, str): msg = str(msg)
def set_note(self, msg: str = '') -> None:
"""
Устанавливает текст заметки в статус-баре.
:param msg: Сообщение для отображения.
"""
if not isinstance(msg, str):
msg = str(msg)
self._note_label.setText(msg)
self._note_label.adjustSize()
def set_progress(self, percent:int = 0) -> None:
if not isinstance(percent, int): percent = 0
elif percent < 0: percent = 0
elif percent > 100: percent = 100
def set_progress(self, percent: int = 0) -> None:
"""
Устанавливает значение прогресс-бара.
:param percent: Значение прогресса (от 0 до 100).
"""
if not isinstance(percent, int):
percent = 0
elif percent < 0:
percent = 0
elif percent > 100:
percent = 100
self._progress_bar.setValue(percent)
def _build_status_bar(self) -> None:
# Создание пользовательского виджета для StatusBar
note_layout = QHBoxLayout()
note_layout.setContentsMargins(10, 1, 10, 1)
note_layout.setSpacing(15) # Устанавливаем расстояние между элементами
"""
Создает и настраивает компоненты статус-бара.
"""
# Создаем горизонтальный макет с отступами и промежутками
layout = QHBoxLayout()
layout.setContentsMargins(10, 1, 10, 1)
layout.setSpacing(15)
# Создание QLabel и QProgressBar
# Инициализируем компоненты статус-бара
self._mode_label = QLabel()
self._note_label = QLabel()
self._progress_bar = QProgressBar()
@ -98,71 +142,106 @@ class CustomStatusBar(QWidget):
self._progress_bar.setMaximumHeight(10)
self._progress_bar.setTextVisible(False)
# Установка политики размеров
# Устанавливаем политику размеров для компонентов
self._mode_label.setSizePolicy(QSP.Policy.Preferred, QSP.Policy.Preferred)
self._note_label.setSizePolicy(QSP.Policy.MinimumExpanding, QSP.Policy.Preferred)
self._progress_bar.setSizePolicy(QSP.Policy.Fixed, QSP.Policy.Preferred)
# Добавление виджетов в макет
note_layout.addWidget(self._progress_bar)
note_layout.addWidget(self._note_label)
note_layout.addStretch(1)
note_layout.addWidget(self._mode_label)
# Добавляем компоненты в макет
layout.addWidget(self._progress_bar)
layout.addWidget(self._note_label)
layout.addStretch(1)
layout.addWidget(self._mode_label)
self.setLayout(note_layout)
self.setLayout(layout)
self.setSizePolicy(QSP.Policy.Expanding, QSP.Policy.Preferred)
class CustomTabWidget(QTabWidget):
"""
Кастомный виджет-вкладка.
def __init__ (self):
Позволяет создавать вкладки с виджетом графика и закрывать их.
"""
def __init__(self):
super().__init__()
self._build_tab_widget()
def get_widget(self) -> QWidget:
"""
Возвращает виджет.
"""
return self
def _build_tab_widget(self) -> None:
"""
Настраивает виджет вкладок: включает возможность закрытия вкладок.
"""
self.setTabsClosable(True)
self.tabCloseRequested.connect(self.close_tab)
#TODO: переписать обмен данными, засунуть ссылки куда-то еще
def create_tab(self, plot_widget:QWidget) -> None:
plot_items:PlotItems = plot_widget.property("pyqt_container")
tab = QWidget()
tab.setProperty("reg_items", plot_items.regions)
tab.setProperty("curve_items", plot_items.curves)
tab.setProperty("qt_items", plot_items.qt_items)
grid = QGridLayout()
grid.addWidget(plot_widget)
tab.setLayout(grid)
self.addTab(tab, "SF_trace_" + dt.now().strftime('%Y_%m_%d-%H_%M_%S'))
self.setCurrentWidget(tab)
def create_tab(self, plot_widget: QWidget) -> None:
"""
Создает новую вкладку с виджетом графика.
def close_tab(self, index:int) -> None:
Извлекает из виджета необходимые данные, сохраняет их в свойствах вкладки.
:param plot_widget: Виджет, содержащий график.
"""
# Извлекаем объект PlotItems, сохранённый в свойстве виджета
plot_items: PlotItems = plot_widget.property("pyqt_container")
new_tab = QWidget()
new_tab.setProperty("reg_items", plot_items.regions)
new_tab.setProperty("curve_items", plot_items.curves)
new_tab.setProperty("qt_items", plot_items.qt_items)
grid_layout = QGridLayout()
grid_layout.addWidget(plot_widget)
new_tab.setLayout(grid_layout)
tab_label = "SF_trace_" + dt.now().strftime('%Y_%m_%d-%H_%M_%S')
self.addTab(new_tab, tab_label)
self.setCurrentWidget(new_tab)
def close_tab(self, index: int) -> None:
"""
Закрывает вкладку по заданному индексу.
:param index: Индекс вкладки для закрытия.
"""
if self.count() > index and index >= 0:
self.removeTab(index)
class CustomMenuBar(QMenuBar):
"""
Кастомное главное меню с док-виджетами для различных настроек.
"""
def __init__(self,
operSettings:OperatorSettings,
sysSettings:SystemSettings,
repSettings:ReportSettings,
filterSettings:FilterSettings) -> None:
operator_settings: OperatorSettings,
system_settings: SystemSettings,
report_settings: ReportSettings,
filter_settings: FilterSettings) -> None:
super().__init__()
self._operSettings = operSettings
self._sysSettings = sysSettings
self._repSettings = repSettings
self._filterSettings = filterSettings
self._operator_settings = operator_settings
self._system_settings = system_settings
self._report_settings = report_settings
self._filter_settings = filter_settings
self._build_dock_widgets()
self._build_menu()
def get_widget(self) -> QWidget:
"""
Возвращает виджет меню.
"""
return self
def setup(self, parent:QMainWindow) -> None:
def setup(self, parent: QMainWindow) -> None:
"""
Добавляет док-виджеты и устанавливает главное меню для главного окна.
:param parent: Главное окно приложения.
"""
parent.addDockWidget(Qt.RightDockWidgetArea, self._operator_dock)
parent.addDockWidget(Qt.RightDockWidgetArea, self._system_dock)
parent.addDockWidget(Qt.RightDockWidgetArea, self._report_dock)
@ -171,33 +250,33 @@ class CustomMenuBar(QMenuBar):
def _build_dock_widgets(self) -> None:
"""
Инициализация док-виджетов для настроек.
Инициализирует док-виджеты для настроек и скрывает их по умолчанию.
"""
# Создаем док-виджет для OperatorSettings
# Док-виджет для настроек оператора
self._operator_dock = QDockWidget("Operator Settings", self)
self._operator_dock.setWidget(self._operSettings)
self._operator_dock.setWidget(self._operator_settings)
self._operator_dock.setObjectName("OperatorSettings")
self._operator_dock.hide() # Скрываем по умолчанию
self._operator_dock.hide()
# Создаем док-виджет для SystemSettings
# Док-виджет для системных настроек
self._system_dock = QDockWidget("System Settings", self)
self._system_dock.setWidget(self._sysSettings)
self._system_dock.setWidget(self._system_settings)
self._system_dock.setObjectName("SystemSettings")
self._system_dock.hide() # Скрываем по умолчанию
self._system_dock.hide()
# Создаем док-виджет для ReportSettings
# Док-виджет для настроек представления отчёта
self._report_dock = QDockWidget("View settings", self)
self._report_dock.setWidget(self._repSettings)
self._report_dock.setWidget(self._report_settings)
self._report_dock.setObjectName("ReportSettings")
self._report_dock.hide() # Скрываем по умолчанию
self._report_dock.hide()
# Создаем док-виджет для filterSettings
# Док-виджет для фильтр-настроек
self._filter_dock = QDockWidget("Filter settings", self)
self._filter_dock.setWidget(self._filterSettings)
self._filter_dock.setWidget(self._filter_settings)
self._filter_dock.setObjectName("FilterSetting")
self._filter_dock.hide() # Скрываем по умолчанию
self._filter_dock.hide()
# Настройка док-виджетов
# Устанавливаем функциональные возможности для каждого док-виджета
self._set_dock_features(self._operator_dock)
self._set_dock_features(self._system_dock)
self._set_dock_features(self._report_dock)
@ -205,144 +284,176 @@ class CustomMenuBar(QMenuBar):
def _build_menu(self) -> None:
"""
Инициализация главного меню.
Инициализирует элементы главного меню.
"""
# Создаем меню "Режимы"
# Создаем меню для выбора режима и настроек
modes_menu = self.addMenu("Mode")
settings_menu = self.addMenu("Settings")
# Создаем действия для меню
self.seeking_action = QAction("Real time folder scanning", self)
self.raport_action = QAction("Raport editor", self)
self.client_action = QAction("Client trace processor", self)
# Действия для переключения режимов
self.action_scanning = QAction("Real time folder scanning", self)
self.action_report = QAction("Raport editor", self)
self.action_client = QAction("Client trace processor", self)
system_settings = QAction("System settings", self)
system_settings.setIcon(QIcon('resources/system_ico.png'))
system_settings.triggered.connect(lambda: self._toggle_visibility(self._system_dock))
# Действия для настроек
system_settings_action = QAction("System settings", self)
system_settings_action.setIcon(QIcon('resources/system_ico.png'))
system_settings_action.triggered.connect(lambda: self._toggle_visibility(self._system_dock))
operator_settings = QAction("Operator settings ", self)
operator_settings.setIcon(QIcon('resources/operator_ico.png'))
operator_settings.triggered.connect(lambda: self._toggle_visibility(self._operator_dock))
operator_settings_action = QAction("Operator settings", self)
operator_settings_action.setIcon(QIcon('resources/operator_ico.png'))
operator_settings_action.triggered.connect(lambda: self._toggle_visibility(self._operator_dock))
self.view_settings = QAction("View settings", self)
self.view_settings.setIcon(QIcon('resources/view_ico.png'))
self.view_settings.triggered.connect(lambda: self._toggle_visibility(self._report_dock))
self.action_view_settings = QAction("View settings", self)
self.action_view_settings.setIcon(QIcon('resources/view_ico.png'))
self.action_view_settings.triggered.connect(lambda: self._toggle_visibility(self._report_dock))
self.filter_settings = QAction("Filter settings", self)
#self.filter_settings.setIcon(QIcon('resources/view_ico.png'))
self.filter_settings.triggered.connect(lambda: self._toggle_visibility(self._filter_dock))
self.action_filter_settings = QAction("Filter settings", self)
self.action_filter_settings.triggered.connect(lambda: self._toggle_visibility(self._filter_dock))
# Добавляем действия в меню "Режимы"
modes_menu.addAction(self.seeking_action)
modes_menu.addAction(self.raport_action)
modes_menu.addAction(self.client_action)
# Добавляем действия в меню "Mode"
modes_menu.addAction(self.action_scanning)
modes_menu.addAction(self.action_report)
modes_menu.addAction(self.action_client)
settings_menu.addAction(system_settings)
settings_menu.addAction(operator_settings)
settings_menu.addAction(self.view_settings)
settings_menu.addAction(self.filter_settings)
# Добавляем действия в меню "Settings"
settings_menu.addAction(system_settings_action)
settings_menu.addAction(operator_settings_action)
settings_menu.addAction(self.action_view_settings)
settings_menu.addAction(self.action_filter_settings)
def _toggle_visibility(self, body:QDockWidget = None) -> None:
def _toggle_visibility(self, dock: QDockWidget = None) -> None:
"""
Переключение видимости док-виджета.
Переключает видимость указанного док-виджета.
:param dock: Док-виджет для переключения.
"""
if body:
is_visible = body.isVisible()
body.setVisible(not is_visible)
if dock:
is_visible = dock.isVisible()
dock.setVisible(not is_visible)
@staticmethod
def _set_dock_features(body:QDockWidget = None) -> None:
def _set_dock_features(dock: QDockWidget = None) -> None:
"""
Настройка флагов док-виджета.
Устанавливает возможность перемещения, закрытия и открепления для док-виджета.
:param dock: Док-виджет для настройки.
"""
if body:
flag_move = QDockWidget.DockWidgetMovable
flag_close = QDockWidget.DockWidgetClosable
flag_floating = QDockWidget.DockWidgetFloatable
body.setFeatures(flag_move | flag_close | flag_floating)
if dock:
features = QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetClosable | QDockWidget.DockWidgetFloatable
dock.setFeatures(features)
class RaportWidget(QWidget):
"""
Виджет для режима редактирования отчёта.
def __init__(self, tabWidget:CustomTabWidget):
Содержит вкладки и кнопки для сохранения состояния и открытия файла.
"""
def __init__(self, tab_widget: CustomTabWidget):
super().__init__()
self._tabWidget = tabWidget
self._tab_widget = tab_widget
self._build_widget()
def get_widget(self) -> QWidget:
"""
Возвращает виджет.
"""
return self
def _build_widget(self):
def _build_widget(self) -> None:
"""
Строит макет виджета с вкладками и кнопками управления.
"""
main_layout = QVBoxLayout()
self.save_screen_btn = QPushButton("Save state")
self.save_screen_btn.setFixedWidth(185)
self.open_file_btn = QPushButton("Open file")
self.open_file_btn.setFixedWidth(185)
self.btn_save_state = QPushButton("Save state")
self.btn_save_state.setFixedWidth(185)
self.btn_open_file = QPushButton("Open file")
self.btn_open_file.setFixedWidth(185)
button_layout = QHBoxLayout()
button_layout.setSpacing(2)
button_layout.addWidget(self.btn_save_state)
button_layout.addWidget(self.btn_open_file)
button_container = QWidget()
button_container.setLayout(button_layout)
button_layout.addWidget(self.save_screen_btn)
button_layout.addWidget(self.open_file_btn)
button_widget = QWidget()
button_widget.setLayout(button_layout)
main_layout.addWidget(self._tabWidget)
main_layout.addWidget(button_widget)
main_layout.addWidget(self._tab_widget)
main_layout.addWidget(button_container)
self.setLayout(main_layout)
class SeekingWidget(QWidget):
"""
Виджет для режима поиска (сканирования папок).
def __init__(self, tabWidget:CustomTabWidget):
"""
def __init__(self, tab_widget: CustomTabWidget):
super().__init__()
self._tabWidget = tabWidget
self._tab_widget = tab_widget
self._build_widget()
def get_widget(self) -> QWidget:
"""
Возвращает виджет.
"""
return self
def _build_widget(self):
def _build_widget(self) -> None:
"""
Создает макет виджета с вкладками.
"""
main_layout = QVBoxLayout()
button_layout = QHBoxLayout()
button_layout.setSpacing(2)
button_widget = QWidget()
button_widget.setLayout(button_layout)
button_container = QWidget()
button_container.setLayout(button_layout)
main_layout.addWidget(self._tabWidget)
main_layout.addWidget(button_widget)
main_layout.addWidget(self._tab_widget)
main_layout.addWidget(button_container)
self.setLayout(main_layout)
class ClientAnalyzerWidget(QWidget):
"""
Виджет для клиентского анализа трассировки.
def __init__(self, tabWidget:CustomTabWidget):
Содержит вкладки и кнопки для сохранения состояния, открытия папки и расчёта TCW.
"""
def __init__(self, tab_widget: CustomTabWidget):
super().__init__()
self._tabWidget = tabWidget
self._tab_widget = tab_widget
self._build_widget()
def get_widget(self) -> QWidget:
"""
Возвращает виджет.
"""
return self
def _build_widget(self):
def _build_widget(self) -> None:
"""
Строит макет виджета с вкладками и управляющими кнопками.
"""
main_layout = QVBoxLayout()
self.save_screen_btn = QPushButton("Save state")
self.save_screen_btn.setFixedWidth(185)
self.open_folder_btn = QPushButton("Open folder")
self.open_folder_btn.setFixedWidth(185)
self.build_TCW_btn = QPushButton("Calculate TCW")
self.build_TCW_btn.setFixedWidth(185)
self.btn_save_state = QPushButton("Save state")
self.btn_save_state.setFixedWidth(185)
self.btn_open_folder = QPushButton("Open folder")
self.btn_open_folder.setFixedWidth(185)
self.btn_calc_tcw = QPushButton("Calculate TCW")
self.btn_calc_tcw.setFixedWidth(185)
button_layout = QHBoxLayout()
button_layout.setSpacing(2)
button_layout.addWidget(self.btn_save_state)
button_layout.addWidget(self.btn_open_folder)
button_layout.addWidget(self.btn_calc_tcw)
button_container = QWidget()
button_container.setLayout(button_layout)
button_layout.addWidget(self.save_screen_btn)
button_layout.addWidget(self.open_folder_btn)
button_layout.addWidget(self.build_TCW_btn)
button_widget = QWidget()
button_widget.setLayout(button_layout)
main_layout.addWidget(self._tabWidget)
main_layout.addWidget(button_widget)
main_layout.addWidget(self._tab_widget)
main_layout.addWidget(button_container)
self.setLayout(main_layout)