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

input-controls.mddocs/

Input Controls

Comprehensive form controls including text inputs, combo boxes, sliders, date/time pickers, and spinboxes with fluent design styling and advanced features. All input controls provide consistent user interaction patterns, validation support, and automatic theme integration.

Capabilities

Text Input Controls

Single and multi-line text input widgets with modern styling and specialized variants for different input types.

class LineEdit(QLineEdit):
    def __init__(self, parent=None): ...
    def setPlaceholderText(self, text: str): ...
    def placeholderText(self) -> str: ...

class SearchLineEdit(LineEdit):
    def __init__(self, parent=None): ...
    def setSearchButtonVisible(self, visible: bool): ...
    searchSignal = pyqtSignal(str)
    clearSignal = pyqtSignal()

class PasswordLineEdit(LineEdit):
    def __init__(self, parent=None): ...
    def setEchoMode(self, mode: QLineEdit.EchoMode): ...

class TextEdit(QTextEdit):
    def __init__(self, parent=None): ...
    def setPlaceholderText(self, text: str): ...

class PlainTextEdit(QPlainTextEdit):
    def __init__(self, parent=None): ...
    def setPlaceholderText(self, text: str): ...

class TextBrowser(QTextBrowser):
    def __init__(self, parent=None): ...

Usage Example:

from qfluentwidgets import (LineEdit, SearchLineEdit, PasswordLineEdit, 
                           TextEdit, PlainTextEdit)

# Basic text input
name_input = LineEdit(self)
name_input.setPlaceholderText("Enter your name")
name_input.textChanged.connect(self.on_name_changed)

# Search input with search button
search_input = SearchLineEdit(self)
search_input.setPlaceholderText("Search files...")
search_input.searchSignal.connect(self.perform_search)
search_input.clearSignal.connect(self.clear_search)

# Password input
password_input = PasswordLineEdit(self)
password_input.setPlaceholderText("Password")
password_input.setEchoMode(QLineEdit.Password)

# Multi-line text
description_input = TextEdit(self)
description_input.setPlaceholderText("Enter description here...")
description_input.setMaximumHeight(120)

# Plain text editor
code_editor = PlainTextEdit(self)
code_editor.setPlaceholderText("Enter code here...")
font = QFont("Consolas", 10)
code_editor.setFont(font)

Combo Box Controls

Dropdown selection controls with support for editable options, custom models, and various selection patterns.

class ComboBox(QComboBox):
    def __init__(self, parent=None): ...
    def setPlaceholderText(self, text: str): ...
    def addItems(self, items: List[str]): ...
    def setCurrentIndex(self, index: int): ...
    def setCurrentText(self, text: str): ...

class EditableComboBox(ComboBox):
    def __init__(self, parent=None): ...
    def setCompleter(self, completer: QCompleter): ...

class ModelComboBox(ComboBox):
    def __init__(self, parent=None): ...
    def setModel(self, model: QAbstractItemModel): ...

class EditableModelComboBox(ModelComboBox):
    def __init__(self, parent=None): ...

Usage Example:

from qfluentwidgets import ComboBox, EditableComboBox, ModelComboBox
from PyQt5.QtCore import QStringListModel

# Basic combo box
language_combo = ComboBox(self)
language_combo.setPlaceholderText("Select language")
languages = ["Python", "JavaScript", "Java", "C++", "C#"]
language_combo.addItems(languages)
language_combo.setCurrentIndex(-1)  # No selection
language_combo.currentTextChanged.connect(self.on_language_changed)

# Editable combo box
country_combo = EditableComboBox(self)
countries = ["United States", "Canada", "United Kingdom", "Germany"]
country_combo.addItems(countries)
country_combo.setPlaceholderText("Type or select country")

# Model-based combo box
model = QStringListModel(["Item 1", "Item 2", "Item 3"])
model_combo = ModelComboBox(self)
model_combo.setModel(model)
model_combo.setPlaceholderText("Choose from model")

Slider Controls

Interactive sliders for numeric value selection with smooth animations and custom styling.

class Slider(QSlider):
    def __init__(self, orientation=Qt.Horizontal, parent=None): ...
    def setRange(self, min: int, max: int): ...
    def setValue(self, value: int): ...
    def value(self) -> int: ...

class ClickableSlider(Slider):
    def __init__(self, orientation=Qt.Horizontal, parent=None): ...
    # Allows clicking anywhere on slider to set value

