from PySide6.QtCore import Signal
from PySide6.QtWidgets import (
QWidget,
QFrame,
QLabel,
QHBoxLayout,
QVBoxLayout,
)
from .cards import Card
from .inputs import ToggleSwitch
class SettingRow(QWidget):
"""
Reusable settings row: bold title +
gray subtitle on the left, optional
Enabled/Disabled state label and a
ToggleSwitch on the right.
"""
toggled = Signal(bool)
def __init__(
self,
title,
subtitle="",
checked=False,
show_state=False,
parent=None,
):
super().__init__(parent)
layout = QHBoxLayout(self)
layout.setContentsMargins(0, 12, 0, 12)
layout.setSpacing(14)
text_layout = QVBoxLayout()
text_layout.setContentsMargins(0, 0, 0, 0)
text_layout.setSpacing(2)
self.title_label = QLabel(title)
self.title_label.setObjectName(
"SettingTitle"
)
self.subtitle_label = QLabel(subtitle)
self.subtitle_label.setObjectName(
"SettingSubtitle"
)
text_layout.addWidget(self.title_label)
text_layout.addWidget(self.subtitle_label)
if not subtitle:
self.subtitle_label.hide()
layout.addLayout(text_layout)
layout.addStretch()
self.state_label = QLabel()
self.state_label.setObjectName(
"SettingState"
)
layout.addWidget(self.state_label)
if not show_state:
self.state_label.hide()
self.switch = ToggleSwitch(
checked=checked
)
layout.addWidget(self.switch)
self.switch.toggled.connect(
self._on_toggled
)
self._update_state(checked)
def _on_toggled(self, checked):
self._update_state(checked)
self.toggled.emit(checked)
def _update_state(self, checked):
self.state_label.setText(
"Enabled" if checked else "Disabled"
)
def is_on(self):
return self.switch.isChecked()
def set_on(self, value):
self.switch.setChecked(value)
class SettingsGroup(Card):
"""
Card holding a titled list of
SettingRow widgets, separated by
thin lines.
"""
def __init__(
self,
title="",
parent=None,
):
super().__init__(parent)
self._layout = QVBoxLayout(self)
self._layout.setContentsMargins(
20, 16, 20, 16
)
self._layout.setSpacing(0)
if title:
title_label = QLabel(title)
title_label.setObjectName(
"SettingsGroupTitle"
)
self._layout.addWidget(title_label)
self._layout.addSpacing(6)
self._row_count = 0
self._separators = {}
def add_row(self, row):
if self._row_count > 0:
separator = QFrame()
separator.setObjectName(
"SettingsSeparator"
)
separator.setFixedHeight(1)
self._layout.addWidget(separator)
self._separators[row] = separator
self._layout.addWidget(row)
self._row_count += 1
return row
def separator_for(self, row):
"""
Linia de deasupra randului (None pentru
primul). Utila cand se filtreaza randuri
si separatoarele trebuie ascunse odata
cu ele.
"""
return self._separators.get(row)
cards qss
/* Tema unica alb/negru (decizie de echipa).
StatCard / LightStatCard sunt objectName-urile
setate de StatCard(card_style=...). */
QFrame#Card,
QFrame#StatCard,
QFrame#LightStatCard {
background-color: #ffffff;
border: 1px solid #e5e7eb;
border-radius: 15px;
}
/* Stat Card Labels */
QLabel#StatNumber {
color: #181717;
font-size: 22px;
font-weight: 800;
}
QLabel#StatLabel {
color: #6b7280;
font-size: 11px;
font-weight: 600;
}
/* Separator between setting rows */
QFrame#SettingsSeparator {
background-color: #f0f0f0;
border: none;
}
/* Hover doar pe cardurile interactive.
Se activeaza cu setProperty("interactive", True)
pe card — aceeasi conventie ca la ModernCard. */
QFrame#Card[interactive="true"]:hover,
QFrame#StatCard[interactive="true"]:hover,
QFrame#LightStatCard[interactive="true"]:hover {
background-color: #fafafa;
border: 1px solid #9ca3af;
}
/* ==========================================================
MODERN REUSABLE CARDS
========================================================== */
QFrame#ModernCard {
background-color: #ffffff;
border: 1px solid #d1d5db;
border-radius: 18px;
}
/* Large page panel */
QFrame#ModernCard[variant="panel"] {
background-color: #ffffff;
border: 1px solid #c7ccd4;
border-radius: 22px;
}
/* Main preview wrapper */
QFrame#ModernCard[variant="preview"] {
background-color: #f8f9fb;
border: 1px solid #d5d9df;
border-radius: 18px;
}
/* Smaller inner section */
QFrame#ModernCard[variant="section"] {
background-color: #ffffff;
border: 1px solid #d9dde3;
border-radius: 14px;
}
/* Interactive hover */
QFrame#ModernCard[interactive="true"]:hover {
background-color: #ffffff;
border: 2px solid #181717;
}