CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyqt-fluent-widgets

A fluent design widgets library based on PyQt5 providing modern Windows 11-style UI components

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

settings-config.mddocs/

Settings and Configuration

Setting cards, configuration management, and option panels for building preference interfaces with validation and persistence. These components provide a modern approach to application settings with fluent design integration.

Capabilities

Setting Cards

Pre-built setting cards for common configuration options with automatic validation and fluent design styling.

class SettingCard(QWidget):
    def __init__(self, icon: Union[FluentIconBase, QIcon, str], title: str, content: str = None, parent=None): ...
    def setTitle(self, title: str): ...
    def setContent(self, content: str): ...
    def setValue(self, value): ...
    def value(self): ...

class SwitchSettingCard(SettingCard):
    def __init__(self, icon: Union[FluentIconBase, QIcon, str], title: str, content: str = None, 
                 configItem: ConfigItem = None, parent=None): ...
    def setChecked(self, checked: bool): ...
    def isChecked(self) -> bool: ...
    
    checkedChanged = pyqtSignal(bool)

class ComboBoxSettingCard(SettingCard):
    def __init__(self, configItem: ConfigItem, icon: Union[FluentIconBase, QIcon, str], 
                 title: str, content: str = None, texts: List[str] = None, parent=None): ...
    def setCurrentIndex(self, index: int): ...
    def setCurrentText(self, text: str): ...
    def currentIndex(self) -> int: ...
    def currentText(self) -> str: ...

class RangeSettingCard(SettingCard):
    def __init__(self, configItem: ConfigItem, icon: Union[FluentIconBase, QIcon, str],
                 title: str, content: str = None, parent=None): ...
    def setRange(self, min: int, max: int): ...
    def setValue(self, value: int): ...
    def value(self) -> int: ...

Usage Example:

from qfluentwidgets import (SwitchSettingCard, ComboBoxSettingCard, RangeSettingCard, 
                           FluentIcon as FIF, ConfigItem, qconfig)

# Switch setting
auto_save_card = SwitchSettingCard(
    FIF.SAVE,
    "Auto Save",
    "Automatically save documents every 5 minutes"
)
auto_save_card.setChecked(True)
auto_save_card.checkedChanged.connect(self.on_auto_save_changed)

# Combo box setting
theme_card = ComboBoxSettingCard(
    qconfig.theme,  # Config item
    FIF.BRUSH,
    "Theme",
    "Choose the application theme",
    texts=["Light", "Dark", "Auto"]
)
theme_card.setCurrentText("Auto")

# Range setting
volume_card = RangeSettingCard(
    qconfig.volume,
    FIF.VOLUME,
    "Volume",
    "Adjust the application volume"
)
volume_card.setRange(0, 100)
volume_card.setValue(75)

Advanced Setting Cards

Specialized setting cards for complex configuration options.

class PushSettingCard(SettingCard):
    def __init__(self, text: str, icon: Union[FluentIconBase, QIcon, str], 
                 title: str, content: str = None, parent=None): ...
    def setButtonText(self, text: str): ...
    def buttonText(self) -> str: ...
    
    clicked = pyqtSignal()

class ColorSettingCard(SettingCard):
    def __init__(self, configItem: ConfigItem, icon: Union[FluentIconBase, QIcon, str],
                 title: str, content: str = None, enableAlpha: bool = False, parent=None): ...
    def setColor(self, color: QColor): ...
    def color(self) -> QColor: ...
    
    colorChanged = pyqtSignal(QColor)

class HyperlinkCard(SettingCard):
    def __init__(self, url: str, text: str, icon: Union[FluentIconBase, QIcon, str],
                 title: str, content: str = None, parent=None): ...
    def setUrl(self, url: str): ...
    def setText(self, text: str): ...

class ExpandSettingCard(SettingCard):
    def __init__(self, icon: Union[FluentIconBase, QIcon, str], title: str, content: str = None, parent=None): ...
    def addWidget(self, widget: QWidget): ...
    def setExpanded(self, expanded: bool): ...
    def isExpanded(self) -> bool: ...
    
    expandedChanged = pyqtSignal(bool)

Usage Example:

from qfluentwidgets import (PushSettingCard, ColorSettingCard, HyperlinkCard, 
                           ExpandSettingCard, FluentIcon as FIF)

# Button setting card
export_card = PushSettingCard(
    "Export Settings",
    FIF.SHARE,
    "Export Configuration",
    "Export your settings to a file"
)
export_card.clicked.connect(self.export_settings)

# Color setting card
accent_card = ColorSettingCard(
    qconfig.themeColor,
    FIF.PALETTE,
    "Accent Color",
    "Choose your preferred accent color",
    enableAlpha=False
)
accent_card.colorChanged.connect(self.on_accent_color_changed)

# Hyperlink card
docs_card = HyperlinkCard(
    "https://docs.example.com",
    "View Documentation",
    FIF.DOCUMENT,
    "Help & Support",
    "Access online documentation and tutorials"
)

