- Переименованы элементы выбора физического канала в настройках WS2812: "1-й канал" -> "2-й канал", "2-й" -> "3-й", "3-й" -> "4-й". - Удален неиспользуемый "4-й канал (4)", так как команды 894XY не существует. - Изменения внесены в LedTestDialog и LedTestSection. - Версия приложения обновлена до 1.4.1.
211 lines
8.3 KiB
Python
211 lines
8.3 KiB
Python
"""Встраиваемая секция «Тест цвета» — цветовое чередование диодов.
|
||
|
||
Позволяет задать порядок цветов (RGB/RBG/…) командой 89
|
||
и запустить тест: красный → зелёный → синий.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from PySide6.QtCore import Qt, QTimer
|
||
from PySide6.QtWidgets import (
|
||
QCheckBox,
|
||
QColorDialog,
|
||
QFormLayout,
|
||
QGroupBox,
|
||
QHBoxLayout,
|
||
QLabel,
|
||
QMessageBox,
|
||
QPushButton,
|
||
QSpinBox,
|
||
QVBoxLayout,
|
||
QWidget,
|
||
)
|
||
|
||
from ...services.com_service import ComConnection
|
||
from ...ui.icons import get_icon_color, icon
|
||
from ..no_wheel_combo_box import NoWheelComboBox
|
||
|
||
_COLOR_ORDERS: list[tuple[int, str]] = [
|
||
(0, "RGB"),
|
||
(1, "RBG"),
|
||
(2, "BRG"),
|
||
(3, "BGR"),
|
||
(4, "GRB"),
|
||
(5, "GBR"),
|
||
]
|
||
|
||
|
||
class LedTestSection(QWidget):
|
||
"""Inline-секция тест цвета (для базового режима)."""
|
||
|
||
def __init__(self, connection: ComConnection, parent: QWidget | None = None) -> None:
|
||
super().__init__(parent)
|
||
self._conn = connection
|
||
self._setup_ui()
|
||
|
||
# ── UI ────────────────────────────────────────────────────────────
|
||
|
||
def _setup_ui(self) -> None:
|
||
root = QVBoxLayout(self)
|
||
root.setContentsMargins(0, 0, 0, 0)
|
||
root.setSpacing(10)
|
||
|
||
# ── Настройки WS2812 (cmd 89) ──
|
||
color_group = QGroupBox("Настройки WS2812 (cmd 89)")
|
||
color_form = QFormLayout(color_group)
|
||
color_form.setSpacing(6)
|
||
|
||
desc = QLabel(
|
||
"Настройки вывода WS2812. Выберите физический канал и настройте порядок цветов, "
|
||
"яркость или гамма-коррекцию."
|
||
)
|
||
desc.setWordWrap(True)
|
||
desc.setObjectName("HelpText")
|
||
color_form.addRow(desc)
|
||
|
||
# Выбор физического канала
|
||
self._cmd89_channel_combo = NoWheelComboBox()
|
||
self._cmd89_channel_combo.addItem("Все ленты (0)", 0)
|
||
self._cmd89_channel_combo.addItem("2-й канал (1)", 1)
|
||
self._cmd89_channel_combo.addItem("3-й канал (2)", 2)
|
||
self._cmd89_channel_combo.addItem("4-й канал (3)", 3)
|
||
color_form.addRow("Физический канал:", self._cmd89_channel_combo)
|
||
|
||
# Порядок цветов
|
||
self._color_order_combo = NoWheelComboBox()
|
||
for code, name in _COLOR_ORDERS:
|
||
self._color_order_combo.addItem(f"{code} — {name}", code)
|
||
|
||
self._set_color_btn = QPushButton("Применить порядок")
|
||
self._set_color_btn.setProperty("role", "primary")
|
||
self._set_color_btn.setIcon(icon("fa5s.palette", color="#ecfdf5"))
|
||
self._set_color_btn.clicked.connect(self._send_color_order)
|
||
|
||
order_layout = QHBoxLayout()
|
||
order_layout.addWidget(self._color_order_combo, 1)
|
||
order_layout.addWidget(self._set_color_btn)
|
||
color_form.addRow("Порядок цветов:", order_layout)
|
||
|
||
# Яркость
|
||
self._cmd89_brightness_spin = QSpinBox()
|
||
self._cmd89_brightness_spin.setRange(0, 255)
|
||
self._cmd89_brightness_spin.setValue(255)
|
||
|
||
apply_bright_btn = QPushButton("Применить яркость")
|
||
apply_bright_btn.setIcon(icon("fa5s.sun", color=get_icon_color()))
|
||
apply_bright_btn.clicked.connect(self._send_brightness)
|
||
|
||
bright_layout = QHBoxLayout()
|
||
bright_layout.addWidget(self._cmd89_brightness_spin, 1)
|
||
bright_layout.addWidget(apply_bright_btn)
|
||
color_form.addRow("Яркость:", bright_layout)
|
||
|
||
# Гамма-коррекция
|
||
self._cmd89_gamma_check = QCheckBox("Включить гамма-коррекцию")
|
||
|
||
apply_gamma_btn = QPushButton("Применить гамму")
|
||
apply_gamma_btn.setIcon(icon("fa5s.adjust", color=get_icon_color()))
|
||
apply_gamma_btn.clicked.connect(self._send_gamma)
|
||
|
||
gamma_layout = QHBoxLayout()
|
||
gamma_layout.addWidget(self._cmd89_gamma_check, 1)
|
||
gamma_layout.addWidget(apply_gamma_btn)
|
||
color_form.addRow("Гамма-коррекция:", gamma_layout)
|
||
|
||
# Пользовательский цвет
|
||
self._custom_color_btn = QPushButton("Выбрать и отправить цвет")
|
||
self._custom_color_btn.setIcon(icon("fa5s.palette", color=get_icon_color()))
|
||
self._custom_color_btn.clicked.connect(self._send_custom_color)
|
||
color_form.addRow("Свой цвет (08):", self._custom_color_btn)
|
||
|
||
# Тест цвета
|
||
self._color_test_btn = QPushButton("Тест цвета")
|
||
self._color_test_btn.setProperty("role", "primary")
|
||
self._color_test_btn.setIcon(icon("fa5s.eye", color="#ecfdf5"))
|
||
self._color_test_btn.clicked.connect(self._run_color_test)
|
||
color_form.addRow(self._color_test_btn)
|
||
|
||
color_hint = QLabel("Должны вывестись: красный → зелёный → синий")
|
||
color_hint.setStyleSheet("color: #9ca3af; font-size: 11px;")
|
||
color_hint.setWordWrap(True)
|
||
color_form.addRow(color_hint)
|
||
|
||
root.addWidget(color_group)
|
||
|
||
# ── Лог ──
|
||
self._log = QLabel("")
|
||
self._log.setObjectName("LogLabel")
|
||
self._log.setWordWrap(True)
|
||
root.addWidget(self._log)
|
||
|
||
# ── Public ────────────────────────────────────────────────────────
|
||
|
||
def refresh_icons(self) -> None:
|
||
"""Нет theme-dependent иконок — ничего не делаем."""
|
||
|
||
# ── Отправка ──────────────────────────────────────────────────────
|
||
|
||
def _send_color_order(self) -> None:
|
||
ch = self._cmd89_channel_combo.currentData()
|
||
code = self._color_order_combo.currentData()
|
||
cmd = f"89{ch}0{code}"
|
||
self._send(cmd)
|
||
|
||
def _send_brightness(self) -> None:
|
||
ch = self._cmd89_channel_combo.currentData()
|
||
val = self._cmd89_brightness_spin.value()
|
||
cmd = f"89{ch}1{val}"
|
||
self._send(cmd)
|
||
|
||
def _send_gamma(self) -> None:
|
||
ch = self._cmd89_channel_combo.currentData()
|
||
val = 1 if self._cmd89_gamma_check.isChecked() else 0
|
||
cmd = f"89{ch}2{val}"
|
||
self._send(cmd)
|
||
|
||
def _send_custom_color(self) -> None:
|
||
color = QColorDialog.getColor(Qt.GlobalColor.white, self, "Выберите цвет")
|
||
if color.isValid():
|
||
ch = self._cmd89_channel_combo.currentData()
|
||
r = color.red()
|
||
g = color.green()
|
||
b = color.blue()
|
||
cmd = f"8{ch}08{r:03d}{g:03d}{b:03d}"
|
||
self._send(cmd)
|
||
|
||
def _run_color_test(self) -> None:
|
||
self._color_test_cmds = ["8003", "8004", "8005", "8002", "8000"]
|
||
self._color_test_idx = 0
|
||
self._color_test_btn.setEnabled(False)
|
||
self._color_test_timer = QTimer(self)
|
||
self._color_test_timer.setInterval(1000)
|
||
self._color_test_timer.timeout.connect(self._color_test_step)
|
||
self._color_test_step()
|
||
self._color_test_timer.start()
|
||
|
||
def _color_test_step(self) -> None:
|
||
if self._color_test_idx >= len(self._color_test_cmds):
|
||
self._color_test_timer.stop()
|
||
self._color_test_btn.setEnabled(True)
|
||
return
|
||
cmd = self._color_test_cmds[self._color_test_idx]
|
||
self._color_test_idx += 1
|
||
self._send(cmd)
|
||
|
||
def _send(self, cmd: str) -> None:
|
||
if not cmd:
|
||
return
|
||
if not self._conn.is_connected:
|
||
QMessageBox.warning(self, "Ошибка", "Порт не подключён.")
|
||
return
|
||
try:
|
||
self._conn.send_command(cmd)
|
||
self._log.setText(f"→ {cmd}")
|
||
resp = self._conn.read_response(timeout=0.3)
|
||
self._conn.release()
|
||
if resp:
|
||
self._log.setText(f"→ {cmd}\n← {resp}")
|
||
except Exception as exc:
|
||
self._conn.release()
|
||
self._log.setText(f"Ошибка: {exc}")
|