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

71
app/common/config.py Normal file
View File

@ -0,0 +1,71 @@
# coding:utf-8
import sys
from enum import Enum
from PySide6.QtCore import QLocale
from qfluentwidgets import (qconfig, QConfig, ConfigItem, OptionsConfigItem, BoolValidator,
OptionsValidator, RangeConfigItem, RangeValidator,
FolderListValidator, Theme, FolderValidator, ConfigSerializer, __version__)
class Language(Enum):
""" Language enumeration """
CHINESE_SIMPLIFIED = QLocale(QLocale.Chinese, QLocale.China)
CHINESE_TRADITIONAL = QLocale(QLocale.Chinese, QLocale.HongKong)
ENGLISH = QLocale(QLocale.English)
AUTO = QLocale()
class LanguageSerializer(ConfigSerializer):
""" Language serializer """
def serialize(self, language):
return language.value.name() if language != Language.AUTO else "Auto"
def deserialize(self, value: str):
return Language(QLocale(value)) if value != "Auto" else Language.AUTO
def isWin11():
return sys.platform == 'win32' and sys.getwindowsversion().build >= 22000
class Config(QConfig):
""" Config of application """
# folders
musicFolders = ConfigItem(
"Folders", "LocalMusic", [], FolderListValidator())
downloadFolder = ConfigItem(
"Folders", "Download", "app/download", FolderValidator())
# main window
micaEnabled = ConfigItem("MainWindow", "MicaEnabled", isWin11(), BoolValidator())
dpiScale = OptionsConfigItem(
"MainWindow", "DpiScale", "Auto", OptionsValidator([1, 1.25, 1.5, 1.75, 2, "Auto"]), restart=True)
language = OptionsConfigItem(
"MainWindow", "Language", Language.AUTO, OptionsValidator(Language), LanguageSerializer(), restart=True)
# Material
blurRadius = RangeConfigItem("Material", "AcrylicBlurRadius", 15, RangeValidator(0, 40))
# software update
checkUpdateAtStartUp = ConfigItem("Update", "CheckUpdateAtStartUp", True, BoolValidator())
YEAR = 2023
AUTHOR = "zhiyiYo"
VERSION = __version__
HELP_URL = "https://qfluentwidgets.com"
REPO_URL = "https://github.com/zhiyiYo/PyQt-Fluent-Widgets"
EXAMPLE_URL = "https://github.com/zhiyiYo/PyQt-Fluent-Widgets/tree/PySide6/examples"
FEEDBACK_URL = "https://github.com/zhiyiYo/PyQt-Fluent-Widgets/issues"
RELEASE_URL = "https://github.com/zhiyiYo/PyQt-Fluent-Widgets/releases/latest"
ZH_SUPPORT_URL = "https://qfluentwidgets.com/zh/price/"
EN_SUPPORT_URL = "https://qfluentwidgets.com/price/"
cfg = Config()
cfg.themeMode.value = Theme.AUTO
qconfig.load('app/config/config.json', cfg)

16
app/common/icon.py Normal file
View File

@ -0,0 +1,16 @@
# coding: utf-8
from enum import Enum
from qfluentwidgets import FluentIconBase, getIconColor, Theme
class Icon(FluentIconBase, Enum):
GRID = "Grid"
MENU = "Menu"
TEXT = "Text"
PRICE = "Price"
EMOJI_TAB_SYMBOLS = "EmojiTabSymbols"
def path(self, theme=Theme.AUTO):
return f":/gallery/images/icons/{self.value}_{getIconColor(theme)}.svg"

260885
app/common/resource.py Normal file

File diff suppressed because it is too large Load Diff

13
app/common/signal_bus.py Normal file
View File

@ -0,0 +1,13 @@
# coding: utf-8
from PySide6.QtCore import QObject, Signal
class SignalBus(QObject):
""" Signal bus """
switchToSampleCard = Signal(str, int)
micaEnableChanged = Signal(bool)
supportSignal = Signal()
signalBus = SignalBus()

25
app/common/style_sheet.py Normal file
View File

