0
# Theme and Styling System
1
2
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.
3
4
## Capabilities
5
6
### Theme Management
7
8
Core theme functionality for switching between light, dark, and automatic modes with system integration.
9
10
```python { .api }
11
class Theme(Enum):
12
LIGHT = "Light"
13
DARK = "Dark"
14
AUTO = "Auto"
15
16
def setTheme(theme: Theme): ...
17
def theme() -> Theme: ...
18
def isDarkTheme() -> bool: ...
19
def isDarkThemeMode() -> bool: ...
20
def toggleTheme(): ...
21
```
22
23
**Usage Example:**
24
```python
25
from qfluentwidgets import setTheme, Theme, isDarkTheme, toggleTheme
26
27
# Set specific theme
28
setTheme(Theme.DARK)
29
setTheme(Theme.LIGHT)
30
setTheme(Theme.AUTO) # Follow system theme
31
32
# Check current theme
33
if isDarkTheme():
34
print("Dark theme is active")
35
36
# Toggle between light and dark
37
toggleTheme()
38
39
# React to theme changes
40
def on_theme_changed():
41
if isDarkTheme():
42
self.update_dark_theme_icons()
43
else:
44
self.update_light_theme_icons()
45
```
46
47
### Color System
48
49
Theme color management and customization with predefined fluent design colors.
50
51
```python { .api }
52
class ThemeColor(Enum):
53
DEFAULT_BLUE = 0
54
# Additional theme colors available
55
56
class FluentThemeColor(Enum):
57
DEFAULT_BLUE = auto()
58
RED = auto()
59
PINK = auto()
60
PURPLE = auto()
61
DEEP_PURPLE = auto()
62
INDIGO = auto()
63
BLUE = auto()
64
LIGHT_BLUE = auto()
65
CYAN = auto()
66
TEAL = auto()
67
GREEN = auto()
68
LIGHT_GREEN = auto()
69
LIME = auto()
70
YELLOW = auto()
71
AMBER = auto()
72
ORANGE = auto()
73
DEEP_ORANGE = auto()
74
BROWN = auto()
75
BLUE_GREY = auto()
76
GREY = auto()
77
78
def setThemeColor(color: QColor): ...
79
def themeColor() -> QColor: ...
80
def applyThemeColor(): ...
81
```
82
83
**Usage Example:**
84
```python
85
from qfluentwidgets import setThemeColor, themeColor, FluentThemeColor
86
from PyQt5.QtGui import QColor
87
88
# Set predefined theme color
89
setThemeColor(FluentThemeColor.RED.color())
90
setThemeColor(FluentThemeColor.TEAL.color())
91
92
# Set custom color
93
custom_color = QColor(120, 80, 200)
94
setThemeColor(custom_color)
95
96
# Get current theme color
97
current = themeColor()
98
print(f"Current theme color: {current.name()}")
99
100
# Available fluent colors
101
colors = [
102
FluentThemeColor.BLUE,
103
FluentThemeColor.GREEN,
104
FluentThemeColor.PURPLE,
105
FluentThemeColor.ORANGE,
106
FluentThemeColor.RED
107
]
108
109
for color in colors:
110
print(f"{color.name}: {color.color().name()}")
111
```
112
113
### System Theme Listener
114
115
Automatic detection and response to system theme changes for seamless user experience.
116
117
```python { .api }
118
class SystemThemeListener(QObject):
119
def __init__(self, parent=None): ...
120
def start(self): ...
121
def stop(self): ...
122
# Signals
123
themeChanged = pyqtSignal(Theme)
124
```
125
126
**Usage Example:**
127
```python
128
from qfluentwidgets import SystemThemeListener, Theme
129
130
# Create theme listener
131
theme_listener = SystemThemeListener(self)
132
133
# Connect to theme changes
134
theme_listener.themeChanged.connect(self.on_system_theme_changed)
135
136
# Start listening
137
theme_listener.start()
138
139
def on_system_theme_changed(self, theme: Theme):
140
print(f"System theme changed to: {theme.value}")
141
self.update_ui_for_theme(theme)
142
143
# Stop listening when not needed
144
theme_listener.stop()
145
```
146
147
### Style Sheet System
148
149
Advanced stylesheet management with fluent design patterns and automatic theme application.
150
151
```python { .api }
152
class FluentStyleSheet(Enum):
153
BUTTON = "button"
154
PUSH_BUTTON = "push_button"
155
TOOL_BUTTON = "tool_button"
156
TOGGLE_BUTTON = "toggle_button"
157
LINE_EDIT = "line_edit"
158
COMBO_BOX = "combo_box"
159
MENU = "menu"
160
NAVIGATION_INTERFACE = "navigation_interface"
161
# Many more stylesheet types available
162
163
class StyleSheetBase:
164
def apply(self, widget: QWidget): ...
165
def content(self) -> str: ...
166
167
class StyleSheetFile(StyleSheetBase):
168
def __init__(self, file: Union[str, Path]): ...
169
170
class StyleSheetCompose(StyleSheetBase):
171
def __init__(self, *stylesheets: StyleSheetBase): ...
172
def add(self, stylesheet: StyleSheetBase): ...
173
174
class CustomStyleSheet(StyleSheetBase):
175
def __init__(self, **kwargs): ...
176
177
def setStyleSheet(widget: QWidget, stylesheet: Union[str, StyleSheetBase]): ...
178
def getStyleSheet(widget: QWidget) -> str: ...
179
def setCustomStyleSheet(widget: QWidget, stylesheet: str, theme: Theme): ...
180
```
181
182
**Usage Example:**
183
```python
184
from qfluentwidgets import (FluentStyleSheet, setStyleSheet, CustomStyleSheet,
185
Theme, setCustomStyleSheet)
186
187
# Apply fluent stylesheet to widget
188
button = QPushButton("Styled Button", self)
189
FluentStyleSheet.BUTTON.apply(button)
190
191
# Custom stylesheet
192
custom_style = CustomStyleSheet(
193
background_color="rgba(255, 255, 255, 0.8)",
194
border_radius="6px",
195
font_size="14px"
196
)
197
setStyleSheet(button, custom_style)
198
199
# Theme-specific custom styles
200
light_style = "background-color: white; color: black;"
201
dark_style = "background-color: #2b2b2b; color: white;"
202
203
setCustomStyleSheet(widget, light_style, Theme.LIGHT)
204
setCustomStyleSheet(widget, dark_style, Theme.DARK)
205
206
# Compose multiple stylesheets
207
composed = StyleSheetCompose(
208
FluentStyleSheet.BUTTON,
209
CustomStyleSheet(font_weight="bold")
210
)
211
composed.apply(button)
212
```
213
214
### Icon System
215
216
Comprehensive icon management with theme-aware colors and fluent design icons.
217
218
```python { .api }
219
class FluentIcon(FluentIconBase, Enum):
220
# Navigation Icons
221
HOME = "Home"
222
BACK = "Back"
223
FORWARD = "Forward"
224
UP = "Up"
225
REFRESH = "Refresh"
226
227
# File Icons
228
FOLDER = "Folder"
229
DOCUMENT = "Document"
230
SAVE = "Save"
231
SAVE_AS = "SaveAs"
232
OPEN = "Open"
233
234
# Media Icons
235
PLAY = "Play"
236
PAUSE = "Pause"
237
STOP = "Stop"
238
MUSIC = "Music"
239
VIDEO = "Video"
240
PHOTO = "Photo"
241
242
# Action Icons
243
ADD = "Add"
244
DELETE = "Delete"
245
EDIT = "Edit"
246
COPY = "Copy"
247
PASTE = "Paste"
248
CUT = "Cut"
249
250
# UI Icons
251
CLOSE = "Close"
252
MINIMIZE = "Minimize"
253
MAXIMIZE = "Maximize"
254
SETTING = "Setting"
255
SEARCH = "Search"
256
FILTER = "Filter"
257
258
# Communication Icons
259
MAIL = "Mail"
260
SEND = "Send"
261
SHARE = "Share"
262
CONTACT = "Contact"
263
PHONE = "Phone"
264
265
# Status Icons
266
ACCEPT = "Accept"
267
CANCEL = "Cancel"
268
WARNING = "Warning"
269
ERROR = "Error"
270
INFO = "Info"
271
272
# And many more...
273
274
class FluentIconBase(Enum):
275
def icon(self, theme: Theme = Theme.AUTO, color: QColor = None) -> QIcon: ...
276
def qicon(self) -> QIcon: ...
277
278
class Icon(QIcon):
279
def __init__(self, icon: Union[FluentIconBase, QIcon, str]): ...
280
281
def getIconColor(theme: Theme = Theme.AUTO) -> QColor: ...
282
def drawSvgIcon(icon: Union[str, FluentIconBase], rect: QRect, painter: QPainter): ...
283
def drawIcon(icon: Union[FluentIconBase, QIcon, str], painter: QPainter, rect: QRect,
284
state: QIcon.State = QIcon.Normal): ...
285
def writeSvg(iconPath: str, color: QColor, outputPath: str): ...
286
```
287
288
**Usage Example:**
289
```python
290
from qfluentwidgets import FluentIcon as FIF, Icon, getIconColor, Theme
291
from PyQt5.QtGui import QColor
292
293
# Use fluent icons
294
home_icon = FIF.HOME
295
save_icon = FIF.SAVE
296
settings_icon = FIF.SETTING
297
298
# Create QIcon from fluent icon
299
qicon = home_icon.icon()
300
themed_icon = home_icon.icon(Theme.DARK)
301
colored_icon = home_icon.icon(color=QColor(255, 0, 0))
302
303
# Use in widgets
304
button = QPushButton("Home", self)
305
button.setIcon(FIF.HOME.icon())
306
307
# Get theme-appropriate icon color
308
icon_color = getIconColor()
309
print(f"Current icon color: {icon_color.name()}")
310
311
# Custom icon creation
312
custom_icon = Icon(FIF.CUSTOM_ICON)
313
314
# Available icon categories (171+ icons total)
315
316
# Navigation Icons
317
navigation_icons = [
318
FIF.HOME, FIF.BACK, FIF.FORWARD, FIF.UP, FIF.DOWN,
319
FIF.ARROW_LEFT, FIF.ARROW_RIGHT, FIF.ARROW_UP, FIF.ARROW_DOWN,
320
FIF.CHEVRON_LEFT, FIF.CHEVRON_RIGHT, FIF.CHEVRON_UP, FIF.CHEVRON_DOWN,
321
FIF.MENU, FIF.MORE, FIF.REFRESH
322
]
323
324
# File and Document Icons
325
file_icons = [
326
FIF.FOLDER, FIF.FOLDER_ADD, FIF.OPEN_FOLDER,
327
FIF.DOCUMENT, FIF.SAVE, FIF.SAVE_AS, FIF.SAVE_COPY,
328
FIF.OPEN, FIF.CLOSE, FIF.PRINT, FIF.EXPORT, FIF.IMPORT
329
]
330
331
# Media and Entertainment Icons
332
media_icons = [
333
FIF.PLAY, FIF.PAUSE, FIF.STOP, FIF.PREVIOUS, FIF.NEXT,
334
FIF.MUSIC, FIF.VIDEO, FIF.PHOTO, FIF.CAMERA, FIF.MIC,
335
FIF.VOLUME, FIF.MUTE, FIF.HEADPHONE
336
]
337
338
# Action and Edit Icons
339
action_icons = [
340
FIF.ADD, FIF.DELETE, FIF.REMOVE, FIF.EDIT, FIF.CUT, FIF.COPY, FIF.PASTE,
341
FIF.UNDO, FIF.REDO, FIF.SEARCH, FIF.FILTER, FIF.SORT,
342
FIF.ACCEPT, FIF.CANCEL, FIF.CLOSE_PANE
343
]
344
345
# UI and Interface Icons
346
ui_icons = [
347
FIF.SETTING, FIF.MINIMIZE, FIF.MAXIMIZE, FIF.FULL_SCREEN,
348
FIF.VIEW, FIF.HIDE, FIF.PIN, FIF.UNPIN,
349
FIF.ZOOM_IN, FIF.ZOOM_OUT, FIF.FIT_PAGE
350
]
351
352
# Communication Icons
353
communication_icons = [
354
FIF.MAIL, FIF.SEND, FIF.SHARE, FIF.CONTACT, FIF.PEOPLE,
355
FIF.PHONE, FIF.CHAT, FIF.MESSAGE, FIF.NOTIFICATION
356
]
357
358
# Status and System Icons
359
status_icons = [
360
FIF.INFO, FIF.WARNING, FIF.ERROR, FIF.HELP, FIF.QUESTION,
361
FIF.COMPLETED, FIF.SYNC, FIF.UPDATE, FIF.DOWNLOAD, FIF.UPLOAD,
362
FIF.CLOUD, FIF.WIFI, FIF.GLOBE, FIF.LINK
363
]
364
365
# Development and Tools Icons
366
dev_icons = [
367
FIF.CODE, FIF.DEVELOPER_TOOLS, FIF.BUG, FIF.TAG, FIF.BRANCH,
368
FIF.COMMAND_PROMPT, FIF.DATABASE, FIF.SERVER, FIF.GITHUB
369
]
370
371
# Shopping and Commerce Icons
372
commerce_icons = [
373
FIF.SHOP, FIF.CART, FIF.MARKET, FIF.CERTIFICATE, FIF.MONEY,
374
FIF.CREDIT_CARD, FIF.RECEIPT, FIF.DISCOUNT
375
]
376
```
377
378
### Font System
379
380
Font management for consistent typography across the application.
381
382
```python { .api }
383
def setFont(font: QFont, widget: QWidget = None): ...
384
def getFont(size: int = 14, weight: QFont.Weight = QFont.Normal) -> QFont: ...
385
```
386
387
**Usage Example:**
388
```python
389
from qfluentwidgets import setFont, getFont
390
from PyQt5.QtGui import QFont
391
392
# Set application font
393
app_font = QFont("Segoe UI", 10)
394
setFont(app_font)
395
396
# Get system-appropriate font
397
fluent_font = getFont(14, QFont.Medium)
398
title_font = getFont(18, QFont.Bold)
399
400
# Apply to specific widget
401
label = QLabel("Title Text", self)
402
label.setFont(title_font)
403
```
404
405
### Text Wrapping
406
407
Utility for intelligent text wrapping and formatting.
408
409
```python { .api }
410
class TextWrap:
411
@staticmethod
412
def wrap(text: str, width: int, font: QFont) -> List[str]: ...
413
@staticmethod
414
def elidedText(text: str, font: QFont, width: int, mode: Qt.TextElideMode = Qt.ElideRight) -> str: ...
415
```
416
417
**Usage Example:**
418
```python
419
from qfluentwidgets import TextWrap
420
from PyQt5.QtCore import Qt
421
422
# Wrap long text
423
long_text = "This is a very long text that needs to be wrapped..."
424
font = getFont(12)
425
wrapped_lines = TextWrap.wrap(long_text, 200, font)
426
427
# Elide text
428
elided = TextWrap.elidedText(long_text, font, 150, Qt.ElideRight)
429
print(elided) # "This is a very long text..."
430
```
431
432
### Smooth Scrolling
433
434
Enhanced scrolling behavior for smoother user interactions.
435
436
```python { .api }
437
class SmoothMode(Enum):
438
NO_SMOOTH = 0
439
CONSTANT = 1
440
LINEAR = 2
441
QUADRATIC = 3
442
COSINE = 4
443
444
class SmoothScroll:
445
def __init__(self, widget: QAbstractScrollArea, orient=Qt.Vertical): ...
446
def setSmoothMode(self, mode: SmoothMode): ...
447
def smoothMode(self) -> SmoothMode: ...
448
```
449
450
**Usage Example:**
451
```python
452
from qfluentwidgets import SmoothScroll, SmoothMode
453
from PyQt5.QtCore import Qt
454
455
# Apply smooth scrolling to scroll area
456
scroll_area = QScrollArea(self)
457
smooth_scroll = SmoothScroll(scroll_area, Qt.Vertical)
458
smooth_scroll.setSmoothMode(SmoothMode.COSINE)
459
460
# Apply to list widget
461
list_widget = QListWidget(self)
462
list_smooth = SmoothScroll(list_widget)
463
list_smooth.setSmoothMode(SmoothMode.LINEAR)
464
```
465
466
## Theme Integration Patterns
467
468
### Application-Wide Theme Setup
469
```python
470
from qfluentwidgets import setTheme, Theme, setThemeColor, FluentThemeColor
471
472
class MainApplication:
473
def __init__(self):
474
# Set initial theme
475
setTheme(Theme.AUTO)
476
477
# Set brand color
478
setThemeColor(FluentThemeColor.BLUE.color())
479
480
# Enable automatic theme switching
481
self.setup_theme_listener()
482
483
def setup_theme_listener(self):
484
self.theme_listener = SystemThemeListener(self)
485
self.theme_listener.themeChanged.connect(self.handle_theme_change)
486
self.theme_listener.start()
487
```
488
489
### Widget-Specific Styling
490
```python
491
# Apply consistent styling to custom widgets
492
class CustomWidget(QWidget):
493
def __init__(self, parent=None):
494
super().__init__(parent)
495
self.setup_ui()
496
self.apply_theme()
497
498
def apply_theme(self):
499
FluentStyleSheet.BUTTON.apply(self.button)
500
FluentStyleSheet.LINE_EDIT.apply(self.line_edit)
501
502
# Custom styling
503
if isDarkTheme():
504
self.setStyleSheet("background-color: #2b2b2b;")
505
else:
506
self.setStyleSheet("background-color: white;")
507
```
508
509
### Dynamic Theme Updates
510
```python
511
def update_theme_colors(self, new_color: QColor):
512
# Update theme color
513
setThemeColor(new_color)
514
515
# Update all themed widgets
516
for widget in self.themed_widgets:
517
widget.update()
518
519
# Refresh icons
520
self.refresh_themed_icons()
521
```