from PySide6.QtWidgets import ( QWidget, QLabel, QVBoxLayout, QHBoxLayout, QPushButton, QSizePolicy, QScrollArea, QStackedWidget, QApplication, ) from PySide6.QtCore import Qt from PySide6.QtGui import QFont from PySide6.QtWidgets import QScroller from screens.bluetooth import BluetoothScreen class SettingsRow(QPushButton): def __init__(self, title: str, subtitle: str): super().__init__() self.setObjectName("SettingsRow") self.setCursor(Qt.PointingHandCursor) self.setCheckable(False) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.setMinimumHeight(70) row = QHBoxLayout(self) row.setContentsMargins(16, 10, 16, 10) row.setSpacing(12) text_col = QVBoxLayout() text_col.setContentsMargins(0, 0, 0, 0) text_col.setSpacing(2) lbl_title = QLabel(title) lbl_title.setObjectName("SettingsRowTitle") lbl_title.setFont(QFont("", 16, 600)) lbl_sub = QLabel(subtitle) lbl_sub.setObjectName("SettingsRowSub") lbl_sub.setFont(QFont("", 12)) lbl_sub.setWordWrap(False) text_col.addWidget(lbl_title) text_col.addWidget(lbl_sub) chevron = QLabel("›") chevron.setObjectName("SettingsChevron") chevron.setFont(QFont("", 20, 600)) chevron.setAlignment(Qt.AlignRight | Qt.AlignVCenter) row.addLayout(text_col) row.addStretch(1) row.addWidget(chevron) class SettingsScreen(QWidget): def __init__(self): super().__init__() root = QVBoxLayout(self) root.setContentsMargins(18, 16, 18, 16) root.setSpacing(12) self.stack = QStackedWidget() root.addWidget(self.stack, 1) self._list_screen = QWidget() list_layout = QVBoxLayout(self._list_screen) list_layout.setContentsMargins(0, 0, 0, 0) list_layout.setSpacing(12) list_title = QLabel("Настройки") list_title.setFont(QFont("", 24, 700)) list_layout.addWidget(list_title) scroll = QScrollArea() scroll.setWidgetResizable(True) scroll.setFrameShape(QScrollArea.NoFrame) scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # === TOUCH SCROLL (Raspberry safe) === scroller = QScroller.scroller(scroll.viewport()) scroller.grabGesture( scroll.viewport(), QScroller.LeftMouseButtonGesture ) content = QWidget() content_layout = QVBoxLayout(content) content_layout.setContentsMargins(0, 0, 0, 0) content_layout.setSpacing(12) bt_row = self._add_section( content_layout, "Сеть", [ ("Wi-Fi", "Доступные сети и подключение"), ("Bluetooth", "Сопряжение и устройства"), ], return_row_title="Bluetooth", ) dev_row = self._add_section( content_layout, "Система", [ ("Об устройстве", "Версия, память, серийный номер"), ("Параметры разработчика", "Отладка и логирование"), ], return_row_title="Параметры разработчика", ) self._add_section( content_layout, "Дисплей и звук", [ ("Экран", "Яркость, сон, тема"), ("Звук", "Громкость, эквалайзер"), ], ) content_layout.addStretch(1) scroll.setWidget(content) list_layout.addWidget(scroll, 1) self._dev_screen = self._build_dev_screen() self._bt_screen = BluetoothScreen(self._show_list) self.stack.addWidget(self._list_screen) self.stack.addWidget(self._dev_screen) self.stack.addWidget(self._bt_screen) if dev_row is not None: dev_row.clicked.connect(self._show_dev) if bt_row is not None: bt_row.clicked.connect(self._show_bluetooth) def _build_dev_screen(self) -> QWidget: screen = QWidget() layout = QVBoxLayout(screen) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(12) hdr = QHBoxLayout() hdr.setContentsMargins(0, 0, 0, 0) hdr.setSpacing(12) back_btn = QPushButton("Назад") back_btn.setObjectName("SettingsBackBtn") back_btn.setMinimumSize(120, 44) back_btn.clicked.connect(self._show_list) title = QLabel("Параметры разработчика") title.setFont(QFont("", 22, 700)) hdr.addWidget(back_btn) hdr.addWidget(title) hdr.addStretch(1) exit_btn = QPushButton("Переход к рабочему столу") exit_btn.setObjectName("DevExitBtn") exit_btn.setMinimumHeight(72) exit_btn.clicked.connect(self._exit_app) layout.addLayout(hdr) layout.addWidget(exit_btn) layout.addStretch(1) return screen def _add_section( self, root: QVBoxLayout, title: str, items: list[tuple[str, str]], return_row_title: str | None = None, ): section = QLabel(title) section.setObjectName("SettingsSection") section.setFont(QFont("", 14, 700)) section.setContentsMargins(2, 8, 2, 0) root.addWidget(section) target_row = None for row_title, row_subtitle in items: row = SettingsRow(row_title, row_subtitle) root.addWidget(row) if return_row_title and row_title == return_row_title: target_row = row return target_row def _show_dev(self): self.stack.setCurrentWidget(self._dev_screen) def _show_list(self): self.stack.setCurrentWidget(self._list_screen) def _show_bluetooth(self): self.stack.setCurrentWidget(self._bt_screen) def _exit_app(self): app = QApplication.instance() if app is not None: app.quit()