@ -0,0 +1,25 @@
# coding: utf-8
from enum import Enum
from qfluentwidgets import StyleSheetBase, Theme, isDarkTheme, qconfig
class StyleSheet(StyleSheetBase, Enum):
""" Style sheet """
LINK_CARD = "link_card"
SAMPLE_CARD = "sample_card"
HOME_INTERFACE = "home_interface"
ICON_INTERFACE = "icon_interface"
VIEW_INTERFACE = "view_interface"
SETTING_INTERFACE = "setting_interface"
GALLERY_INTERFACE = "gallery_interface"
NAVIGATION_VIEW_INTERFACE = "navigation_view_interface"
SYSTEM_INTERFACE = "system_interface"
def path(self, theme=Theme.AUTO):
theme = qconfig.theme if theme == Theme.AUTO else theme
#D:\Downloads\PyQt-Fluent-Widgets-PySide6\app\resource\qss\dark\view_interface.qss
#return f"./app/gallery/qss/{theme.value.lower()}/{self.value}.qss"
return f"./app/resource/qss/{theme.value.lower()}/{self.value}.qss"

21
app/common/translator.py Normal file
View File

@ -0,0 +1,21 @@
# coding: utf-8
from PySide6.QtCore import QObject
class Translator(QObject):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.text = self.tr('Text')
self.view = self.tr('View')
self.menus = self.tr('Menus & toolbars')
self.icons = self.tr('Icons')
self.layout = self.tr('Layout')
self.dialogs = self.tr('Dialogs & flyouts')
self.scroll = self.tr('Scrolling')
self.material = self.tr('Material')
self.dateTime = self.tr('Date & time')
self.navigation = self.tr('Navigation')
self.basicInput = self.tr('Basic input')
self.statusInfo = self.tr('Status & info')
self.price = self.tr("Price")

73
app/common/trie.py Normal file
View File

@ -0,0 +1,73 @@
# coding: utf-8
from queue import Queue
class Trie:
""" String trie """
def __init__(self):
self.key = ''
self.value = None
self.children = [None] * 26
self.isEnd = False
def insert(self, key: str, value):
""" insert item """
key = key.lower()
node = self
for c in key:
i = ord(c) - 97
if not 0 <= i < 26:
return
if not node.children[i]:
node.children[i] = Trie()
node = node.children[i]
node.isEnd = True
node.key = key
node.value = value
def get(self, key, default=None):
""" get value of key """
node = self.searchPrefix(key)
if not (node and node.isEnd):
return default
return node.value
def searchPrefix(self, prefix):
""" search node matchs the prefix """
prefix = prefix.lower()
node = self
for c in prefix:
i = ord(c) - 97
if not (0 <= i < 26 and node.children[i]):
return None
node = node.children[i]
return node
def items(self, prefix):
""" search items match the prefix """
node = self.searchPrefix(prefix)
if not node:
return []
q = Queue()
result = []
q.put(node)
while not q.empty():
node = q.get()
if node.isEnd:
result.append((node.key, node.value))
for c in node.children:
if c:
q.put(c)
return result

View File

@ -0,0 +1,71 @@
# coding:utf-8
from PySide6.QtCore import Qt, Signal, QUrl
from PySide6.QtGui import QPixmap, QDesktopServices
from PySide6.QtWidgets import QFrame, QLabel, QVBoxLayout, QWidget, QHBoxLayout
from qfluentwidgets import IconWidget, FluentIcon, TextWrap, SingleDirectionScrollArea
from ..common.style_sheet import StyleSheet
class LinkCard(QFrame):
def __init__(self, icon, title, content, url, parent=None):
super().__init__(parent=parent)
self.url = QUrl(url)
self.setFixedSize(198, 220)
self.iconWidget = IconWidget(icon, self)
self.titleLabel = QLabel(title, self)
self.contentLabel = QLabel(TextWrap.wrap(content, 28, False)[0], self)
self.urlWidget = IconWidget(FluentIcon.LINK, self)
self.__initWidget()
def __initWidget(self):
self.setCursor(Qt.PointingHandCursor)
self.iconWidget.setFixedSize(54, 54)
self.urlWidget.setFixedSize(16, 16)
self.vBoxLayout = QVBoxLayout(self)
self.vBoxLayout.setSpacing(0)
self.vBoxLayout.setContentsMargins(24, 24, 0, 13)
self.vBoxLayout.addWidget(self.iconWidget)
self.vBoxLayout.addSpacing(16)
self.vBoxLayout.addWidget(self.titleLabel)
self.vBoxLayout.addSpacing(8)
self.vBoxLayout.addWidget(self.contentLabel)
self.vBoxLayout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
self.urlWidget.move(170, 192)
self.titleLabel.setObjectName('titleLabel')
self.contentLabel.setObjectName('contentLabel')
def mouseReleaseEvent(self, e):
super().mouseReleaseEvent(e)
QDesktopServices.openUrl(self.url)
class LinkCardView(SingleDirectionScrollArea):
""" Link card view """
def __init__(self, parent=None):
super().__init__(parent, Qt.Horizontal)
self.view = QWidget(self)
self.hBoxLayout = QHBoxLayout(self.view)
self.hBoxLayout.setContentsMargins(36, 0, 0, 0)
self.hBoxLayout.setSpacing(12)
self.hBoxLayout.setAlignment(Qt.AlignLeft)
self.setWidget(self.view)
self.setWidgetResizable(True)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.view.setObjectName('view')
StyleSheet.LINK_CARD.apply(self)
def addCard(self, icon, title, content, url):
""" add link card """
card = LinkCard(icon, title, content, url, self.view)
self.hBoxLayout.addWidget(card, 0, Qt.AlignLeft)

