- Удален кастомный безрамочный режим (FramelessWindowHint) главного окна и диалогов. - Внедрено нативное управление окнами операционной системы (изменение размеров, максимизация, минимизация). - Добавлено применение QPalette под выбранную тему (темную/свелую) и акцент для покраски системных элементов окон. - Внутреннее содержимое диалогов (StyledDialog) обернуто в QScrollArea с автоскроллом и ограничением по высоте до 720px во избежание выхода окон за пределы экрана. - TitleBar упрощен до простой верхней панели вкладок (sub-header/tabs). - В диалог теста подсветки добавлен выбор номера ленты (1..4) при тесте пикселя виртуальной матрицы, обновлена логика генерации и отправки тестовой команды. - Раздел "Бродяга морей" переименован в "Бродяги морей".
69 lines
3.2 KiB
Python
69 lines
3.2 KiB
Python
"""Базовый класс для стилизованных диалоговых окон.
|
||
|
||
Использует стандартные системные рамки и заголовки, поддерживает
|
||
изменение размеров, сворачивание и разворачивание диалогов.
|
||
Внутреннее содержимое оборачивается в прокручиваемую область (QScrollArea),
|
||
чтобы избежать проблем с выходом окон за границы экрана при низком разрешении.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from PySide6.QtCore import QSize, Qt
|
||
from PySide6.QtWidgets import (
|
||
QDialog,
|
||
QScrollArea,
|
||
QVBoxLayout,
|
||
QWidget,
|
||
)
|
||
|
||
|
||
class StyledDialog(QDialog):
|
||
"""QDialog со стандартной рамкой, прокруткой содержимого и поддержкой изменения размеров."""
|
||
|
||
def __init__(self, parent: QWidget | None = None, **kwargs) -> None:
|
||
super().__init__(parent, **kwargs)
|
||
self.setWindowFlags(
|
||
Qt.WindowType.Dialog
|
||
| Qt.WindowType.WindowMinimizeButtonHint
|
||
| Qt.WindowType.WindowMaximizeButtonHint
|
||
| Qt.WindowType.WindowCloseButtonHint
|
||
)
|
||
|
||
# Главный макет диалога
|
||
main_layout = QVBoxLayout(self)
|
||
main_layout.setContentsMargins(0, 0, 0, 0)
|
||
main_layout.setSpacing(0)
|
||
|
||
# Прокручиваемая область для содержимого
|
||
self._scroll_area = QScrollArea(self)
|
||
self._scroll_area.setWidgetResizable(True)
|
||
self._scroll_area.setFrameShape(QScrollArea.Shape.NoFrame)
|
||
self._scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||
main_layout.addWidget(self._scroll_area)
|
||
|
||
# Виджет-контейнер для содержимого
|
||
self._content_widget = QWidget()
|
||
self._scroll_area.setWidget(self._content_widget)
|
||
|
||
# Макет содержимого
|
||
self._body_layout = QVBoxLayout(self._content_widget)
|
||
self._body_layout.setContentsMargins(12, 12, 12, 12)
|
||
self._body_layout.setSpacing(8)
|
||
|
||
def setWindowTitle(self, title: str) -> None: # noqa: N802
|
||
super().setWindowTitle(title)
|
||
|
||
def containerLayout(self) -> QVBoxLayout:
|
||
"""Вернуть layout области содержимого (для совместимости с наследниками)."""
|
||
return self._body_layout
|
||
|
||
def sizeHint(self) -> QSize:
|
||
"""Вычислить предпочтительный размер на основе содержимого, ограничивая высоту."""
|
||
hint = self._scroll_area.widget().sizeHint()
|
||
# Добавляем небольшой запас по ширине для вертикальной полосы прокрутки
|
||
hint.setWidth(hint.width() + 18)
|
||
# Ограничиваем высоту 720 пикселями на случай больших макетов (например, тест подсветки)
|
||
if hint.height() > 720:
|
||
hint.setHeight(720)
|
||
return hint
|