car_ui/screens/settings.py
2026-01-09 01:01:45 +03:00

289 lines
9.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from PySide6.QtWidgets import (
QWidget,
QLabel,
QVBoxLayout,
QHBoxLayout,
QPushButton,
QSizePolicy,
QScrollArea,
QStackedWidget,
QApplication,
)
from PySide6.QtCore import Qt, Signal
from PySide6.QtGui import QFont
from PySide6.QtWidgets import QScroller
from screens.bluetooth import BluetoothScreen
import build_info
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):
view_changed = Signal(str, bool)
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_rows = self._add_section(
content_layout,
"Сеть",
[
("Wi-Fi", "Доступные сети и подключение"),
("Bluetooth", "Сопряжение и устройства"),
],
)
bt_row = bt_rows.get("Bluetooth")
self._add_section(
content_layout,
"Дисплей и звук",
[
("Экран", "Яркость, сон, тема"),
("Звук", "Громкость, эквалайзер"),
],
)
system_rows = self._add_section(
content_layout,
"Система",
[
("Об устройстве", "Версия, память, серийный номер"),
("Параметры разработчика", "Отладка и логирование"),
],
)
about_row = system_rows.get("Об устройстве")
dev_row = system_rows.get("Параметры разработчика")
content_layout.addStretch(1)
scroll.setWidget(content)
list_layout.addWidget(scroll, 1)
self._dev_screen = self._build_dev_screen()
self._about_screen = self._build_about_screen()
self._bt_screen = BluetoothScreen(self._show_list)
self.stack.addWidget(self._list_screen)
self.stack.addWidget(self._dev_screen)
self.stack.addWidget(self._about_screen)
self.stack.addWidget(self._bt_screen)
if dev_row is not None:
dev_row.clicked.connect(self._show_dev)
if about_row is not None:
about_row.clicked.connect(self._show_about)
if bt_row is not None:
bt_row.clicked.connect(self._show_bluetooth)
self._show_list()
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]],
) -> dict[str, SettingsRow]:
section = QLabel(title)
section.setObjectName("SettingsSection")
section.setFont(QFont("", 14, 700))
section.setContentsMargins(2, 8, 2, 0)
root.addWidget(section)
rows: dict[str, SettingsRow] = {}
for row_title, row_subtitle in items:
row = SettingsRow(row_title, row_subtitle)
root.addWidget(row)
rows[row_title] = row
return rows
def _build_about_screen(self) -> QWidget:
screen = QWidget()
layout = QVBoxLayout(screen)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(12)
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setFrameShape(QScrollArea.NoFrame)
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
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)
info = QVBoxLayout()
info.setContentsMargins(0, 0, 0, 0)
info.setSpacing(8)
info.addWidget(self._info_row("Приложение", build_info.APP_NAME))
info.addWidget(self._info_row("Версия", build_info.VERSION))
info.addWidget(self._info_row("Сборка", build_info.BUILD_DATE))
info.addWidget(self._info_row("Коммит", build_info.GIT_HASH))
info.addWidget(self._info_row("Устройство", build_info.get_device_model()))
info.addWidget(self._info_row("ОС", build_info.get_os_pretty_name()))
info.addWidget(self._info_row("Ядро", build_info.get_kernel_version()))
info.addWidget(self._info_row("RAM (используется/всего)", build_info.get_ram_info()))
info.addWidget(self._info_row("Диск (используется/всего)", build_info.get_disk_info()))
info.addWidget(self._info_row("Серийный номер", build_info.get_serial_number()))
info.addWidget(self._info_row("IP", build_info.get_ip_address()))
info.addWidget(self._info_row("Температура CPU", build_info.get_cpu_temp()))
# title = QLabel("Об устройстве")
# title.setFont(QFont("", 22, 700))
# content_layout.addWidget(title)
content_layout.addLayout(info)
content_layout.addStretch(1)
scroll.setWidget(content)
layout.addWidget(scroll)
return screen
def _info_row(self, label: str, value: str) -> QWidget:
row = QWidget()
layout = QHBoxLayout(row)
layout.setContentsMargins(12, 6, 12, 6)
layout.setSpacing(12)
lbl = QLabel(label)
lbl.setFont(QFont("", 15, 600))
val = QLabel(value)
val.setFont(QFont("", 15))
val.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
layout.addWidget(lbl)
layout.addStretch(1)
layout.addWidget(val)
return row
def _show_dev(self):
self.stack.setCurrentWidget(self._dev_screen)
self.view_changed.emit("Параметры разработчика", True)
def _show_list(self):
self.stack.setCurrentWidget(self._list_screen)
self.view_changed.emit("Настройки", False)
def _show_bluetooth(self):
self.stack.setCurrentWidget(self._bt_screen)
self.view_changed.emit("Bluetooth", True)
def _show_about(self):
self.stack.setCurrentWidget(self._about_screen)
self.view_changed.emit("Об устройстве", True)
def show_list(self):
self._show_list()
def _exit_app(self):
app = QApplication.instance()
if app is not None:
app.quit()