initial fluent-widgets ui

This commit is contained in:
2025-08-14 18:45:16 +08:00
parent 746e83ab23
commit 4c66886257
1198 changed files with 805339 additions and 0 deletions

35
docs/.readthedocs.yaml Normal file
View File

@ -0,0 +1,35 @@
# Read the Docs configuration file for Sphinx projects
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.8"
# You can also specify other tool versions:
# nodejs: "20"
# rust: "1.70"
# golang: "1.20"
# Build documentation in the "docs/" directory with Sphinx
sphinx:
configuration: docs/source/conf.py
# You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs
# builder: "dirhtml"
# Fail on all warnings to avoid broken references
# fail_on_warning: true
# Optionally build your docs in additional formats such as PDF and ePub
# formats:
# - pdf
# - epub
# Optional but recommended, declare the Python requirements required
# to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- requirements: docs/requirements.txt

83
docs/README_zh.md Normal file
View File

@ -0,0 +1,83 @@
<p align="center">
<img width="18%" align="center" src="https://raw.githubusercontent.com/zhiyiYo/PyQt-Fluent-Widgets/master/docs/source/_static/logo.png" alt="logo">
</p>
<h1 align="center">
PySide6-Fluent-Widgets
</h1>
<p align="center">
基于 PySide6 的 Fluent Design 风格组件库
</p>
<div align="center">
[![Version](https://img.shields.io/pypi/v/pyside6-fluent-widgets?color=%2334D058&label=Version)](https://pypi.org/project/PyQt-Fluent-Widgets)
[![Download](https://static.pepy.tech/personalized-badge/pyside6-fluent-widgets?period=total&units=international_system&left_color=grey&right_color=brightgreen&left_text=Downloads)]()
[![GPLv3](https://img.shields.io/badge/License-GPLv3-blue?color=#4ec820)](LICENSE)
[![Platform Win32 | Linux | macOS](https://img.shields.io/badge/Platform-Win32%20|%20Linux%20|%20macOS-blue?color=#4ec820)]()
</div>
<p align="center">
<a href="../README.md">English</a> | 简体中文 | <a href="https://qfluentwidgets.com/">官网</a>
</p>
![Interface](https://raw.githubusercontent.com/zhiyiYo/PyQt-Fluent-Widgets/master/docs/source/_static/Interface.jpg)
## 安装📥
安装轻量版 (亚克力组件不可用)
```shell
pip install PySide6-Fluent-Widgets -i https://pypi.org/simple/
```
安装完整版:
```shell
pip install "PySide6-Fluent-Widgets[full]" -i https://pypi.org/simple/
```
[商用高级版](https://qfluentwidgets.com/zh/pages/pro) 组件库包含更多组件,可从 [发行页面](https://github.com/zhiyiYo/PyQt-Fluent-Widgets/releases) 下载体验编译好的示例程序 `PyQt-Fluent-Widgets-Pro-Gallery.zip`
C++ QFluentWidgets 组件库非开源,可从 [发行页面](https://github.com/zhiyiYo/PyQt-Fluent-Widgets/releases) 下载体验编译好的示例程序 `C++_QFluentWidgets.zip`,价格见 [官网](https://qfluentwidgets.com/zh/price)。
> [!Warning]
> 请勿同时安装 PyQt-Fluent-Widgets、PyQt6-Fluent-Widgets、PySide2-Fluent-Widgets 和 PySide6-Fluent-Widgets因为他们的包名都是 `qfluentwidgets`
## 运行示例▶️
使用 pip 安装好 PySide6-Fluent-Widgets 包并下载好此仓库的代码之后,就可以运行 examples 目录下的任意示例程序,比如:
```shell
cd examples/gallery
python demo.py
```
如果遇到 `ImportError: cannot import name 'XXX' from 'qfluentwidgets'`,这表明安装的包版本过低。可以按照上面的安装指令将 pypi 源替换为 https://pypi.org/simple 并重新安装.
## 在线文档📕
想要了解 PyQt-Fluent-Widgets 的正确使用姿势?请仔细阅读 [帮助文档](https://qfluentwidgets.com/zh/) 👈
## 许可证📄
PySide6-Fluent-Widgets 使用双许可证。非商业用途使用 [GPLv3](../LICENSE) 许可证进行授权,商用请购买 [商用许可证](https://qfluentwidgets.com/zh/price) 以获得商用授权。
组件库受软件著作权保护软著登字第12532763号任何盗用、破解组件库或未经授权的商业使用均被视为侵权行为。
Copyright © 2021 by zhiyiYo.
## Fluent Client🚩
[Fluent Client](https://qfluentwidgets.com/zh/pages/designer) 集成了设计师插件和脚手架功能,支持在 Designer 中直接拖拽使用 QFluentWidgets 的组件,所见即所得,让现代化界面搭建如丝般顺滑!可在 [淘宝](https://item.taobao.com/item.htm?ft=t&id=767961666600) 购买使用 Fluent Client。
![Fluent Designer](https://img.fastmirror.net/s/2024/02/18/65d22363d4a73.jpg)
## 另见👀
下面是一些基于 PyQt-Fluent-Widgets 的项目:
* [**zhiyiYo/Fluent-M3U8**: 美观易用的跨平台 m3u8 下载器](https://fluent-m3u8.org)
* [**zhiyiYo/Groove**: 基于 PyQt5 的跨平台音乐播放器](https://github.com/zhiyiYo/Groove)
* [**zhiyiYo/Alpha-Gobang-Zero**: 基于强化学习的五子棋机器人](https://github.com/zhiyiYo/Alpha-Gobang-Zero)
## 参考
* [**Windows design**: Design guidelines and toolkits for creating native app experiences](https://learn.microsoft.com/zh-cn/windows/apps/design/)
* [**Microsoft/WinUI-Gallery**: An app demonstrates the controls available in WinUI and the Fluent Design System](https://github.com/microsoft/WinUI-Gallery)

View File

@ -0,0 +1,59 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2021, zhiyiYo
# This file is distributed under the same license as the PyQt-Fluent-Widgets
# package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2024.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PyQt-Fluent-Widgets \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-02-14 16:27+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: zh_CN\n"
"Language-Team: zh_CN <LL@li.org>\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.11.0\n"
#: ../../source/autoapi/qfluentwidgets/common/screen/index.rst:2
#: 5cbc41558be84815afd78c68d42f57f1
msgid "screen"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/common/screen/index.rst:8
#: cdfd877627da44a3aed7890115f1f7f5
msgid "Module Contents"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/common/screen/index.rst:19:<autosummary>:1
#: b58daf2b841b4f67aef498b4ffdac276
msgid ""
":py:obj:`getCurrentScreen "
"<qfluentwidgets.common.screen.getCurrentScreen>`\\ \\(\\)"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/common/screen/index.rst:22
#: ../../source/autoapi/qfluentwidgets/common/screen/index.rst:19:<autosummary>:1
#: 537950fc0a7e485ca72a24c85031621a c96fe63ba32d42f5b7b310960aab68f6
msgid "get current screen"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/common/screen/index.rst:19:<autosummary>:1
#: 642ab5a36d3b4b67aa2e1c1caf37dc1e
msgid ""
":py:obj:`getCurrentScreenGeometry "
"<qfluentwidgets.common.screen.getCurrentScreenGeometry>`\\ "
"\\(\\[avaliable\\]\\)"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/common/screen/index.rst:27
#: ../../source/autoapi/qfluentwidgets/common/screen/index.rst:19:<autosummary>:1
#: 766a955c0bdb4b369bdc0515447bd04e a9fd07381e8c4d4d96f70a5c2b1284da
msgid "get current screen geometry"
msgstr ""

View File

@ -0,0 +1,55 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2021, zhiyiYo
# This file is distributed under the same license as the PyQt-Fluent-Widgets
# package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2023.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PyQt-Fluent-Widgets \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-01 17:56+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: zh_CN\n"
"Language-Team: zh_CN <LL@li.org>\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.11.0\n"
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_picker/index.rst:2
#: 2c7a4eb494b047b7b2d1d878a5f8922d
msgid "calendar_picker"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_picker/index.rst:8
#: a61263caff454426a5c4ef23aaba94c6
msgid "Module Contents"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_picker/index.rst:18:<autosummary>:1
#: 73ca36eaf2804370a7b3929299e0cd0a
msgid ""
":py:obj:`CalendarPicker "
"<qfluentwidgets.components.date_time.calendar_picker.CalendarPicker>`\\"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_picker/index.rst:23
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_picker/index.rst:18:<autosummary>:1
#: 9f8c9513514745018e2949f4c9b6c9af abb5f98b738344ab90bb1e0a3b89e2b5
msgid "Calendar picker"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_picker/index.rst:21
#: be59c5e217d34b2eb5088f7d3db90341
msgid "Bases: :py:obj:`PyQt5.QtWidgets.QPushButton`"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_picker/index.rst:31
#: 67e9fa08ecb8439dbd377d39c5b187a1
msgid "set the selected date"
msgstr ""

View File

@ -0,0 +1,259 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2021, zhiyiYo
# This file is distributed under the same license as the PyQt-Fluent-Widgets
# package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2023.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PyQt-Fluent-Widgets \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-01 17:56+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: zh_CN\n"
"Language-Team: zh_CN <LL@li.org>\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.11.0\n"
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:2
#: 2c988020c6f641cf92836e19597b1272
msgid "calendar_view"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:8
#: b1e547b688a147e6bcb8cdb9b6ebbf29
msgid "Module Contents"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: bdd754a4d7bd4f36a49c2d226646254a
msgid ""
":py:obj:`ScrollButton "
"<qfluentwidgets.components.date_time.calendar_view.ScrollButton>`\\"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:35
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: a2d093ab1b4245b08128b7412b6c7ae1 b0d6cdd4877b4241939a36a126e6803d
msgid "Scroll button"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 55eeb982b4f845d085eaa50d34a514e2
msgid ""
":py:obj:`ScrollItemDelegate "
"<qfluentwidgets.components.date_time.calendar_view.ScrollItemDelegate>`\\"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 0e7a0115ef4546eabf7dbd91ce6afb95
msgid ""
":py:obj:`YearScrollItemDelegate "
"<qfluentwidgets.components.date_time.calendar_view.YearScrollItemDelegate>`\\"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:65
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: d2509d80d136456c9871969bedd049e0 f266246c911744408c5821ec92897cf3
msgid "Year scroll item delegate"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: e76738aad06546ffa3e41fbc96f750e0
msgid ""
":py:obj:`DayScrollItemDelegate "
"<qfluentwidgets.components.date_time.calendar_view.DayScrollItemDelegate>`\\"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:72
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 44f23ec1710e4743b26aabaf8d728d2c cdbc6abca6954d29afa87622c6696187
msgid "Day scroll item delegate"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: d09859a212e043bf9d314f12cfd5409c
msgid ""
":py:obj:`ScrollViewBase "
"<qfluentwidgets.components.date_time.calendar_view.ScrollViewBase>`\\"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:79
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 5da98688b4f34612972789c7fcd67b41 d32737ac0bd34920bbe0f13afb1e4da3
msgid "Scroll view base class"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 58dea08db4b44a6190efd510d2f0609f
msgid ""
":py:obj:`CalendarViewBase "
"<qfluentwidgets.components.date_time.calendar_view.CalendarViewBase>`\\"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:116
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 20f6bbe661d94d29ac72f7a0f0b43941 d9155cc883074a51a6c52e048a5c5020
msgid "Calendar view base class"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: d7230c4edbfc43208ba89f212702cccf
msgid ""
":py:obj:`YearScrollView "
"<qfluentwidgets.components.date_time.calendar_view.YearScrollView>`\\"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:144
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 1322c5c3909947f8ab006d1c61a002e6 acd53b1830d64ff5a16063d9ca72aff3
msgid "Year scroll view"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: dfd726d11b5042acb88bd593addf276f
msgid ""
":py:obj:`YearCalendarView "
"<qfluentwidgets.components.date_time.calendar_view.YearCalendarView>`\\"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:157
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 679c78e45ca14a2cbbd1ad9d7a5c88e7 a2c0afb24b22417ab86f443186ee8af8
msgid "Year calendar view"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 98668e45068e45188a784862e878ffba
msgid ""
":py:obj:`MonthScrollView "
"<qfluentwidgets.components.date_time.calendar_view.MonthScrollView>`\\"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:164
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 08b7e51e6a8540d0a58d4446cab0865f c1deeb35b77643309bde47d0b2377af5
msgid "Month scroll view"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 116e14b6686b4d65a84e848974987b53
msgid ""
":py:obj:`MonthCalendarView "
"<qfluentwidgets.components.date_time.calendar_view.MonthCalendarView>`\\"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:177
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: b5ba0d7f3764434d8798be09fb6e2cf2 cddbcdf66ee745d4ad203141f4d1ebe6
msgid "Month calendar view"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: d4c5de70160640f7ae248cbdb71451e5
msgid ""
":py:obj:`DayScrollView "
"<qfluentwidgets.components.date_time.calendar_view.DayScrollView>`\\"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:187
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 88bef63906e64b5793c2d49efffc6e8c b320d066f1ff465db2f865d3506139e0
msgid "Day scroll view"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 3673635cfc6d4e188c04900e134f0626
msgid ""
":py:obj:`DayCalendarView "
"<qfluentwidgets.components.date_time.calendar_view.DayCalendarView>`\\"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:212
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 1574d319bf1c49c181d119ae5abfe608 26bcea1b968f4b9e867d0bef87b4dca9
msgid "Day calendar view"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 3c458b4753514a73bc8d3c72d5dc4358
msgid ""
":py:obj:`CalendarView "
"<qfluentwidgets.components.date_time.calendar_view.CalendarView>`\\"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:225
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:30:<autosummary>:1
#: 72229873b28d4bbba6daf82c32ac2110 e35f8e474e5748b6bca3c8198b17a393
msgid "Calendar view"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:33
#: 866f6ea5fea445b9849da45bbbddfcd4
msgid ""
"Bases: "
":py:obj:`qfluentwidgets.components.widgets.button.TransparentToolButton`"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:43
#: aae780aadcb64f04b86a3dd7dbb68305
msgid "Bases: :py:obj:`PyQt5.QtWidgets.QStyledItemDelegate`"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:63
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:70
#: 572f849630224896a8b0b47ec88e09ea efd01b2bf1ff46008c461132eb52d059
msgid "Bases: :py:obj:`ScrollItemDelegate`"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:77
#: 316cd424f3554e9d80d16f9fbf8be3c1
msgid "Bases: :py:obj:`PyQt5.QtWidgets.QListWidget`"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:114
#: f5a470f5714246b89a580bbae72f71e4
msgid "Bases: :py:obj:`PyQt5.QtWidgets.QFrame`"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:142
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:162
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:185
#: 029bbbe0e3274575a34395cccc15e45f e66a198e5daf4c7ababf9644fd0e0824
#: e8d7e62817804d93853558edbefb9dd7
msgid "Bases: :py:obj:`ScrollViewBase`"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:155
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:175
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:210
#: 2acbf87d60c44a9db9d35db9f35db55b 8cfee58132b44720bee3ba64d8959b52
#: f3d094c7231c44c1aa7bf592b633953c
msgid "Bases: :py:obj:`CalendarViewBase`"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:223
#: fcb82323d5dd467a8e956ea58b486e14
msgid "Bases: :py:obj:`PyQt5.QtWidgets.QWidget`"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:233
#: f729fa3364464cdd853c5a9ef6231789
msgid "add shadow to dialog"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:238
#: 1b9cacd39a1b4df1a3dbfe4a60f4b47e
msgid "set the selected date"
msgstr ""
#: ../../source/autoapi/qfluentwidgets/components/date_time/calendar_view/index.rst:243
#: b7767d3d96564500af8f9794b7ab51d2
msgid "show calendar view"
msgstr ""

35
docs/make.bat Normal file
View File

@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
if "%1" == "" goto help
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

16
docs/requirements.txt Normal file
View File

@ -0,0 +1,16 @@
PyQt5>=5.15.0
PyQt5-Frameless-Window
darkdetect
colorthief
scipy
pillow
sphinx-markdown-tables==0.0.17
sphinx-intl
furo
sphinx-autoapi
sphinx-copybutton
sphinx_design
urllib3<2.0.0
mock==1.0.1
commonmark==0.9.1
recommonmark==0.5.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -0,0 +1,35 @@
function buildFancybox() {
$(".article-container section img").unwrap();
let images = Array.from($('.article-container section img'));
if (!images.length) return;
images.forEach(el => {
const src = $(el).attr("src");
const alt = $(el).attr("alt") || '';
$(el).after(`<a href="${src}" data-download-src="${src}" data-caption="${alt}" data-fancybox="gallery"><img src="${src}"/></a>`);
$(el).remove();
});
window.Fancybox.bind('[data-fancybox="gallery"]', {
Toolbar: {
display: [
"counter",
"zoom",
"slideshow",
"fullscreen",
"download",
"thumbs",
"close",
],
},
Image: {
zoom: false,
},
showClass: "fancybox-zoomIn",
hideClass: "fancybox-zoomOut",
});
}
buildFancybox();

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

53
docs/source/conf.py Normal file
View File

@ -0,0 +1,53 @@
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = 'PyQt-Fluent-Widgets'
copyright = '2023, zhiyiYo'
author = 'zhiyiYo'
release = 'v0.4.0'
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
source_parsers = {
'.md': 'recommonmark.parser.CommonMarkParser',
}
source_suffix = ['.rst', '.md']
extensions = ['recommonmark', 'sphinx_markdown_tables']
templates_path = ['_templates']
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = 'sphinx_rtd_theme'
html_static_path = ['_static']
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
html_theme_options = {
"sidebar_hide_name": False,
}
html_show_sourcelink = True
html_title = "PyQt-Fluent-Widgets"
html_favicon = "_static/logo.png"
html_css_files = [
'css/fancybox.css',
'css/custom.css',
]
html_js_files = [
'js/fancybox.umd.js',
'js/fancybox.js',
]
copybutton_prompt_text = r">>> |\.\.\. |\$ |In \[\d*\]: | {2,5}\.\.\.: | {5,8}: "
copybutton_prompt_is_regexp = True

69
docs/source/designer.rst Normal file
View File

@ -0,0 +1,69 @@
Designer
--------
In Qt Designer, there are two ways to use PyQt-Fluent-Widgets.
Promoting widget
^^^^^^^^^^^^^^^^
Right click on a widget, select the ``Promote to ...`` of context menu.
Promoting a widget indicates that it should be replaced with the specified subclass, in our case the ``qfluentwidgets.PushButton``.
.. image:: ./_static/promote_context.jpg
:target: ./_static/promote_context.jpg
:alt:
You will be presented with a dialog to specify the custom widget class the placeholder widget will become.
The header file is the name of the Python module used to import the class, which is ``qfluentwidgets``. Specify ``PushButton`` as the class name of the widget to replace it with.
.. image:: ./_static/promote_dialog.jpg
:target: ./_static/promote_dialog.jpg
:alt:
Well, the widget is now promoted to fluent push button. But you won't be able to see any changes within Qt Designer. Save the window as ``mainwindow.ui`` and compile it to python code, you will see that the ``PushButton`` is imported from ``qfluentwidgets`` package.
Using plugin
^^^^^^^^^^^^
1. create a virtual environment, ``conda`` is the recommended way.
2. Activate virtual environment and run the following code in shell:
.. code-block:: sh
pip install PyQt-Fluent-Widget
pip install pyqt5-tools
3. Download the full code from `PyQt-Fluent-Widgets Repo <https://github.com/zhiyiYo/PyQt-Fluent-Widgets>`_.
4. Run ``python ./tools/designer.py`` to launch Qt Designer (You must use this way to launch Qt Designer).
If everything goes smoothly, you will see all PyQt-Fluent-Widgets components in the sidebar of Qt Designer.
If the startup fails or the components of PyQt-Fluent-Widgets cannot be seen, the solution can be found in `#196 <https://github.com/zhiyiYo/PyQt-Fluent-Widgets/issues/196>`_.
.. image:: ./_static/Designer_plugin.jpg
:target: ./_static/Designer_plugin.jpg
:alt:
The plugin for PySide6 is unstable and may not start QtDesigner successfully. It is recommended to use QtDesigner of PyQt5/6 to generate ui files.
.. note:: PyQt5 must upgrade PyQt5-Frameless-Window to 0.2.7 in order to use the plugin, while PySide6 and PyQt6 do not need to upgrading to frameless packages. PySide2 does not support plugins, but you can use PyQt5's QtDesigner to generate ui files and then compile them into py files using uic.
Complex example
^^^^^^^^^^^^^^^
Here is an example that uses a side navigation bar to implement multiple sub-interfaces window.
.. raw:: html
<div style="position: relative; padding: 30% 45%;">
<iframe style="position: absolute; width: 100%; height: 100%; left: 0; top: 0;" src="https://player.bilibili.com/player.html?cid=1193201502&aid=530806716&page=1&as_wide=1&high_quality=1&danmaku=0" frameborder="no" scrolling="no" allowfullscreen="true"></iframe>
</div>

62
docs/source/gallery.md Normal file
View File

@ -0,0 +1,62 @@
## Gallery
### Basic input
#### Button
![](./_static/gallery/button.gif)
#### Check Box
![](./_static/gallery/check_box.gif)
#### Combo Box
![](./_static/gallery/combo_box.gif)
#### Radio Button
![](./_static/gallery/radio_button.gif)
#### Switch Button
![](./_static/gallery/switch_button.gif)
#### Slider
![](./_static/gallery/slider.gif)
#### Hollow Handle Slider
![](./_static/gallery/hollow_handle_slider.gif)
### Dialogs
#### Color Dialog
![](./_static/gallery/color_dialog.gif)
#### Dialog
![](./_static/gallery/dialog.gif)
#### Message Box
![](./_static/gallery/message_box.gif)
#### Win10 Style Message Dialog
![](./_static/gallery/dialog_with_mask.gif)
#### Folder List Dialog
![](./_static/gallery/folder_list_dialog.gif)
### Menus
![](./_static/gallery/round_menu.gif)
### Flow Layout
![](./_static/gallery/flow_layout.gif)
### Navigation
![](./_static/gallery/navigation.gif)
### Status & info
#### State Tool Tip
![](./_static/gallery/state_tool_tip.gif)
#### Tool Tip
![](./_static/gallery/tool_tip.gif)
### Material
#### Acrylic Label
<img width="60%" src="./_static/gallery/acrylic_label.png"/>

19
docs/source/icon.md Normal file
View File

@ -0,0 +1,19 @@
## Icon
Many widgets need icons, if you want PyQt-Fluent-Widgets change your icons automatically when the theme changes, then you can inherit `FluentIconBase` and overide `path()` method. Here is an example:
```python
from enum import Enum
from qfluentwidgets import getIconColor, Theme, FluentIconBase
class MyFluentIcon(FluentIconBase, Enum):
""" Custom icons """
ADD = "Add"
CUT = "Cut"
COPY = "Copy"
def path(self, theme=Theme.AUTO):
return f':/icons/{self.value}_{getIconColor(theme)}.svg'
```

55
docs/source/index.rst Normal file
View File

@ -0,0 +1,55 @@
.. PyQt-Fluent-Widgets documentation master file, created by
sphinx-quickstart on Tue Jan 17 15:31:54 2023.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
.. raw:: html
<p align="center">
<img width="18%" align="center" src="./_static/logo.png" alt="logo">
</p>
<h1 align="center">
PyQt-Fluent-Widgets
</h1>
<hr/>
<p align="center">
A fluent design widgets library based on PyQt5
</p>
<p align="center">
<a style="text-decoration:none">
<img src="https://img.shields.io/badge/Platform-Win32%20|%20Linux%20|%20macOS-blue?color=#4ec820" alt="Platform Win32 | Linux | macOS"/>
</a>
<a style="text-decoration:none">
<img src="https://static.pepy.tech/personalized-badge/pyqt-fluent-widgets?period=total&units=international_system&left_color=grey&right_color=brightgreen&left_text=Downloads" alt="Download"/>
</a>
<a style="text-decoration:none">
<img src="https://img.shields.io/badge/License-LGPLv3-blue?color=#4ec820" alt="LGPLv3"/>
</a>
</p>
<p align="center">
<img src="./_static/Interface.jpg" alt="Interface">
</p>
Welcome to PyQt-Fluent-Widgets's document!
===============================================
This document will show you all the features of PyQt-Fluent-Widgets and the best practice of it.
.. toctree::
:maxdepth: 2
:caption: Contents
quick-start
settings
theme
navigation
icon
gallery
see-also

104
docs/source/navigation.md Normal file
View File

@ -0,0 +1,104 @@
## Navigation
### Structure
PyQt Fluent Widgets provides a side navigation class `NavigationInterface`. You can use it with `QStackWidget` and put them in `QHBoxLayout`. Examples are available at https://github.com/zhiyiYo/PyQt-Fluent-Widgets/tree/master/examples/navigation2.
![](_static/NavigationInterface_Structure.jpg)
`NavigationInterface` contains `NavigationPanel` which is used to place navigation menu items. All navigation menu items should inherit from `NavigationWidget` and you can add them to the panel by calling `NavigationInterface.addWidget()` or `NavigationPanel.addWidget()`. PyQt-Fluent-Widgets implements subclass `NavigationPushButton` and provides a convenient method `NavigationInterface.addItem()` to add it to the panel.
If you want to customize a navigation menu item, you should inherit the `NavigationWidget` and rewrite its `paintEvent()` and `setCompacted()`(optional). Here an example shows how to create an avatar item.
```python
from qfluentwidgets import NavigationWidget
class AvatarWidget(NavigationWidget):
""" Avatar widget """
def __init__(self, parent=None):
super().__init__(isSelectable=False, parent=parent)
self.avatar = QImage('resource/shoko.png').scaled(
24, 24, Qt.KeepAspectRatio, Qt.SmoothTransformation)
def paintEvent(self, e):
painter = QPainter(self)
painter.setRenderHints(
QPainter.SmoothPixmapTransform | QPainter.Antialiasing)
painter.setPen(Qt.NoPen)
if self.isPressed:
painter.setOpacity(0.7)
# draw background
if self.isEnter:
c = 255 if isDarkTheme() else 0
painter.setBrush(QColor(c, c, c, 10))
painter.drawRoundedRect(self.rect(), 5, 5)
# draw avatar
painter.setBrush(QBrush(self.avatar))
painter.translate(8, 6)
painter.drawEllipse(0, 0, 24, 24)
painter.translate(-8, -6)
if not self.isCompacted:
painter.setPen(Qt.white if isDarkTheme() else Qt.black)
font = QFont('Segoe UI')
font.setPixelSize(14)
painter.setFont(font)
painter.drawText(QRect(44, 0, 255, 36), Qt.AlignVCenter, 'zhiyiYo')
```
Now let's take a look at the parameters required for the `addWidget()` methed:
```python
def addWidget(
self,
routeKey: str,
widget: NavigationWidget,
onClick=None,
position=NavigationItemPosition.TOP,
tooltip: str = None,
parentRouteKey: str = None
)
```
As you can see, this method requires four parameters:
* `routeKey`: A unique name for the `widget` to be added. You can consider the sub interface in the `QStackWidget` as a web page, and the `routeKey` is the url of the web page. When you switch between sub interfaces, `NavigationPanel` will add a `routeKey` to the navigation history. When you click the return button, the `routeKey` at the top of the navigation history will pop up. If there are other `routeKeys` in the history at this time, PyQt-Fluent-Widgets will switch to the corresponding sub interface corresponding to current top `routeKey`. Otherwise, it will switch to the sub interface corresponding to `defaultRouteKey`, so you should call `NavigationInterface.setDefaultRouteKey()` before running app.
* `widget`: The widget to be added to panel.
* `onClick`: Slot function connected to the widget's `clicked` signal. If you want to switch sub interfaces when clicking `widget`t, it is recommended to write this slot function as `lambda: self.stackWidget.setCurrentWidget(self.xxxInterface) `.
* `position`: Where to add the `widget` to the panel. The following values are available:
* `NavigationItemPosition.TOP`: add `widget` to the top layout of panel.
* `NavigationItemPosition.SCROLL`: add `widget` to the scroll layout of panel. You can scroll the widgets in scroll layout When there are too many menu items.
* `NavigationItemPosition.BOTTOM`: add `widget` to the bottom layout of panel.
* `tooltip`: The tooltip of menu item.
* `parentRouteKey`: The route key of parent menu item, the widget of parent item must be the instance of `NavigationTreeWidgetBase`
### Display mode
The navigation panel has four display modes:
* `NavigationDisplayMode.EXPAND`: An expanded left pane on large window widths (1008px or greater).
![](_static/NavigationInterface_Expanded.jpg)
* `NavigationDisplayMode.COMPACT`: A left, icon-only, nav panel on medium window widths (1007px or less).
![](_static/NavigationInterface_Compact.jpg)
* `NavigationDisplayMode.MENU`: An expanded left menu (1007px or less).
![](_static/NavigationInterface_Menu.jpg)
* `NavigationDisplayMode.MINIMAL`: Only a menu button on small window widths (you should add and manage the menu button to main window by yourself like [navigation3](https://github.com/zhiyiYo/PyQt-Fluent-Widgets/tree/master/examples/navigation3) does).
If you call `NavigationInterface.setExpandWidth()`, the large window width (1008px) will change accordingly.
### More examples
Here is an another style of navigation interface, and its corresponding example program is available at https://github.com/zhiyiYo/PyQt-Fluent-Widgets/tree/master/examples/navigation.
![](_static/NavigationInterfacee.jpg)
Minimal display mode navigation interface is available at [navigation3](https://github.com/zhiyiYo/PyQt-Fluent-Widgets/tree/master/examples/navigation3).
![](_static/NavigationInterface_Minimal.jpg)

View File

@ -0,0 +1,34 @@
Quick start
-----------
Install
~~~~~~~
To install lite version (``AcrylicLabel`` is not available) use pip:
.. code:: shell
pip install PyQt-Fluent-Widgets -i https://pypi.org/simple/
Or install full-featured version use pip:
.. code:: shell
pip install "PyQt-Fluent-Widgets[full]" -i https://pypi.org/simple/
If you are using PySide2, PySide6 or PyQt6, you can download the code in `PySide2 <https://github.com/zhiyiYo/PyQt-Fluent-Widgets/tree/PySide2>`__, `PySide6 <https://github.com/zhiyiYo/PyQt-Fluent-Widgets/tree/PySide6>`__ or `PyQt6 <https://github.com/zhiyiYo/PyQt-Fluent-Widgets/tree/PyQt6>`__ branch.
.. warning:: Don't install PyQt-Fluent-Widgets, PyQt6-Fluent-Widgets, PySide2-Fluent-Widgets and PySide6-Fluent-Widgets at the same time, because their package names are all ``qfluentwidgets``.
Run example
~~~~~~~~~~~
After installing PyQt-Fluent-Widgets package using pip, you can run any
demo in the examples directory, for example:
.. code:: python
cd examples/gallery
python demo.py
.. note:: If you encounter ``ImportError: cannot import name 'XXX' from 'qfluentwidgets'``, it indicates that the package version you installed is too low. You can replace the mirror source with https://pypi.org/simple and reinstall again.

16
docs/source/see-also.md Normal file
View File

@ -0,0 +1,16 @@
## See also
Here are some projects that use PyQt-Fluent-Widgets:
- [**zhiyiYo/QMaterialWidgets**: A material design widgets library based on PySide](https://github.com/zhiyiYo/QMaterialWidgets)
![](https://raw.githubusercontent.com/zhiyiYo/QMaterialWidgets/master/docs/source/_static/Interface.jpg)
<br>
- [**zhiyiYo/Groove**: A cross-platform music player based on PyQt5](https://github.com/zhiyiYo/Groove)
![](./_static/Groove音乐.jpg)
<br>
- [**zhiyiYo/Alpha-Gobang-Zero**: A gobang robot based on reinforcement learning](https://github.com/zhiyiYo/Alpha-Gobang-Zero)
![](./_static/Alpha-Gobang-Zero.jpg)

77
docs/source/settings.md Normal file
View File

@ -0,0 +1,77 @@
## Settings
PyQt-Fluent-Widgets presents each configuration item as a `SettingCard` on the interface. The behavior of user on the `SettingCard` will change the value of the configuration item, and PyQt-Fluent-Widgets will update the configuration item to the json configuration file automatically.
### Config
PyQt-Fluent-Widgets uses the `ConfigItem` class to represent a configuration item and uses the `QConfig` class to read and write the value of `ConfigItem`. The `QConfig` class will automatically update the configuration file when the value of the `ConfigItem` changes.
Since the value in config file may be manually modified by the user to an invalid value, PyQt-Fluent-Widgets use `ConfigValidator` and its subclass to verify and correct the config value.
Json files only support string, boolean value, list and dict, for enumeration classes or `QColor`, we can't use `json.dump()` to write them directly into a json file, so PyQt-Fluent-Widgets provides `ConfigSerializer` and its subclass to serialize and deserialize config item from config file. For example, you can use `ColorSerializer` to serialize config items with `QColor` value type.
`ConfigItem` has the following attributes:
| Attribute | Type | Description |
| :----------: | :----------------: | ------------------------------------------------------------ |
| `group` | `str` | The group to which the config item belongs |
| `name` | `str` | Name of config item |
| `default` | `Any` | The default value of config item, it will be used when the value in the config file is illegal |
| `validator` | `ConfigValidator` | Config validator |
| `serializer` | `ConfigSerializer` | Config serializer |
| `restart` | `bool` | Whether to restart the application after updating value |
You should add config items to the class attribute of `QConfig` subclasss, then use `qconfig.load()` to load config file, for example:
```python
class MvQuality(Enum):
""" MV quality enumeration class """
FULL_HD = "Full HD"
HD = "HD"
SD = "SD"
LD = "LD"
@staticmethod
def values():
return [q.value for q in MvQuality]
class Config(QConfig):
""" Config of application """
# main window
enableAcrylic = ConfigItem("MainWindow", "EnableAcrylic", False, BoolValidator())
playBarColor = ColorConfigItem("MainWindow", "PlayBarColor", "#225C7F")
themeMode = OptionsConfigItem("MainWindow", "ThemeMode", "Light", OptionsValidator(["Light", "Dark", "Auto"]), restart=True)
recentPlaysNumber = RangeConfigItem("MainWindow", "RecentPlayNumbers", 300, RangeValidator(10, 300))
# online
onlineMvQuality = OptionsConfigItem("Online", "MvQuality", MvQuality.FULL_HD, OptionsValidator(MvQuality), EnumSerializer(MvQuality))
# create config object and initialize it
cfg = Config()
qconfig.load('config/config.json', cfg)
```
### Setting card
PyQt-Fluent-Widgets provides many kinds of setting card:
| Class | Description |
| :----------------------: | ------------------------------------------------------------ |
| `HyperlinkCard` | Setting card with a hyper link |
| `ColorSettingCard` | Setting card with a color picker |
| `CustomColorSettingCard` | Setting card with a button to choose color |
| `ComboBoxSettingCard` | Setting card with a combo box |
| `RangeSettingCard` | Setting card with a slider |
| `PushSettingCard` | Setting card with a naive push button |
| `PrimaryPushSettingCard` | Setting card with a push button highlighted in the background |
| `SwitchSettingCard` | Setting card with a switch button |
| `OptionsSettingCard` | Setting card with a group of radio buttons |
| `FolderListSettingCard` | Setting card for showing and managing folder list |
You can use `SettingCardGroup.addSettingCard()` to add a setting card to the same group, and `SettingCardGroup` will adjust its layout automatically based on the height of setting cards.
For the usage of these components, see [settings_ interface.py](https://github.com/zhiyiYo/PyQt-Fluent-Widgets/blob/master/examples/settings/setting_interface.py).

44
docs/source/theme.md Normal file
View File

@ -0,0 +1,44 @@
## Theme
### Theme mode
You can use the `setTheme()` method to switch the light/dark theme of PyQt-Fluent-Widgets. The parameter of `setTheme()` accepts the following three values:
* `Theme.LIGHT`: Light theme
* `Theme.DARK`: Dark theme
* `Theme.AUTO`: Follow system theme. If the system theme cannot be detected, the light theme will be used.
When the theme changes, the config instance managed by `qconfig` (i.e., the config object passed in using the `qconfig.load()` method) will emit the `themeChanged` signal.
If you want to automatically switch the interface style when the theme changes, you can inherit `StyleSheetBase` and override the `path()` method. Suppose you have a `MainWindow` class and its qss file paths are `app/resource/qss/light/main_window.qss` and `app/resource/qss/dark/main_window.qss`, the code can be written like this:
```python
from enum import Enum
from qfluentwidgets import StyleSheetBase, Theme, isDarkTheme, qconfig
class StyleSheet(StyleSheetBase, Enum):
""" Style sheet """
MAIN_WINDOW = "main_window"
def path(self, theme=Theme.AUTO):
theme = qconfig.theme if theme == Theme.AUTO else theme
return f"app/resource/qss/{theme.value.lower()}/{self.value}.qss"
class MainWindow(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent)
# apply style sheet to main window
StyleSheet.MAIN_WINDOW.apply(self)
```
### Theme color
You can use `setThemeColor()` method to change the theme color of PyQt-Fluent-Widgets. This method accepts the following three types of parameters:
* `QColor`
* `Qt.GlobalColor`
* `str`: Hex color strings or color names, such as `#0065d5` or `red`.
When the theme color changes, `qconfig` will emit the `themeColorChanged` signal.