class HollowHandleStyle:
    # Custom slider handle style with hollow appearance
    pass

Usage Example:

from qfluentwidgets import Slider, ClickableSlider
from PyQt5.QtCore import Qt

# Horizontal slider
volume_slider = Slider(Qt.Horizontal, self)
volume_slider.setRange(0, 100)
volume_slider.setValue(50)
volume_slider.valueChanged.connect(self.set_volume)

# Vertical slider
brightness_slider = Slider(Qt.Vertical, self)
brightness_slider.setRange(0, 255)
brightness_slider.setValue(128)

# Clickable slider (jump to click position)
seek_slider = ClickableSlider(Qt.Horizontal, self)
seek_slider.setRange(0, 1000)
seek_slider.sliderPressed.connect(self.start_seeking)
seek_slider.sliderReleased.connect(self.stop_seeking)

Spin Box Controls

Numeric input controls with increment/decrement buttons and validation.

class SpinBox(QSpinBox):
    def __init__(self, parent=None): ...
    def setRange(self, min: int, max: int): ...
    def setSingleStep(self, step: int): ...

class DoubleSpinBox(QDoubleSpinBox):
    def __init__(self, parent=None): ...
    def setRange(self, min: float, max: float): ...
    def setDecimals(self, decimals: int): ...

class CompactSpinBox(SpinBox):
    def __init__(self, parent=None): ...
    # Smaller, more compact version

class CompactDoubleSpinBox(DoubleSpinBox):
    def __init__(self, parent=None): ...

Usage Example:

from qfluentwidgets import SpinBox, DoubleSpinBox, CompactSpinBox

# Integer spin box
quantity_spin = SpinBox(self)
quantity_spin.setRange(1, 100)
quantity_spin.setSingleStep(1)
quantity_spin.setValue(1)
quantity_spin.valueChanged.connect(self.update_quantity)

# Double precision spin box
price_spin = DoubleSpinBox(self)
price_spin.setRange(0.0, 999999.99)
price_spin.setDecimals(2)
price_spin.setSingleStep(0.01)
price_spin.setPrefix("$")

# Compact spin box for toolbars
compact_spin = CompactSpinBox(self)
compact_spin.setRange(1, 10)
compact_spin.setValue(5)

Date and Time Controls

Date and time selection widgets with calendar popups and various display formats.

class DateEdit(QDateEdit):
    def __init__(self, parent=None): ...
    def setDate(self, date: QDate): ...
    def date(self) -> QDate: ...

class TimeEdit(QTimeEdit):
    def __init__(self, parent=None): ...
    def setTime(self, time: QTime): ...
    def time(self) -> QTime: ...

class DateTimeEdit(QDateTimeEdit):
    def __init__(self, parent=None): ...
    def setDateTime(self, datetime: QDateTime): ...
    def dateTime(self) -> QDateTime: ...

class CompactDateEdit(DateEdit): ...
class CompactTimeEdit(TimeEdit): ...
class CompactDateTimeEdit(DateTimeEdit): ...

Usage Example:

from qfluentwidgets import DateEdit, TimeEdit, DateTimeEdit
from PyQt5.QtCore import QDate, QTime, QDateTime

# Date picker
birth_date = DateEdit(self)
birth_date.setDate(QDate.currentDate())
birth_date.setDisplayFormat("yyyy-MM-dd")
birth_date.dateChanged.connect(self.on_date_changed)

# Time picker
appointment_time = TimeEdit(self)
appointment_time.setTime(QTime.currentTime())
appointment_time.setDisplayFormat("hh:mm AP")

# Date and time picker
event_datetime = DateTimeEdit(self)
event_datetime.setDateTime(QDateTime.currentDateTime())
event_datetime.setDisplayFormat("yyyy-MM-dd hh:mm")

Switch Controls

Toggle switches for boolean settings and on/off states.

class SwitchButton(QWidget):
    def __init__(self, parent=None, indicatorPos=IndicatorPosition.LEFT): ...
    def setChecked(self, checked: bool): ...
    def isChecked(self) -> bool: ...
    def setText(self, text: str): ...
    def text(self) -> str: ...
    
    checkedChanged = pyqtSignal(bool)

class IndicatorPosition(Enum):
    LEFT = 0  
    RIGHT = 1

Usage Example:

from qfluentwidgets import SwitchButton, IndicatorPosition

# Basic switch
notifications_switch = SwitchButton(self)
notifications_switch.setText("Enable Notifications")
notifications_switch.setChecked(True)
notifications_switch.checkedChanged.connect(self.toggle_notifications)

