A fluent design widgets library based on PyQt5 providing modern Windows 11-style UI components
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Comprehensive theme management with automatic dark/light mode detection, color customization, and fluent design stylesheets. The styling system provides consistent visual appearance across all widgets with smooth theme transitions and customizable accent colors.
Core theme functionality for switching between light, dark, and automatic modes with system integration.
class Theme(Enum):
LIGHT = "Light"
DARK = "Dark"
AUTO = "Auto"
def setTheme(theme: Theme): ...
def theme() -> Theme: ...
def isDarkTheme() -> bool: ...
def isDarkThemeMode() -> bool: ...
def toggleTheme(): ...Usage Example:
from qfluentwidgets import setTheme, Theme, isDarkTheme, toggleTheme
# Set specific theme
setTheme(Theme.DARK)
setTheme(Theme.LIGHT)
setTheme(Theme.AUTO) # Follow system theme
# Check current theme
if isDarkTheme():
print("Dark theme is active")
# Toggle between light and dark
toggleTheme()
# React to theme changes
def on_theme_changed():
if isDarkTheme():
self.update_dark_theme_icons()
else:
self.update_light_theme_icons()Theme color management and customization with predefined fluent design colors.
class ThemeColor(Enum):
DEFAULT_BLUE = 0
# Additional theme colors available
class FluentThemeColor(Enum):
DEFAULT_BLUE = auto()
RED = auto()
PINK = auto()
PURPLE = auto()
DEEP_PURPLE = auto()
INDIGO = auto()
BLUE = auto()
LIGHT_BLUE = auto()
CYAN = auto()
TEAL = auto()
GREEN = auto()
LIGHT_GREEN = auto()
LIME = auto()
YELLOW = auto()
AMBER = auto()
ORANGE = auto()
DEEP_ORANGE = auto()
BROWN = auto()
BLUE_GREY = auto()
GREY = auto()
def setThemeColor(color: QColor): ...
def themeColor() -> QColor: ...
def applyThemeColor(): ...Usage Example:
from qfluentwidgets import setThemeColor, themeColor, FluentThemeColor
from PyQt5.QtGui import QColor
# Set predefined theme color
setThemeColor(FluentThemeColor.RED.color())
setThemeColor(FluentThemeColor.TEAL.color())
# Set custom color
custom_color = QColor(120, 80, 200)
setThemeColor(custom_color)
# Get current theme color
current = themeColor()
print(f"Current theme color: {current.name()}")
# Available fluent colors
colors = [
FluentThemeColor.BLUE,
FluentThemeColor.GREEN,
FluentThemeColor.PURPLE,
FluentThemeColor.ORANGE,
FluentThemeColor.RED
]
for color in colors:
print(f"{color.name}: {color.color().name()}")Automatic detection and response to system theme changes for seamless user experience.
class SystemThemeListener(QObject):
def __init__(self, parent=None): ...
def start(self): ...
def stop(self): ...
# Signals
themeChanged = pyqtSignal(Theme)Usage Example:
from qfluentwidgets import SystemThemeListener, Theme
# Create theme listener
theme_listener = SystemThemeListener(self)
# Connect to theme changes
theme_listener.themeChanged.connect(self.on_system_theme_changed)
# Start listening
theme_listener.start()
def on_system_theme_changed(self, theme: Theme):
print(f"System theme changed to: {theme.value}")
self.update_ui_for_theme(theme)
# Stop listening when not needed
theme_listener.stop()Advanced stylesheet management with fluent design patterns and automatic theme application.
class FluentStyleSheet(Enum):
BUTTON = "button"
PUSH_BUTTON = "push_button"
TOOL_BUTTON = "tool_button"
TOGGLE_BUTTON = "toggle_button"
LINE_EDIT = "line_edit"
COMBO_BOX = "combo_box"
MENU = "menu"
NAVIGATION_INTERFACE = "navigation_interface"
# Many more stylesheet types available
class StyleSheetBase:
def apply(self, widget: QWidget): ...
def content(self) -> str: ...
class StyleSheetFile(StyleSheetBase):
def __init__(self, file: Union[str, Path]): ...
class StyleSheetCompose(StyleSheetBase):
def __init__(self, *stylesheets: StyleSheetBase): ...
def add(self, stylesheet: StyleSheetBase): ...
class CustomStyleSheet(StyleSheetBase):
def __init__(self, **kwargs): ...
def setStyleSheet(widget: QWidget, stylesheet: Union[str, StyleSheetBase]): ...
def getStyleSheet(widget: QWidget) -> str: ...
def setCustomStyleSheet(widget: QWidget, stylesheet: str, theme: Theme): ...Usage Example:
from qfluentwidgets import (FluentStyleSheet, setStyleSheet, CustomStyleSheet,
Theme, setCustomStyleSheet)
# Apply fluent stylesheet to widget
button = QPushButton("Styled Button", self)
FluentStyleSheet.BUTTON.apply(button)
# Custom stylesheet
custom_style = CustomStyleSheet(
background_color="rgba(255, 255, 255, 0.8)",
border_radius="6px",
font_size="14px"
)
setStyleSheet(button, custom_style)
# Theme-specific custom styles
light_style = "background-color: white; color: black;"
dark_style = "background-color: #2b2b2b; color: white;"
setCustomStyleSheet(widget, light_style, Theme.LIGHT)
setCustomStyleSheet(widget, dark_style, Theme.DARK)
# Compose multiple stylesheets
composed = StyleSheetCompose(
FluentStyleSheet.BUTTON,
CustomStyleSheet(font_weight="bold")
)
composed.apply(button)Comprehensive icon management with theme-aware colors and fluent design icons.
class FluentIcon(FluentIconBase, Enum):
# Navigation Icons
HOME = "Home"
BACK = "Back"
FORWARD = "Forward"
UP = "Up"
REFRESH = "Refresh"
# File Icons
FOLDER = "Folder"
DOCUMENT = "Document"
SAVE = "Save"
SAVE_AS = "SaveAs"
OPEN = "Open"
# Media Icons
PLAY = "Play"
PAUSE = "Pause"
STOP = "Stop"
MUSIC = "Music"
VIDEO = "Video"
PHOTO = "Photo"
# Action Icons
ADD = "Add"
DELETE = "Delete"
EDIT = "Edit"
COPY = "Copy"
PASTE = "Paste"
CUT = "Cut"
# UI Icons
CLOSE = "Close"
MINIMIZE = "Minimize"
MAXIMIZE = "Maximize"
SETTING = "Setting"
SEARCH = "Search"
FILTER = "Filter"
# Communication Icons
MAIL = "Mail"
SEND = "Send"
SHARE = "Share"
CONTACT = "Contact"
PHONE = "Phone"
# Status Icons
ACCEPT = "Accept"
CANCEL = "Cancel"
WARNING = "Warning"
ERROR = "Error"
INFO = "Info"
# And many more...
class FluentIconBase(Enum):
def icon(self, theme: Theme = Theme.AUTO, color: QColor = None) -> QIcon: ...
def qicon(self) -> QIcon: ...
class Icon(QIcon):
def __init__(self, icon: Union[FluentIconBase, QIcon, str]): ...
def getIconColor(theme: Theme = Theme.AUTO) -> QColor: ...
def drawSvgIcon(icon: Union[str, FluentIconBase], rect: QRect, painter: QPainter): ...
def drawIcon(icon: Union[FluentIconBase, QIcon, str], painter: QPainter, rect: QRect,
state: QIcon.State = QIcon.Normal): ...
def writeSvg(iconPath: str, color: QColor, outputPath: str): ...Usage Example:
from qfluentwidgets import FluentIcon as FIF, Icon, getIconColor, Theme
from PyQt5.QtGui import QColor
# Use fluent icons
home_icon = FIF.HOME
save_icon = FIF.SAVE
settings_icon = FIF.SETTING
# Create QIcon from fluent icon
qicon = home_icon.icon()
themed_icon = home_icon.icon(Theme.DARK)
colored_icon = home_icon.icon(color=QColor(255, 0, 0))
# Use in widgets
button = QPushButton("Home", self)
button.setIcon(FIF.HOME.icon())
# Get theme-appropriate icon color
icon_color = getIconColor()
print(f"Current icon color: {icon_color.name()}")
# Custom icon creation
custom_icon = Icon(FIF.CUSTOM_ICON)
# Available icon categories (171+ icons total)
# Navigation Icons
navigation_icons = [
FIF.HOME, FIF.BACK, FIF.FORWARD, FIF.UP, FIF.DOWN,
FIF.ARROW_LEFT, FIF.ARROW_RIGHT, FIF.ARROW_UP, FIF.ARROW_DOWN,
FIF.CHEVRON_LEFT, FIF.CHEVRON_RIGHT, FIF.CHEVRON_UP, FIF.CHEVRON_DOWN,
FIF.MENU, FIF.MORE, FIF.REFRESH
]
# File and Document Icons
file_icons = [
FIF.FOLDER, FIF.FOLDER_ADD, FIF.OPEN_FOLDER,
FIF.DOCUMENT, FIF.SAVE, FIF.SAVE_AS, FIF.SAVE_COPY,
FIF.OPEN, FIF.CLOSE, FIF.PRINT, FIF.EXPORT, FIF.IMPORT
]
# Media and Entertainment Icons
media_icons = [
FIF.PLAY, FIF.PAUSE, FIF.STOP, FIF.PREVIOUS, FIF.NEXT,
FIF.MUSIC, FIF.VIDEO, FIF.PHOTO, FIF.CAMERA, FIF.MIC,
FIF.VOLUME, FIF.MUTE, FIF.HEADPHONE
]
# Action and Edit Icons
action_icons = [
FIF.ADD, FIF.DELETE, FIF.REMOVE, FIF.EDIT, FIF.CUT, FIF.COPY, FIF.PASTE,
FIF.UNDO, FIF.REDO, FIF.SEARCH, FIF.FILTER, FIF.SORT,
FIF.ACCEPT, FIF.CANCEL, FIF.CLOSE_PANE
]
# UI and Interface Icons
ui_icons = [
FIF.SETTING, FIF.MINIMIZE, FIF.MAXIMIZE, FIF.FULL_SCREEN,
FIF.VIEW, FIF.HIDE, FIF.PIN, FIF.UNPIN,
FIF.ZOOM_IN, FIF.ZOOM_OUT, FIF.FIT_PAGE
]
# Communication Icons
communication_icons = [
FIF.MAIL, FIF.SEND, FIF.SHARE, FIF.CONTACT, FIF.PEOPLE,
FIF.PHONE, FIF.CHAT, FIF.MESSAGE, FIF.NOTIFICATION
]
# Status and System Icons
status_icons = [
FIF.INFO, FIF.WARNING, FIF.ERROR, FIF.HELP, FIF.QUESTION,
FIF.COMPLETED, FIF.SYNC, FIF.UPDATE, FIF.DOWNLOAD, FIF.UPLOAD,
FIF.CLOUD, FIF.WIFI, FIF.GLOBE, FIF.LINK
]
# Development and Tools Icons
dev_icons = [
FIF.CODE, FIF.DEVELOPER_TOOLS, FIF.BUG, FIF.TAG, FIF.BRANCH,
FIF.COMMAND_PROMPT, FIF.DATABASE, FIF.SERVER, FIF.GITHUB
]
# Shopping and Commerce Icons
commerce_icons = [
FIF.SHOP, FIF.CART, FIF.MARKET, FIF.CERTIFICATE, FIF.MONEY,
FIF.CREDIT_CARD, FIF.RECEIPT, FIF.DISCOUNT
]Font management for consistent typography across the application.
def setFont(font: QFont, widget: QWidget = None): ...
def getFont(size: int = 14, weight: QFont.Weight = QFont.Normal) -> QFont: ...Usage Example:
from qfluentwidgets import setFont, getFont
from PyQt5.QtGui import QFont
# Set application font
app_font = QFont("Segoe UI", 10)
setFont(app_font)
# Get system-appropriate font
fluent_font = getFont(14, QFont.Medium)
title_font = getFont(18, QFont.Bold)
# Apply to specific widget
label = QLabel("Title Text", self)
label.setFont(title_font)Utility for intelligent text wrapping and formatting.
class TextWrap:
@staticmethod
def wrap(text: str, width: int, font: QFont) -> List[str]: ...
@staticmethod
def elidedText(text: str, font: QFont, width: int, mode: Qt.TextElideMode = Qt.ElideRight) -> str: ...Usage Example:
from qfluentwidgets import TextWrap
from PyQt5.QtCore import Qt
# Wrap long text
long_text = "This is a very long text that needs to be wrapped..."
font = getFont(12)
wrapped_lines = TextWrap.wrap(long_text, 200, font)
# Elide text
elided = TextWrap.elidedText(long_text, font, 150, Qt.ElideRight)
print(elided) # "This is a very long text..."Enhanced scrolling behavior for smoother user interactions.
class SmoothMode(Enum):
NO_SMOOTH = 0
CONSTANT = 1
LINEAR = 2
QUADRATIC = 3
COSINE = 4
class SmoothScroll:
def __init__(self, widget: QAbstractScrollArea, orient=Qt.Vertical): ...
def setSmoothMode(self, mode: SmoothMode): ...
def smoothMode(self) -> SmoothMode: ...Usage Example:
from qfluentwidgets import SmoothScroll, SmoothMode
from PyQt5.QtCore import Qt
# Apply smooth scrolling to scroll area
scroll_area = QScrollArea(self)
smooth_scroll = SmoothScroll(scroll_area, Qt.Vertical)
smooth_scroll.setSmoothMode(SmoothMode.COSINE)
# Apply to list widget
list_widget = QListWidget(self)
list_smooth = SmoothScroll(list_widget)
list_smooth.setSmoothMode(SmoothMode.LINEAR)from qfluentwidgets import setTheme, Theme, setThemeColor, FluentThemeColor
class MainApplication:
def __init__(self):
# Set initial theme
setTheme(Theme.AUTO)
# Set brand color
setThemeColor(FluentThemeColor.BLUE.color())
# Enable automatic theme switching
self.setup_theme_listener()
def setup_theme_listener(self):
self.theme_listener = SystemThemeListener(self)
self.theme_listener.themeChanged.connect(self.handle_theme_change)
self.theme_listener.start()# Apply consistent styling to custom widgets
class CustomWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setup_ui()
self.apply_theme()
def apply_theme(self):
FluentStyleSheet.BUTTON.apply(self.button)
FluentStyleSheet.LINE_EDIT.apply(self.line_edit)
# Custom styling
if isDarkTheme():
self.setStyleSheet("background-color: #2b2b2b;")
else:
self.setStyleSheet("background-color: white;")def update_theme_colors(self, new_color: QColor):
# Update theme color
setThemeColor(new_color)
# Update all themed widgets
for widget in self.themed_widgets:
widget.update()
# Refresh icons
self.refresh_themed_icons()Install with Tessl CLI
npx tessl i tessl/pypi-pyqt-fluent-widgets