View File

@ -0,0 +1,75 @@
# coding:utf-8
from PySide6.QtCore import Qt, Signal
from PySide6.QtGui import QPixmap
from PySide6.QtWidgets import QWidget, QFrame, QLabel, QVBoxLayout, QHBoxLayout
from qfluentwidgets import IconWidget, TextWrap, FlowLayout, CardWidget
from ..common.signal_bus import signalBus
from ..common.style_sheet import StyleSheet
class SampleCard(CardWidget):
""" Sample card """
def __init__(self, icon, title, content, routeKey, index, parent=None):
super().__init__(parent=parent)
self.index = index
self.routekey = routeKey
self.iconWidget = IconWidget(icon, self)
self.titleLabel = QLabel(title, self)
self.contentLabel = QLabel(TextWrap.wrap(content, 45, False)[0], self)
self.hBoxLayout = QHBoxLayout(self)
self.vBoxLayout = QVBoxLayout()
self.setFixedSize(360, 90)
self.iconWidget.setFixedSize(48, 48)
self.hBoxLayout.setSpacing(28)
self.hBoxLayout.setContentsMargins(20, 0, 0, 0)
self.vBoxLayout.setSpacing(2)
self.vBoxLayout.setContentsMargins(0, 0, 0, 0)
self.vBoxLayout.setAlignment(Qt.AlignVCenter)
self.hBoxLayout.setAlignment(Qt.AlignVCenter)
self.hBoxLayout.addWidget(self.iconWidget)
self.hBoxLayout.addLayout(self.vBoxLayout)
self.vBoxLayout.addStretch(1)
self.vBoxLayout.addWidget(self.titleLabel)
self.vBoxLayout.addWidget(self.contentLabel)
self.vBoxLayout.addStretch(1)
self.titleLabel.setObjectName('titleLabel')
self.contentLabel.setObjectName('contentLabel')
def mouseReleaseEvent(self, e):
super().mouseReleaseEvent(e)
signalBus.switchToSampleCard.emit(self.routekey, self.index)
class SampleCardView(QWidget):
""" Sample card view """
def __init__(self, title: str, parent=None):
super().__init__(parent=parent)
self.titleLabel = QLabel(title, self)
self.vBoxLayout = QVBoxLayout(self)
self.flowLayout = FlowLayout()
self.vBoxLayout.setContentsMargins(36, 0, 36, 0)
self.vBoxLayout.setSpacing(10)
self.flowLayout.setContentsMargins(0, 0, 0, 0)
self.flowLayout.setHorizontalSpacing(12)
self.flowLayout.setVerticalSpacing(12)
self.vBoxLayout.addWidget(self.titleLabel)
self.vBoxLayout.addLayout(self.flowLayout, 1)
self.titleLabel.setObjectName('viewTitleLabel')
StyleSheet.SAMPLE_CARD.apply(self)
def addSampleCard(self, icon, title, content, routeKey, index):
""" add sample card """
card = SampleCard(icon, title, content, routeKey, index, self)
self.flowLayout.addWidget(card)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

BIN
app/resource/images/Dvd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
app/resource/images/SBR.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Some files were not shown because too many files have changed in this diff Show More