# Switch with indicator on right
auto_save_switch = SwitchButton(self, IndicatorPosition.RIGHT)
auto_save_switch.setText("Auto Save")
auto_save_switch.setChecked(False)

# Multiple switches in settings
switches = [
    ("Dark Mode", self.toggle_dark_mode),
    ("Sound Effects", self.toggle_sound),
    ("Auto Updates", self.toggle_updates)
]

for text, callback in switches:
    switch = SwitchButton(self)
    switch.setText(text)
    switch.checkedChanged.connect(callback)

Check Box Controls

Enhanced check boxes with fluent design styling and tri-state support.

class CheckBox(QCheckBox):
    def __init__(self, parent=None): ...
    def __init__(self, text: str, parent=None): ...
    def setTristate(self, tristate: bool = True): ...
    def isTristate(self) -> bool: ...

Usage Example:

from qfluentwidgets import CheckBox
from PyQt5.QtCore import Qt

# Basic checkbox
agree_checkbox = CheckBox("I agree to the terms and conditions", self)
agree_checkbox.stateChanged.connect(self.on_agreement_changed)

# Tri-state checkbox for hierarchical selection
parent_checkbox = CheckBox("Select All", self)
parent_checkbox.setTristate(True)
parent_checkbox.stateChanged.connect(self.on_parent_selection_changed)

# Child checkboxes
child_checkboxes = []
for item in ["Item 1", "Item 2", "Item 3"]:
    checkbox = CheckBox(item, self)
    checkbox.stateChanged.connect(self.update_parent_state)
    child_checkboxes.append(checkbox)

Advanced Input Features

Line Edit with Buttons

class LineEditButton(LineEdit):
    def __init__(self, parent=None): ...
    def addButton(self, button: QToolButton, position: QLineEdit.ActionPosition): ...

Usage Example:

from qfluentwidgets import LineEditButton, FluentIcon as FIF
from PyQt5.QtWidgets import QToolButton

# Line edit with custom buttons
search_edit = LineEditButton(self)
search_edit.setPlaceholderText("Search...")

# Add search button
search_btn = QToolButton()
search_btn.setIcon(FIF.SEARCH.icon())
search_btn.clicked.connect(self.perform_search)
search_edit.addButton(search_btn, QLineEdit.TrailingPosition)

# Add clear button
clear_btn = QToolButton()
clear_btn.setIcon(FIF.CLOSE.icon())
clear_btn.clicked.connect(search_edit.clear)
search_edit.addButton(clear_btn, QLineEdit.TrailingPosition)

Input Validation and Error Handling

Built-in Validation

# Numeric validation
spin_box = SpinBox(self)
spin_box.setRange(1, 100)  # Automatically validates range

# Date validation
date_edit = DateEdit(self)
date_edit.setDateRange(QDate(2020, 1, 1), QDate(2030, 12, 31))

# Text length validation
line_edit = LineEdit(self)
line_edit.setMaxLength(50)

Custom Validation

from PyQt5.QtGui import QValidator

class EmailValidator(QValidator):
    def validate(self, text: str, pos: int):
        if "@" in text and "." in text.split("@")[-1]:
            return QValidator.Acceptable, text, pos
        return QValidator.Intermediate, text, pos

# Apply custom validator
email_edit = LineEdit(self)
email_edit.setValidator(EmailValidator())

Input State Management

# Track input changes
def setup_form_validation(self):
    self.required_fields = [name_edit, email_edit, phone_edit]
    
    for field in self.required_fields:
        field.textChanged.connect(self.validate_form)
        
def validate_form(self):
    all_valid = all(field.text().strip() for field in self.required_fields)
    self.submit_button.setEnabled(all_valid)

Accessibility and User Experience

Keyboard Navigation

# Set tab order for form controls
self.setTabOrder(name_edit, email_edit)
self.setTabOrder(email_edit, phone_edit)
self.setTabOrder(phone_edit, submit_button)

Screen Reader Support

# Set accessible names and descriptions
name_edit.setAccessibleName("Full Name")
email_edit.setAccessibleDescription("Enter your email address")

Input Feedback

# Visual feedback for validation
def on_email_validation(self, is_valid: bool):
    if is_valid:
        email_edit.setStyleSheet("border: 2px solid green;")
    else:
        email_edit.setStyleSheet("border: 2px solid red;")

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