# Expandable setting card
advanced_card = ExpandSettingCard(
    FIF.DEVELOPER_TOOLS,
    "Advanced Settings",
    "Configure advanced options"
)

# Add widgets to expandable card
debug_switch = SwitchSettingCard(FIF.BUG, "Debug Mode", "Enable debug logging")
cache_button = PushSettingCard("Clear Cache", FIF.DELETE, "Cache", "Clear application cache")

advanced_card.addWidget(debug_switch)
advanced_card.addWidget(cache_button)

Setting Card Groups

Containers for organizing related setting cards with proper spacing and grouping.

class SettingCardGroup(QWidget):
    def __init__(self, title: str, parent=None): ...
    def addSettingCard(self, card: SettingCard): ...
    def addSettingCards(self, cards: List[SettingCard]): ...
    def setTitle(self, title: str): ...
    def title(self) -> str: ...

Usage Example:

from qfluentwidgets import SettingCardGroup

# Create setting groups
appearance_group = SettingCardGroup("Appearance", self)
appearance_group.addSettingCard(theme_card)
appearance_group.addSettingCard(accent_card)

behavior_group = SettingCardGroup("Behavior", self)
behavior_group.addSettingCard(auto_save_card)
behavior_group.addSettingCard(volume_card)

advanced_group = SettingCardGroup("Advanced", self)
advanced_group.addSettingCard(advanced_card)
advanced_group.addSettingCard(export_card)

# Layout groups in settings interface
settings_layout = QVBoxLayout()
settings_layout.addWidget(appearance_group)
settings_layout.addWidget(behavior_group)
settings_layout.addWidget(advanced_group)

Configuration System

Robust configuration management with validation, serialization, and automatic persistence.

class QConfig(QObject):
    def __init__(self): ...
    def get(self, item: ConfigItem): ...
    def set(self, item: ConfigItem, value, save: bool = True): ...
    def save(self): ...
    def load(self, file: str = None): ...
    
    configChanged = pyqtSignal(ConfigItem, object)

class ConfigItem:
    def __init__(self, group: str, name: str, default, validator: ConfigValidator = None, 
                 serializer: ConfigSerializer = None, restart: bool = False): ...
    def value(self): ...
    def setValue(self, value): ...

class RangeConfigItem(ConfigItem):
    def __init__(self, group: str, name: str, default: Union[int, float], 
                 range: Tuple[Union[int, float], Union[int, float]], validator: ConfigValidator = None): ...

class OptionsConfigItem(ConfigItem):
    def __init__(self, group: str, name: str, default, options: List, validator: ConfigValidator = None): ...

class ColorConfigItem(ConfigItem):
    def __init__(self, group: str, name: str, default: QColor, validator: ConfigValidator = None): ...

Usage Example:

from qfluentwidgets import QConfig, ConfigItem, RangeConfigItem, OptionsConfigItem, ColorConfigItem

# Create global config instance
qconfig = QConfig()

# Define configuration items
class Config:
    # Basic config items
    auto_save = ConfigItem("General", "AutoSave", True)
    language = OptionsConfigItem("General", "Language", "English", ["English", "Spanish", "French"])
    
    # Range config
    volume = RangeConfigItem("Audio", "Volume", 75, (0, 100))
    
    # Color config
    theme_color = ColorConfigItem("Theme", "AccentColor", QColor(0, 120, 212))

# Register with global config
for item in [Config.auto_save, Config.language, Config.volume, Config.theme_color]:
    qconfig.addConfigItem(item)

# Load configuration
qconfig.load("config.json")

# Use configuration values
if qconfig.get(Config.auto_save):
    self.enable_auto_save()

# React to changes
qconfig.configChanged.connect(self.on_config_changed)

def on_config_changed(self, item, value):
    if item == Config.theme_color:
        self.update_theme_color(value)

Configuration Validators

Input validation for configuration values with custom validation logic.

class ConfigValidator:
    def validate(self, value) -> bool: ...
    def correct(self, value): ...

class RangeValidator(ConfigValidator):
    def __init__(self, min_value: Union[int, float], max_value: Union[int, float]): ...

class OptionsValidator(ConfigValidator):
    def __init__(self, options: List): ...

class BoolValidator(ConfigValidator): ...

class FolderValidator(ConfigValidator): ...

class FolderListValidator(ConfigValidator): ...

class ColorValidator(ConfigValidator): ...

Usage Example:

from qfluentwidgets import RangeValidator, OptionsValidator, ColorValidator

# Custom validator
class EmailValidator(ConfigValidator):
    def validate(self, value):
        return "@" in str(value) and "." in str(value).split("@")[-1]
    
    def correct(self, value):
        if not self.validate(value):
            return "user@example.com"
        return value

# Configuration with validation
email_config = ConfigItem(
    "User", 
    "Email", 
    "user@example.com", 
    validator=EmailValidator()
)

# Range validation
volume_config = RangeConfigItem(
    "Audio", 
    "Volume", 
    50, 
    (0, 100),
    validator=RangeValidator(0, 100)
)

# Options validation
theme_config = OptionsConfigItem(
    "Appearance",
    "Theme",
    "Auto",
    ["Light", "Dark", "Auto"],
    validator=OptionsValidator(["Light", "Dark", "Auto"])
)

Configuration Serializers

Custom serialization for complex configuration data types.

class ConfigSerializer:
    def serialize(self, value) -> str: ...
    def deserialize(self, value: str): ...

class EnumSerializer(ConfigSerializer):
    def __init__(self, enum_class): ...

class ColorSerializer(ConfigSerializer): ...

Usage Example:

from qfluentwidgets import EnumSerializer, ColorSerializer
from enum import Enum

# Enum serialization
class Priority(Enum):
    LOW = 1
    MEDIUM = 2
    HIGH = 3

priority_config = ConfigItem(
    "Tasks",
    "DefaultPriority", 
    Priority.MEDIUM,
    serializer=EnumSerializer(Priority)
)

# Color serialization
color_config = ConfigItem(
    "Theme",
    "AccentColor",
    QColor(0, 120, 212),
    serializer=ColorSerializer()
)

# Custom serializer
class ListSerializer(ConfigSerializer):
    def serialize(self, value):
        return ",".join(str(v) for v in value)
    
    def deserialize(self, value):
        return [item.strip() for item in value.split(",") if item.strip()]

favorites_config = ConfigItem(
    "User",
    "FavoriteFolders",
    ["/home/user/Documents", "/home/user/Pictures"],
    serializer=ListSerializer()
)

Complete Settings Interface Example

from qfluentwidgets import *

class SettingsInterface(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi()
        self.connectSignals()
    
    def setupUi(self):
        # Main layout
        layout = QVBoxLayout(self)
        
        # Title
        title = LargeTitleLabel("Settings")
        layout.addWidget(title)
        
        # Scroll area for settings
        scroll = SmoothScrollArea(self)
        scroll_widget = QWidget()
        scroll_layout = QVBoxLayout(scroll_widget)
        
        # General settings group
        general_group = SettingCardGroup("General")
        
        self.auto_save_card = SwitchSettingCard(
            FIF.SAVE, "Auto Save", "Automatically save changes"
        )
        self.language_card = ComboBoxSettingCard(
            None, FIF.LOCALE, "Language", "Select interface language",
            texts=["English", "Spanish", "French", "German"]
        )
        
        general_group.addSettingCards([self.auto_save_card, self.language_card])
        
        # Appearance settings group
        appearance_group = SettingCardGroup("Appearance")
        
        self.theme_card = ComboBoxSettingCard(
            None, FIF.BRUSH, "Theme", "Choose application theme",
            texts=["Light", "Dark", "Auto"]
        )
        self.accent_card = ColorSettingCard(
            None, FIF.PALETTE, "Accent Color", "Personalize your accent color"
        )
        
        appearance_group.addSettingCards([self.theme_card, self.accent_card])
        
        # Advanced settings group
        advanced_group = SettingCardGroup("Advanced")
        
        self.debug_card = SwitchSettingCard(
            FIF.DEVELOPER_TOOLS, "Debug Mode", "Enable debugging features"
        )
        self.export_card = PushSettingCard(
            "Export", FIF.SHARE, "Export Settings", "Save settings to file"
        )
        
        advanced_group.addSettingCards([self.debug_card, self.export_card])
        
        # Add groups to layout
        scroll_layout.addWidget(general_group)
        scroll_layout.addWidget(appearance_group)
        scroll_layout.addWidget(advanced_group)
        scroll_layout.addStretch()
        
        scroll.setWidget(scroll_widget)
        layout.addWidget(scroll)
    
    def connectSignals(self):
        self.auto_save_card.checkedChanged.connect(self.on_auto_save_changed)
        self.language_card.currentTextChanged.connect(self.on_language_changed)
        self.theme_card.currentTextChanged.connect(self.on_theme_changed)
        self.accent_card.colorChanged.connect(self.on_accent_changed)
        self.export_card.clicked.connect(self.export_settings)
    
    def on_auto_save_changed(self, checked):
        qconfig.set(Config.auto_save, checked)
    
    def on_language_changed(self, language):
        qconfig.set(Config.language, language)
    
    def on_theme_changed(self, theme):
        theme_enum = Theme.LIGHT if theme == "Light" else Theme.DARK if theme == "Dark" else Theme.AUTO
        setTheme(theme_enum)
    
    def on_accent_changed(self, color):
        setThemeColor(color)
    
    def export_settings(self):
        file_path, _ = QFileDialog.getSaveFileName(self, "Export Settings", "", "JSON files (*.json)")
        if file_path:
            qconfig.save(file_path)

Install with Tessl CLI

npx tessl i tessl/pypi-pyqt-fluent-widgets

docs

buttons.md

dialog-notification.md

display-widgets.md

index.md

input-controls.md

layout-animation.md

list-view-widgets.md

material-effects.md

menu-command.md

multimedia.md

settings-config.md

theme-styling.md

window-navigation.md

tile.json