initial fluent-widgets ui
This commit is contained in:
8
qfluentwidgets/components/settings/__init__.py
Normal file
8
qfluentwidgets/components/settings/__init__.py
Normal file
@ -0,0 +1,8 @@
|
||||
from .setting_card import (SettingCard, SwitchSettingCard, RangeSettingCard,
|
||||
PushSettingCard, ColorSettingCard, HyperlinkCard,
|
||||
PrimaryPushSettingCard, ColorPickerButton, ComboBoxSettingCard)
|
||||
from .expand_setting_card import ExpandSettingCard, ExpandGroupSettingCard, SimpleExpandGroupSettingCard
|
||||
from .folder_list_setting_card import FolderListSettingCard
|
||||
from .options_setting_card import OptionsSettingCard
|
||||
from .custom_color_setting_card import CustomColorSettingCard
|
||||
from .setting_card_group import SettingCardGroup
|
||||
139
qfluentwidgets/components/settings/custom_color_setting_card.py
Normal file
139
qfluentwidgets/components/settings/custom_color_setting_card.py
Normal file
@ -0,0 +1,139 @@
|
||||
# coding:utf-8
|
||||
from typing import Union
|
||||
from PySide6.QtCore import Qt, Signal
|
||||
from PySide6.QtGui import QIcon, QColor
|
||||
from PySide6.QtWidgets import QWidget, QLabel, QButtonGroup, QVBoxLayout, QPushButton, QHBoxLayout
|
||||
|
||||
from ..dialog_box import ColorDialog
|
||||
from .expand_setting_card import ExpandGroupSettingCard
|
||||
from ..widgets.button import RadioButton
|
||||
from ...common.config import qconfig, ColorConfigItem
|
||||
from ...common.icon import FluentIconBase
|
||||
|
||||
|
||||
class CustomColorSettingCard(ExpandGroupSettingCard):
|
||||
""" Custom color setting card """
|
||||
|
||||
colorChanged = Signal(QColor)
|
||||
|
||||
def __init__(self, configItem: ColorConfigItem, icon: Union[str, QIcon, FluentIconBase], title: str,
|
||||
content=None, parent=None, enableAlpha=False):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
configItem: ColorConfigItem
|
||||
options config item
|
||||
|
||||
icon: str | QIcon | FluentIconBase
|
||||
the icon to be drawn
|
||||
|
||||
title: str
|
||||
the title of setting card
|
||||
|
||||
content: str
|
||||
the content of setting card
|
||||
|
||||
parent: QWidget
|
||||
parent window
|
||||
|
||||
enableAlpha: bool
|
||||
whether to enable the alpha channel
|
||||
"""
|
||||
super().__init__(icon, title, content, parent=parent)
|
||||
self.enableAlpha = enableAlpha
|
||||
self.configItem = configItem
|
||||
self.defaultColor = QColor(configItem.defaultValue)
|
||||
self.customColor = QColor(qconfig.get(configItem))
|
||||
|
||||
self.choiceLabel = QLabel(self)
|
||||
|
||||
self.radioWidget = QWidget(self.view)
|
||||
self.radioLayout = QVBoxLayout(self.radioWidget)
|
||||
self.defaultRadioButton = RadioButton(
|
||||
self.tr('Default color'), self.radioWidget)
|
||||
self.customRadioButton = RadioButton(
|
||||
self.tr('Custom color'), self.radioWidget)
|
||||
self.buttonGroup = QButtonGroup(self)
|
||||
|
||||
self.customColorWidget = QWidget(self.view)
|
||||
self.customColorLayout = QHBoxLayout(self.customColorWidget)
|
||||
self.customLabel = QLabel(
|
||||
self.tr('Custom color'), self.customColorWidget)
|
||||
self.chooseColorButton = QPushButton(
|
||||
self.tr('Choose color'), self.customColorWidget)
|
||||
|
||||
self.__initWidget()
|
||||
|
||||
def __initWidget(self):
|
||||
self.__initLayout()
|
||||
|
||||
if self.defaultColor != self.customColor:
|
||||
self.customRadioButton.setChecked(True)
|
||||
self.chooseColorButton.setEnabled(True)
|
||||
else:
|
||||
self.defaultRadioButton.setChecked(True)
|
||||
self.chooseColorButton.setEnabled(False)
|
||||
|
||||
self.choiceLabel.setText(self.buttonGroup.checkedButton().text())
|
||||
self.choiceLabel.adjustSize()
|
||||
|
||||
self.choiceLabel.setObjectName("titleLabel")
|
||||
self.customLabel.setObjectName("titleLabel")
|
||||
self.chooseColorButton.setObjectName('chooseColorButton')
|
||||
|
||||
self.buttonGroup.buttonClicked.connect(self.__onRadioButtonClicked)
|
||||
self.chooseColorButton.clicked.connect(self.__showColorDialog)
|
||||
|
||||
def __initLayout(self):
|
||||
self.addWidget(self.choiceLabel)
|
||||
|
||||
self.radioLayout.setSpacing(19)
|
||||
self.radioLayout.setAlignment(Qt.AlignTop)
|
||||
self.radioLayout.setContentsMargins(48, 18, 0, 18)
|
||||
self.buttonGroup.addButton(self.customRadioButton)
|
||||
self.buttonGroup.addButton(self.defaultRadioButton)
|
||||
self.radioLayout.addWidget(self.customRadioButton)
|
||||
self.radioLayout.addWidget(self.defaultRadioButton)
|
||||
self.radioLayout.setSizeConstraint(QVBoxLayout.SetMinimumSize)
|
||||
|
||||
self.customColorLayout.setContentsMargins(48, 18, 44, 18)
|
||||
self.customColorLayout.addWidget(self.customLabel, 0, Qt.AlignLeft)
|
||||
self.customColorLayout.addWidget(self.chooseColorButton, 0, Qt.AlignRight)
|
||||
self.customColorLayout.setSizeConstraint(QHBoxLayout.SetMinimumSize)
|
||||
|
||||
self.viewLayout.setSpacing(0)
|
||||
self.viewLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.addGroupWidget(self.radioWidget)
|
||||
self.addGroupWidget(self.customColorWidget)
|
||||
|
||||
def __onRadioButtonClicked(self, button: RadioButton):
|
||||
""" radio button clicked slot """
|
||||
if button.text() == self.choiceLabel.text():
|
||||
return
|
||||
|
||||
self.choiceLabel.setText(button.text())
|
||||
self.choiceLabel.adjustSize()
|
||||
|
||||
if button is self.defaultRadioButton:
|
||||
self.chooseColorButton.setDisabled(True)
|
||||
qconfig.set(self.configItem, self.defaultColor)
|
||||
if self.defaultColor != self.customColor:
|
||||
self.colorChanged.emit(self.defaultColor)
|
||||
else:
|
||||
self.chooseColorButton.setDisabled(False)
|
||||
qconfig.set(self.configItem, self.customColor)
|
||||
if self.defaultColor != self.customColor:
|
||||
self.colorChanged.emit(self.customColor)
|
||||
|
||||
def __showColorDialog(self):
|
||||
""" show color dialog """
|
||||
w = ColorDialog(
|
||||
qconfig.get(self.configItem), self.tr('Choose color'), self.window(), self.enableAlpha)
|
||||
w.colorChanged.connect(self.__onCustomColorChanged)
|
||||
w.exec()
|
||||
|
||||
def __onCustomColorChanged(self, color):
|
||||
""" custom color changed slot """
|
||||
qconfig.set(self.configItem, color)
|
||||
self.customColor = QColor(color)
|
||||
self.colorChanged.emit(color)
|
||||
390
qfluentwidgets/components/settings/expand_setting_card.py
Normal file
390
qfluentwidgets/components/settings/expand_setting_card.py
Normal file
@ -0,0 +1,390 @@
|
||||
# coding:utf-8
|
||||
from typing import List, Union
|
||||
from PySide6.QtCore import QEvent, Qt, QPropertyAnimation, Property, QEasingCurve, QRectF
|
||||
from PySide6.QtGui import QColor, QPainter, QIcon, QPainterPath
|
||||
from PySide6.QtWidgets import QFrame, QWidget, QAbstractButton, QApplication, QScrollArea, QVBoxLayout
|
||||
|
||||
from ...common.config import isDarkTheme
|
||||
from ...common.icon import FluentIcon as FIF
|
||||
from ...common.style_sheet import FluentStyleSheet
|
||||
from .setting_card import SettingCard
|
||||
from ..layout.v_box_layout import VBoxLayout
|
||||
|
||||
|
||||
class ExpandButton(QAbstractButton):
|
||||
""" Expand button """
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setFixedSize(30, 30)
|
||||
self.__angle = 0
|
||||
self.isHover = False
|
||||
self.isPressed = False
|
||||
self.rotateAni = QPropertyAnimation(self, b'angle', self)
|
||||
self.clicked.connect(self.__onClicked)
|
||||
|
||||
def paintEvent(self, e):
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHints(QPainter.Antialiasing |
|
||||
QPainter.SmoothPixmapTransform)
|
||||
painter.setPen(Qt.NoPen)
|
||||
|
||||
# draw background
|
||||
r = 255 if isDarkTheme() else 0
|
||||
color = Qt.transparent
|
||||
|
||||
if self.isEnabled():
|
||||
if self.isPressed:
|
||||
color = QColor(r, r, r, 10)
|
||||
elif self.isHover:
|
||||
color = QColor(r, r, r, 14)
|
||||
else:
|
||||
painter.setOpacity(0.36)
|
||||
|
||||
painter.setBrush(color)
|
||||
painter.drawRoundedRect(self.rect(), 4, 4)
|
||||
|
||||
# draw icon
|
||||
painter.translate(self.width()//2, self.height()//2)
|
||||
painter.rotate(self.__angle)
|
||||
FIF.ARROW_DOWN.render(painter, QRectF(-5, -5, 9.6, 9.6))
|
||||
|
||||
def enterEvent(self, e):
|
||||
self.setHover(True)
|
||||
|
||||
def leaveEvent(self, e):
|
||||
self.setHover(False)
|
||||
|
||||
def mousePressEvent(self, e):
|
||||
super().mousePressEvent(e)
|
||||
self.setPressed(True)
|
||||
|
||||
def mouseReleaseEvent(self, e):
|
||||
super().mouseReleaseEvent(e)
|
||||
self.setPressed(False)
|
||||
|
||||
def setHover(self, isHover: bool):
|
||||
self.isHover = isHover
|
||||
self.update()
|
||||
|
||||
def setPressed(self, isPressed: bool):
|
||||
self.isPressed = isPressed
|
||||
self.update()
|
||||
|
||||
def __onClicked(self):
|
||||
self.setExpand(self.angle < 180)
|
||||
|
||||
def setExpand(self, isExpand: bool):
|
||||
self.rotateAni.stop()
|
||||
self.rotateAni.setEndValue(180 if isExpand else 0)
|
||||
self.rotateAni.setDuration(200)
|
||||
self.rotateAni.start()
|
||||
|
||||
def getAngle(self):
|
||||
return self.__angle
|
||||
|
||||
def setAngle(self, angle):
|
||||
self.__angle = angle
|
||||
self.update()
|
||||
|
||||
angle = Property(float, getAngle, setAngle)
|
||||
|
||||
|
||||
class SpaceWidget(QWidget):
|
||||
""" Spacing widget """
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.setAttribute(Qt.WA_TranslucentBackground)
|
||||
self.setFixedHeight(1)
|
||||
|
||||
|
||||
class HeaderSettingCard(SettingCard):
|
||||
""" Header setting card """
|
||||
|
||||
def __init__(self, icon, title, content=None, parent=None):
|
||||
super().__init__(icon, title, content, parent)
|
||||
self.expandButton = ExpandButton(self)
|
||||
|
||||
self.hBoxLayout.addWidget(self.expandButton, 0, Qt.AlignRight)
|
||||
self.hBoxLayout.addSpacing(8)
|
||||
|
||||
self.titleLabel.setObjectName("titleLabel")
|
||||
self.installEventFilter(self)
|
||||
|
||||
def eventFilter(self, obj, e):
|
||||
if obj is self:
|
||||
if e.type() == QEvent.Enter:
|
||||
self.expandButton.setHover(True)
|
||||
elif e.type() == QEvent.Leave:
|
||||
self.expandButton.setHover(False)
|
||||
elif e.type() == QEvent.MouseButtonPress and e.button() == Qt.LeftButton:
|
||||
self.expandButton.setPressed(True)
|
||||
elif e.type() == QEvent.MouseButtonRelease and e.button() == Qt.LeftButton:
|
||||
self.expandButton.setPressed(False)
|
||||
self.expandButton.click()
|
||||
|
||||
return super().eventFilter(obj, e)
|
||||
|
||||
def addWidget(self, widget: QWidget):
|
||||
""" add widget to tail """
|
||||
N = self.hBoxLayout.count()
|
||||
self.hBoxLayout.removeItem(self.hBoxLayout.itemAt(N - 1))
|
||||
self.hBoxLayout.addWidget(widget, 0, Qt.AlignRight)
|
||||
self.hBoxLayout.addSpacing(19)
|
||||
self.hBoxLayout.addWidget(self.expandButton, 0, Qt.AlignRight)
|
||||
self.hBoxLayout.addSpacing(8)
|
||||
|
||||
def paintEvent(self, e):
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHints(QPainter.Antialiasing)
|
||||
painter.setPen(Qt.NoPen)
|
||||
|
||||
if isDarkTheme():
|
||||
painter.setBrush(QColor(255, 255, 255, 13))
|
||||
else:
|
||||
painter.setBrush(QColor(255, 255, 255, 170))
|
||||
|
||||
p = self.parent() # type: ExpandSettingCard
|
||||
path = QPainterPath()
|
||||
path.setFillRule(Qt.WindingFill)
|
||||
path.addRoundedRect(QRectF(self.rect().adjusted(1, 1, -1, -1)), 6, 6)
|
||||
|
||||
# set the bottom border radius to 0 if parent is expanded
|
||||
if p.isExpand:
|
||||
path.addRect(1, self.height() - 8, self.width() - 2, 8)
|
||||
|
||||
painter.drawPath(path.simplified())
|
||||
|
||||
|
||||
class ExpandBorderWidget(QWidget):
|
||||
""" Expand setting card border widget """
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.setAttribute(Qt.WA_TransparentForMouseEvents)
|
||||
parent.installEventFilter(self)
|
||||
|
||||
def eventFilter(self, obj, e):
|
||||
if obj is self.parent() and e.type() == QEvent.Resize:
|
||||
self.resize(e.size())
|
||||
|
||||
return super().eventFilter(obj, e)
|
||||
|
||||
def paintEvent(self, e):
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHints(QPainter.Antialiasing)
|
||||
painter.setBrush(Qt.NoBrush)
|
||||
|
||||
if isDarkTheme():
|
||||
painter.setPen(QColor(0, 0, 0, 50))
|
||||
else:
|
||||
painter.setPen(QColor(0, 0, 0, 19))
|
||||
|
||||
p = self.parent() # type: ExpandSettingCard
|
||||
r, d = 6, 12
|
||||
ch, h, w = p.card.height(), self.height(), self.width()
|
||||
|
||||
# only draw rounded rect if parent is not expanded
|
||||
painter.drawRoundedRect(self.rect().adjusted(1, 1, -1, -1), r, r)
|
||||
|
||||
# draw the seperator line under card widget
|
||||
if ch < h:
|
||||
painter.drawLine(1, ch, w - 1, ch)
|
||||
|
||||
|
||||
|
||||
|
||||
class ExpandSettingCard(QScrollArea):
|
||||
""" Expandable setting card """
|
||||
|
||||
def __init__(self, icon: Union[str, QIcon, FIF], title: str, content: str = None, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.isExpand = False
|
||||
|
||||
self.scrollWidget = QFrame(self)
|
||||
self.view = QFrame(self.scrollWidget)
|
||||
self.card = HeaderSettingCard(icon, title, content, self)
|
||||
|
||||
self.scrollLayout = QVBoxLayout(self.scrollWidget)
|
||||
self.viewLayout = QVBoxLayout(self.view)
|
||||
self.spaceWidget = SpaceWidget(self.scrollWidget)
|
||||
self.borderWidget = ExpandBorderWidget(self)
|
||||
|
||||
# expand animation
|
||||
self.expandAni = QPropertyAnimation(self.verticalScrollBar(), b'value', self)
|
||||
|
||||
self.__initWidget()
|
||||
|
||||
def __initWidget(self):
|
||||
""" initialize widgets """
|
||||
self.setWidget(self.scrollWidget)
|
||||
self.setWidgetResizable(True)
|
||||
self.setFixedHeight(self.card.height())
|
||||
self.setViewportMargins(0, self.card.height(), 0, 0)
|
||||
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
|
||||
# initialize layout
|
||||
self.scrollLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.scrollLayout.setSpacing(0)
|
||||
self.scrollLayout.addWidget(self.view)
|
||||
self.scrollLayout.addWidget(self.spaceWidget)
|
||||
|
||||
# initialize expand animation
|
||||
self.expandAni.setEasingCurve(QEasingCurve.OutQuad)
|
||||
self.expandAni.setDuration(200)
|
||||
|
||||
# initialize style sheet
|
||||
self.view.setObjectName('view')
|
||||
self.scrollWidget.setObjectName('scrollWidget')
|
||||
self.setProperty('isExpand', False)
|
||||
FluentStyleSheet.EXPAND_SETTING_CARD.apply(self.card)
|
||||
FluentStyleSheet.EXPAND_SETTING_CARD.apply(self)
|
||||
|
||||
self.card.installEventFilter(self)
|
||||
self.expandAni.valueChanged.connect(self._onExpandValueChanged)
|
||||
self.card.expandButton.clicked.connect(self.toggleExpand)
|
||||
|
||||
def addWidget(self, widget: QWidget):
|
||||
""" add widget to tail """
|
||||
self.card.addWidget(widget)
|
||||
|
||||
def wheelEvent(self, e):
|
||||
e.ignore()
|
||||
|
||||
def setExpand(self, isExpand: bool):
|
||||
""" set the expand status of card """
|
||||
if self.isExpand == isExpand:
|
||||
return
|
||||
|
||||
# update style sheet
|
||||
self.isExpand = isExpand
|
||||
self.setProperty('isExpand', isExpand)
|
||||
self.setStyle(QApplication.style())
|
||||
|
||||
# start expand animation
|
||||
if isExpand:
|
||||
h = self.viewLayout.sizeHint().height()
|
||||
self.verticalScrollBar().setValue(h)
|
||||
self.expandAni.setStartValue(h)
|
||||
self.expandAni.setEndValue(0)
|
||||
else:
|
||||
self.expandAni.setStartValue(0)
|
||||
self.expandAni.setEndValue(self.verticalScrollBar().maximum())
|
||||
|
||||
self.expandAni.start()
|
||||
self.card.expandButton.setExpand(isExpand)
|
||||
|
||||
def toggleExpand(self):
|
||||
""" toggle expand status """
|
||||
self.setExpand(not self.isExpand)
|
||||
|
||||
def resizeEvent(self, e):
|
||||
self.card.resize(self.width(), self.card.height())
|
||||
self.scrollWidget.resize(self.width(), self.scrollWidget.height())
|
||||
|
||||
def _onExpandValueChanged(self):
|
||||
vh = self.viewLayout.sizeHint().height()
|
||||
h = self.viewportMargins().top()
|
||||
self.setFixedHeight(max(h + vh - self.verticalScrollBar().value(), h))
|
||||
|
||||
def _adjustViewSize(self):
|
||||
""" adjust view size """
|
||||
h = self.viewLayout.sizeHint().height()
|
||||
self.spaceWidget.setFixedHeight(h)
|
||||
|
||||
if self.isExpand:
|
||||
self.setFixedHeight(self.card.height()+h)
|
||||
|
||||
def setValue(self, value):
|
||||
""" set the value of config item """
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class GroupSeparator(QWidget):
|
||||
""" group separator """
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.setFixedHeight(3)
|
||||
|
||||
def paintEvent(self, e):
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHints(QPainter.Antialiasing)
|
||||
|
||||
if isDarkTheme():
|
||||
painter.setPen(QColor(0, 0, 0, 50))
|
||||
else:
|
||||
painter.setPen(QColor(0, 0, 0, 19))
|
||||
|
||||
painter.drawLine(0, 1, self.width(), 1)
|
||||
|
||||
|
||||
class ExpandGroupSettingCard(ExpandSettingCard):
|
||||
""" Expand group setting card """
|
||||
|
||||
def __init__(self, icon: Union[str, QIcon, FIF], title: str, content: str = None, parent=None):
|
||||
super().__init__(icon, title, content, parent)
|
||||
self.widgets = [] # type: List[QWidget]
|
||||
|
||||
self.viewLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.viewLayout.setSpacing(0)
|
||||
|
||||
def addGroupWidget(self, widget: QWidget):
|
||||
""" add widget to group """
|
||||
# add separator
|
||||
if self.viewLayout.count() >= 1:
|
||||
self.viewLayout.addWidget(GroupSeparator(self.view))
|
||||
|
||||
widget.setParent(self.view)
|
||||
self.widgets.append(widget)
|
||||
self.viewLayout.addWidget(widget)
|
||||
self._adjustViewSize()
|
||||
|
||||
def removeGroupWidget(self, widget: QWidget):
|
||||
""" remove a group from card """
|
||||
if widget not in self.widgets:
|
||||
return
|
||||
|
||||
layoutIndex = self.viewLayout.indexOf(widget)
|
||||
index = self.widgets.index(widget)
|
||||
|
||||
self.viewLayout.removeWidget(widget)
|
||||
self.widgets.remove(widget)
|
||||
|
||||
if not self.widgets:
|
||||
return self._adjustViewSize()
|
||||
|
||||
# remove separator
|
||||
if layoutIndex >= 1:
|
||||
separator = self.viewLayout.itemAt(layoutIndex - 1).widget()
|
||||
separator.deleteLater()
|
||||
self.viewLayout.removeWidget(separator)
|
||||
elif index == 0:
|
||||
separator = self.viewLayout.itemAt(0).widget()
|
||||
separator.deleteLater()
|
||||
self.viewLayout.removeWidget(separator)
|
||||
|
||||
self._adjustViewSize()
|
||||
|
||||
def _adjustViewSize(self):
|
||||
""" adjust view size """
|
||||
h = sum(w.sizeHint().height() + 3 for w in self.widgets)
|
||||
self.spaceWidget.setFixedHeight(h)
|
||||
|
||||
if self.isExpand:
|
||||
self.setFixedHeight(self.card.height()+h)
|
||||
|
||||
|
||||
class SimpleExpandGroupSettingCard(ExpandGroupSettingCard):
|
||||
""" Simple expand group setting card """
|
||||
|
||||
def _adjustViewSize(self):
|
||||
""" adjust view size """
|
||||
h = self.viewLayout.sizeHint().height()
|
||||
self.spaceWidget.setFixedHeight(h)
|
||||
|
||||
if self.isExpand:
|
||||
self.setFixedHeight(self.card.height()+h)
|
||||
134
qfluentwidgets/components/settings/folder_list_setting_card.py
Normal file
134
qfluentwidgets/components/settings/folder_list_setting_card.py
Normal file
@ -0,0 +1,134 @@
|
||||
# coding:utf-8
|
||||
from typing import List
|
||||
from pathlib import Path
|
||||
|
||||
from PySide6.QtCore import Qt, Signal, QSize
|
||||
from PySide6.QtGui import QPainter, QIcon
|
||||
from PySide6.QtWidgets import (QPushButton, QFileDialog, QWidget, QLabel,
|
||||
QHBoxLayout, QToolButton, QSizePolicy)
|
||||
|
||||
from ...components.widgets.button import ToolButton, PushButton
|
||||
from ...common.config import ConfigItem, qconfig
|
||||
from ...common.icon import drawIcon
|
||||
from ...common.icon import FluentIcon as FIF
|
||||
from ..dialog_box.dialog import Dialog
|
||||
from .expand_setting_card import ExpandSettingCard
|
||||
|
||||
|
||||
|
||||
class FolderItem(QWidget):
|
||||
""" Folder item """
|
||||
|
||||
removed = Signal(QWidget)
|
||||
|
||||
def __init__(self, folder: str, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.folder = folder
|
||||
self.hBoxLayout = QHBoxLayout(self)
|
||||
self.folderLabel = QLabel(folder, self)
|
||||
self.removeButton = ToolButton(FIF.CLOSE, self)
|
||||
|
||||
self.removeButton.setFixedSize(39, 29)
|
||||
self.removeButton.setIconSize(QSize(12, 12))
|
||||
|
||||
self.setFixedHeight(53)
|
||||
self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
|
||||
self.hBoxLayout.setContentsMargins(48, 0, 60, 0)
|
||||
self.hBoxLayout.addWidget(self.folderLabel, 0, Qt.AlignLeft)
|
||||
self.hBoxLayout.addSpacing(16)
|
||||
self.hBoxLayout.addStretch(1)
|
||||
self.hBoxLayout.addWidget(self.removeButton, 0, Qt.AlignRight)
|
||||
self.hBoxLayout.setAlignment(Qt.AlignVCenter)
|
||||
|
||||
self.removeButton.clicked.connect(
|
||||
lambda: self.removed.emit(self))
|
||||
|
||||
|
||||
class FolderListSettingCard(ExpandSettingCard):
|
||||
""" Folder list setting card """
|
||||
|
||||
folderChanged = Signal(list)
|
||||
|
||||
def __init__(self, configItem: ConfigItem, title: str, content: str = None, directory="./", parent=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
configItem: RangeConfigItem
|
||||
configuration item operated by the card
|
||||
|
||||
title: str
|
||||
the title of card
|
||||
|
||||
content: str
|
||||
the content of card
|
||||
|
||||
directory: str
|
||||
working directory of file dialog
|
||||
|
||||
parent: QWidget
|
||||
parent widget
|
||||
"""
|
||||
super().__init__(FIF.FOLDER, title, content, parent)
|
||||
self.configItem = configItem
|
||||
self._dialogDirectory = directory
|
||||
self.addFolderButton = PushButton(self.tr('Add folder'), self, FIF.FOLDER_ADD)
|
||||
|
||||
self.folders = qconfig.get(configItem).copy() # type:List[str]
|
||||
self.__initWidget()
|
||||
|
||||
def __initWidget(self):
|
||||
self.addWidget(self.addFolderButton)
|
||||
|
||||
# initialize layout
|
||||
self.viewLayout.setSpacing(0)
|
||||
self.viewLayout.setAlignment(Qt.AlignTop)
|
||||
self.viewLayout.setContentsMargins(0, 0, 0, 0)
|
||||
for folder in self.folders:
|
||||
self.__addFolderItem(folder)
|
||||
|
||||
self.addFolderButton.clicked.connect(self.__showFolderDialog)
|
||||
|
||||
def __showFolderDialog(self):
|
||||
""" show folder dialog """
|
||||
folder = QFileDialog.getExistingDirectory(
|
||||
self, self.tr("Choose folder"), self._dialogDirectory)
|
||||
|
||||
if not folder or folder in self.folders:
|
||||
return
|
||||
|
||||
self.__addFolderItem(folder)
|
||||
self.folders.append(folder)
|
||||
qconfig.set(self.configItem, self.folders)
|
||||
self.folderChanged.emit(self.folders)
|
||||
|
||||
def __addFolderItem(self, folder: str):
|
||||
""" add folder item """
|
||||
item = FolderItem(folder, self.view)
|
||||
item.removed.connect(self.__showConfirmDialog)
|
||||
self.viewLayout.addWidget(item)
|
||||
item.show()
|
||||
self._adjustViewSize()
|
||||
|
||||
def __showConfirmDialog(self, item: FolderItem):
|
||||
""" show confirm dialog """
|
||||
name = Path(item.folder).name
|
||||
title = self.tr('Are you sure you want to delete the folder?')
|
||||
content = self.tr("If you delete the ") + f'"{name}"' + \
|
||||
self.tr(" folder and remove it from the list, the folder will no "
|
||||
"longer appear in the list, but will not be deleted.")
|
||||
w = Dialog(title, content, self.window())
|
||||
w.yesSignal.connect(lambda: self.__removeFolder(item))
|
||||
w.exec_()
|
||||
|
||||
def __removeFolder(self, item: FolderItem):
|
||||
""" remove folder """
|
||||
if item.folder not in self.folders:
|
||||
return
|
||||
|
||||
self.folders.remove(item.folder)
|
||||
self.viewLayout.removeWidget(item)
|
||||
item.deleteLater()
|
||||
self._adjustViewSize()
|
||||
|
||||
self.folderChanged.emit(self.folders)
|
||||
qconfig.set(self.configItem, self.folders)
|
||||
86
qfluentwidgets/components/settings/options_setting_card.py
Normal file
86
qfluentwidgets/components/settings/options_setting_card.py
Normal file
@ -0,0 +1,86 @@
|
||||
# coding:utf-8
|
||||
from typing import Union
|
||||
from PySide6.QtCore import Signal
|
||||
from PySide6.QtGui import QIcon
|
||||
from PySide6.QtWidgets import QButtonGroup, QLabel
|
||||
|
||||
from ...common.config import OptionsConfigItem, qconfig
|
||||
from ...common.icon import FluentIconBase
|
||||
from ..widgets.button import RadioButton
|
||||
from .expand_setting_card import ExpandSettingCard
|
||||
|
||||
|
||||
class OptionsSettingCard(ExpandSettingCard):
|
||||
""" setting card with a group of options """
|
||||
|
||||
optionChanged = Signal(OptionsConfigItem)
|
||||
|
||||
def __init__(self, configItem, icon: Union[str, QIcon, FluentIconBase], title, content=None, texts=None, parent=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
configItem: OptionsConfigItem
|
||||
options config item
|
||||
|
||||
icon: str | QIcon | FluentIconBase
|
||||
the icon to be drawn
|
||||
|
||||
title: str
|
||||
the title of setting card
|
||||
|
||||
content: str
|
||||
the content of setting card
|
||||
|
||||
texts: List[str]
|
||||
the texts of radio buttons
|
||||
|
||||
parent: QWidget
|
||||
parent window
|
||||
"""
|
||||
super().__init__(icon, title, content, parent)
|
||||
self.texts = texts or []
|
||||
self.configItem = configItem
|
||||
self.configName = configItem.name
|
||||
self.choiceLabel = QLabel(self)
|
||||
self.buttonGroup = QButtonGroup(self)
|
||||
|
||||
self.choiceLabel.setObjectName("titleLabel")
|
||||
self.addWidget(self.choiceLabel)
|
||||
|
||||
# create buttons
|
||||
self.viewLayout.setSpacing(19)
|
||||
self.viewLayout.setContentsMargins(48, 18, 0, 18)
|
||||
for text, option in zip(texts, configItem.options):
|
||||
button = RadioButton(text, self.view)
|
||||
self.buttonGroup.addButton(button)
|
||||
self.viewLayout.addWidget(button)
|
||||
button.setProperty(self.configName, option)
|
||||
|
||||
self._adjustViewSize()
|
||||
self.setValue(qconfig.get(self.configItem))
|
||||
configItem.valueChanged.connect(self.setValue)
|
||||
self.buttonGroup.buttonClicked.connect(self.__onButtonClicked)
|
||||
|
||||
def __onButtonClicked(self, button: RadioButton):
|
||||
""" button clicked slot """
|
||||
if button.text() == self.choiceLabel.text():
|
||||
return
|
||||
|
||||
value = button.property(self.configName)
|
||||
qconfig.set(self.configItem, value)
|
||||
|
||||
self.choiceLabel.setText(button.text())
|
||||
self.choiceLabel.adjustSize()
|
||||
self.optionChanged.emit(self.configItem)
|
||||
|
||||
def setValue(self, value):
|
||||
""" select button according to the value """
|
||||
qconfig.set(self.configItem, value)
|
||||
|
||||
for button in self.buttonGroup.buttons():
|
||||
isChecked = button.property(self.configName) == value
|
||||
button.setChecked(isChecked)
|
||||
|
||||
if isChecked:
|
||||
self.choiceLabel.setText(button.text())
|
||||
self.choiceLabel.adjustSize()
|
||||
449
qfluentwidgets/components/settings/setting_card.py
Normal file
449
qfluentwidgets/components/settings/setting_card.py
Normal file
@ -0,0 +1,449 @@
|
||||
# coding:utf-8
|
||||
from typing import Union
|
||||
|
||||
from PySide6.QtCore import Qt, Signal
|
||||
from PySide6.QtGui import QColor, QIcon, QPainter
|
||||
from PySide6.QtWidgets import QFrame, QHBoxLayout, QLabel, QToolButton, QVBoxLayout, QPushButton
|
||||
from PySide6.QtSvgWidgets import QSvgWidget
|
||||
|
||||
from ..dialog_box.color_dialog import ColorDialog
|
||||
from ..widgets.combo_box import ComboBox
|
||||
from ..widgets.switch_button import SwitchButton, IndicatorPosition
|
||||
from ..widgets.slider import Slider
|
||||
from ..widgets.icon_widget import IconWidget
|
||||
from ..widgets.button import HyperlinkButton
|
||||
from ...common.style_sheet import FluentStyleSheet
|
||||
from ...common.config import qconfig, isDarkTheme, ConfigItem, OptionsConfigItem
|
||||
from ...common.icon import FluentIconBase, drawIcon
|
||||
|
||||
|
||||
class SettingIconWidget(IconWidget):
|
||||
|
||||
def paintEvent(self, e):
|
||||
painter = QPainter(self)
|
||||
|
||||
if not self.isEnabled():
|
||||
painter.setOpacity(0.36)
|
||||
|
||||
painter.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
|
||||
drawIcon(self._icon, painter, self.rect())
|
||||
|
||||
|
||||
|
||||
class SettingCard(QFrame):
|
||||
""" Setting card """
|
||||
|
||||
def __init__(self, icon: Union[str, QIcon, FluentIconBase], title, content=None, parent=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
icon: str | QIcon | FluentIconBase
|
||||
the icon to be drawn
|
||||
|
||||
title: str
|
||||
the title of card
|
||||
|
||||
content: str
|
||||
the content of card
|
||||
|
||||
parent: QWidget
|
||||
parent widget
|
||||
"""
|
||||
super().__init__(parent=parent)
|
||||
self.iconLabel = SettingIconWidget(icon, self)
|
||||
self.titleLabel = QLabel(title, self)
|
||||
self.contentLabel = QLabel(content or '', self)
|
||||
self.hBoxLayout = QHBoxLayout(self)
|
||||
self.vBoxLayout = QVBoxLayout()
|
||||
|
||||
if not content:
|
||||
self.contentLabel.hide()
|
||||
|
||||
self.setFixedHeight(70 if content else 50)
|
||||
self.iconLabel.setFixedSize(16, 16)
|
||||
|
||||
# initialize layout
|
||||
self.hBoxLayout.setSpacing(0)
|
||||
self.hBoxLayout.setContentsMargins(16, 0, 0, 0)
|
||||
self.hBoxLayout.setAlignment(Qt.AlignVCenter)
|
||||
self.vBoxLayout.setSpacing(0)
|
||||
self.vBoxLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.vBoxLayout.setAlignment(Qt.AlignVCenter)
|
||||
|
||||
self.hBoxLayout.addWidget(self.iconLabel, 0, Qt.AlignLeft)
|
||||
self.hBoxLayout.addSpacing(16)
|
||||
|
||||
self.hBoxLayout.addLayout(self.vBoxLayout)
|
||||
self.vBoxLayout.addWidget(self.titleLabel, 0, Qt.AlignLeft)
|
||||
self.vBoxLayout.addWidget(self.contentLabel, 0, Qt.AlignLeft)
|
||||
|
||||
self.hBoxLayout.addSpacing(16)
|
||||
self.hBoxLayout.addStretch(1)
|
||||
|
||||
self.contentLabel.setObjectName('contentLabel')
|
||||
FluentStyleSheet.SETTING_CARD.apply(self)
|
||||
|
||||
def setTitle(self, title: str):
|
||||
""" set the title of card """
|
||||
self.titleLabel.setText(title)
|
||||
|
||||
def setContent(self, content: str):
|
||||
""" set the content of card """
|
||||
self.contentLabel.setText(content)
|
||||
self.contentLabel.setVisible(bool(content))
|
||||
|
||||
def setValue(self, value):
|
||||
""" set the value of config item """
|
||||
pass
|
||||
|
||||
def setIconSize(self, width: int, height: int):
|
||||
""" set the icon fixed size """
|
||||
self.iconLabel.setFixedSize(width, height)
|
||||
|
||||
def paintEvent(self, e):
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHints(QPainter.Antialiasing)
|
||||
|
||||
if isDarkTheme():
|
||||
painter.setBrush(QColor(255, 255, 255, 13))
|
||||
painter.setPen(QColor(0, 0, 0, 50))
|
||||
else:
|
||||
painter.setBrush(QColor(255, 255, 255, 170))
|
||||
painter.setPen(QColor(0, 0, 0, 19))
|
||||
|
||||
painter.drawRoundedRect(self.rect().adjusted(1, 1, -1, -1), 6, 6)
|
||||
|
||||
|
||||
|
||||
class SwitchSettingCard(SettingCard):
|
||||
""" Setting card with switch button """
|
||||
|
||||
checkedChanged = Signal(bool)
|
||||
|
||||
def __init__(self, icon: Union[str, QIcon, FluentIconBase], title, content=None,
|
||||
configItem: ConfigItem = None, parent=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
icon: str | QIcon | FluentIconBase
|
||||
the icon to be drawn
|
||||
|
||||
title: str
|
||||
the title of card
|
||||
|
||||
content: str
|
||||
the content of card
|
||||
|
||||
configItem: ConfigItem
|
||||
configuration item operated by the card
|
||||
|
||||
parent: QWidget
|
||||
parent widget
|
||||
"""
|
||||
super().__init__(icon, title, content, parent)
|
||||
self.configItem = configItem
|
||||
self.switchButton = SwitchButton(
|
||||
self.tr('Off'), self, IndicatorPosition.RIGHT)
|
||||
|
||||
if configItem:
|
||||
self.setValue(qconfig.get(configItem))
|
||||
configItem.valueChanged.connect(self.setValue)
|
||||
|
||||
# add switch button to layout
|
||||
self.hBoxLayout.addWidget(self.switchButton, 0, Qt.AlignRight)
|
||||
self.hBoxLayout.addSpacing(16)
|
||||
|
||||
self.switchButton.checkedChanged.connect(self.__onCheckedChanged)
|
||||
|
||||
def __onCheckedChanged(self, isChecked: bool):
|
||||
""" switch button checked state changed slot """
|
||||
self.setValue(isChecked)
|
||||
self.checkedChanged.emit(isChecked)
|
||||
|
||||
def setValue(self, isChecked: bool):
|
||||
if self.configItem:
|
||||
qconfig.set(self.configItem, isChecked)
|
||||
|
||||
self.switchButton.setChecked(isChecked)
|
||||
self.switchButton.setText(
|
||||
self.tr('On') if isChecked else self.tr('Off'))
|
||||
|
||||
def setChecked(self, isChecked: bool):
|
||||
self.setValue(isChecked)
|
||||
|
||||
def isChecked(self):
|
||||
return self.switchButton.isChecked()
|
||||
|
||||
|
||||
class RangeSettingCard(SettingCard):
|
||||
""" Setting card with a slider """
|
||||
|
||||
valueChanged = Signal(int)
|
||||
|
||||
def __init__(self, configItem, icon: Union[str, QIcon, FluentIconBase], title, content=None, parent=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
configItem: RangeConfigItem
|
||||
configuration item operated by the card
|
||||
|
||||
icon: str | QIcon | FluentIconBase
|
||||
the icon to be drawn
|
||||
|
||||
title: str
|
||||
the title of card
|
||||
|
||||
content: str
|
||||
the content of card
|
||||
|
||||
parent: QWidget
|
||||
parent widget
|
||||
"""
|
||||
super().__init__(icon, title, content, parent)
|
||||
self.configItem = configItem
|
||||
self.slider = Slider(Qt.Horizontal, self)
|
||||
self.valueLabel = QLabel(self)
|
||||
self.slider.setMinimumWidth(268)
|
||||
|
||||
self.slider.setSingleStep(1)
|
||||
self.slider.setRange(*configItem.range)
|
||||
self.slider.setValue(configItem.value)
|
||||
self.valueLabel.setNum(configItem.value)
|
||||
|
||||
self.hBoxLayout.addStretch(1)
|
||||
self.hBoxLayout.addWidget(self.valueLabel, 0, Qt.AlignRight)
|
||||
self.hBoxLayout.addSpacing(6)
|
||||
self.hBoxLayout.addWidget(self.slider, 0, Qt.AlignRight)
|
||||
self.hBoxLayout.addSpacing(16)
|
||||
|
||||
self.valueLabel.setObjectName('valueLabel')
|
||||
configItem.valueChanged.connect(self.setValue)
|
||||
self.slider.valueChanged.connect(self.__onValueChanged)
|
||||
|
||||
def __onValueChanged(self, value: int):
|
||||
""" slider value changed slot """
|
||||
self.setValue(value)
|
||||
self.valueChanged.emit(value)
|
||||
|
||||
def setValue(self, value):
|
||||
qconfig.set(self.configItem, value)
|
||||
self.valueLabel.setNum(value)
|
||||
self.valueLabel.adjustSize()
|
||||
self.slider.setValue(value)
|
||||
|
||||
|
||||
class PushSettingCard(SettingCard):
|
||||
""" Setting card with a push button """
|
||||
|
||||
clicked = Signal()
|
||||
|
||||
def __init__(self, text, icon: Union[str, QIcon, FluentIconBase], title, content=None, parent=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
text: str
|
||||
the text of push button
|
||||
|
||||
icon: str | QIcon | FluentIconBase
|
||||
the icon to be drawn
|
||||
|
||||
title: str
|
||||
the title of card
|
||||
|
||||
content: str
|
||||
the content of card
|
||||
|
||||
parent: QWidget
|
||||
parent widget
|
||||
"""
|
||||
super().__init__(icon, title, content, parent)
|
||||
self.button = QPushButton(text, self)
|
||||
self.hBoxLayout.addWidget(self.button, 0, Qt.AlignRight)
|
||||
self.hBoxLayout.addSpacing(16)
|
||||
self.button.clicked.connect(self.clicked)
|
||||
|
||||
|
||||
class PrimaryPushSettingCard(PushSettingCard):
|
||||
""" Push setting card with primary color """
|
||||
|
||||
def __init__(self, text, icon, title, content=None, parent=None):
|
||||
super().__init__(text, icon, title, content, parent)
|
||||
self.button.setObjectName('primaryButton')
|
||||
|
||||
|
||||
class HyperlinkCard(SettingCard):
|
||||
""" Hyperlink card """
|
||||
|
||||
def __init__(self, url, text, icon: Union[str, QIcon, FluentIconBase], title, content=None, parent=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
url: str
|
||||
the url to be opened
|
||||
|
||||
text: str
|
||||
text of url
|
||||
|
||||
icon: str | QIcon | FluentIconBase
|
||||
the icon to be drawn
|
||||
|
||||
title: str
|
||||
the title of card
|
||||
|
||||
content: str
|
||||
the content of card
|
||||
|
||||
text: str
|
||||
the text of push button
|
||||
|
||||
parent: QWidget
|
||||
parent widget
|
||||
"""
|
||||
super().__init__(icon, title, content, parent)
|
||||
self.linkButton = HyperlinkButton(url, text, self)
|
||||
self.hBoxLayout.addWidget(self.linkButton, 0, Qt.AlignRight)
|
||||
self.hBoxLayout.addSpacing(16)
|
||||
|
||||
|
||||
class ColorPickerButton(QToolButton):
|
||||
""" Color picker button """
|
||||
|
||||
colorChanged = Signal(QColor)
|
||||
|
||||
def __init__(self, color: QColor, title: str, parent=None, enableAlpha=False):
|
||||
super().__init__(parent=parent)
|
||||
self.title = title
|
||||
self.enableAlpha = enableAlpha
|
||||
self.setFixedSize(96, 32)
|
||||
self.setAttribute(Qt.WA_TranslucentBackground)
|
||||
|
||||
self.setColor(color)
|
||||
self.setCursor(Qt.PointingHandCursor)
|
||||
self.clicked.connect(self.__showColorDialog)
|
||||
|
||||
def __showColorDialog(self):
|
||||
""" show color dialog """
|
||||
w = ColorDialog(self.color, self.tr(
|
||||
'Choose ')+self.title, self.window(), self.enableAlpha)
|
||||
w.colorChanged.connect(self.__onColorChanged)
|
||||
w.exec()
|
||||
|
||||
def __onColorChanged(self, color):
|
||||
""" color changed slot """
|
||||
self.setColor(color)
|
||||
self.colorChanged.emit(color)
|
||||
|
||||
def setColor(self, color):
|
||||
""" set color """
|
||||
self.color = QColor(color)
|
||||
self.update()
|
||||
|
||||
def paintEvent(self, e):
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHints(QPainter.Antialiasing)
|
||||
pc = QColor(255, 255, 255, 10) if isDarkTheme() else QColor(234, 234, 234)
|
||||
painter.setPen(pc)
|
||||
|
||||
color = QColor(self.color)
|
||||
if not self.enableAlpha:
|
||||
color.setAlpha(255)
|
||||
|
||||
painter.setBrush(color)
|
||||
painter.drawRoundedRect(self.rect().adjusted(1, 1, -1, -1), 5, 5)
|
||||
|
||||
|
||||
class ColorSettingCard(SettingCard):
|
||||
""" Setting card with color picker """
|
||||
|
||||
colorChanged = Signal(QColor)
|
||||
|
||||
def __init__(self, configItem, icon: Union[str, QIcon, FluentIconBase],
|
||||
title: str, content: str = None, parent=None, enableAlpha=False):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
configItem: RangeConfigItem
|
||||
configuration item operated by the card
|
||||
|
||||
icon: str | QIcon | FluentIconBase
|
||||
the icon to be drawn
|
||||
|
||||
title: str
|
||||
the title of card
|
||||
|
||||
content: str
|
||||
the content of card
|
||||
|
||||
parent: QWidget
|
||||
parent widget
|
||||
|
||||
enableAlpha: bool
|
||||
whether to enable the alpha channel
|
||||
"""
|
||||
super().__init__(icon, title, content, parent)
|
||||
self.configItem = configItem
|
||||
self.colorPicker = ColorPickerButton(
|
||||
qconfig.get(configItem), title, self, enableAlpha)
|
||||
self.hBoxLayout.addWidget(self.colorPicker, 0, Qt.AlignRight)
|
||||
self.hBoxLayout.addSpacing(16)
|
||||
self.colorPicker.colorChanged.connect(self.__onColorChanged)
|
||||
configItem.valueChanged.connect(self.setValue)
|
||||
|
||||
def __onColorChanged(self, color: QColor):
|
||||
qconfig.set(self.configItem, color)
|
||||
self.colorChanged.emit(color)
|
||||
|
||||
def setValue(self, color: QColor):
|
||||
self.colorPicker.setColor(color)
|
||||
qconfig.set(self.configItem, color)
|
||||
|
||||
|
||||
class ComboBoxSettingCard(SettingCard):
|
||||
""" Setting card with a combo box """
|
||||
|
||||
def __init__(self, configItem: OptionsConfigItem, icon: Union[str, QIcon, FluentIconBase], title, content=None, texts=None, parent=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
configItem: OptionsConfigItem
|
||||
configuration item operated by the card
|
||||
|
||||
icon: str | QIcon | FluentIconBase
|
||||
the icon to be drawn
|
||||
|
||||
title: str
|
||||
the title of card
|
||||
|
||||
content: str
|
||||
the content of card
|
||||
|
||||
texts: List[str]
|
||||
the text of items
|
||||
|
||||
parent: QWidget
|
||||
parent widget
|
||||
"""
|
||||
super().__init__(icon, title, content, parent)
|
||||
self.configItem = configItem
|
||||
self.comboBox = ComboBox(self)
|
||||
self.hBoxLayout.addWidget(self.comboBox, 0, Qt.AlignRight)
|
||||
self.hBoxLayout.addSpacing(16)
|
||||
|
||||
self.optionToText = {o: t for o, t in zip(configItem.options, texts)}
|
||||
for text, option in zip(texts, configItem.options):
|
||||
self.comboBox.addItem(text, userData=option)
|
||||
|
||||
self.comboBox.setCurrentText(self.optionToText[qconfig.get(configItem)])
|
||||
self.comboBox.currentIndexChanged.connect(self._onCurrentIndexChanged)
|
||||
configItem.valueChanged.connect(self.setValue)
|
||||
|
||||
def _onCurrentIndexChanged(self, index: int):
|
||||
|
||||
qconfig.set(self.configItem, self.comboBox.itemData(index))
|
||||
|
||||
def setValue(self, value):
|
||||
if value not in self.optionToText:
|
||||
return
|
||||
|
||||
self.comboBox.setCurrentText(self.optionToText[value])
|
||||
qconfig.set(self.configItem, value)
|
||||
48
qfluentwidgets/components/settings/setting_card_group.py
Normal file
48
qfluentwidgets/components/settings/setting_card_group.py
Normal file
@ -0,0 +1,48 @@
|
||||
# coding:utf-8
|
||||
from typing import List
|
||||
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtWidgets import QWidget, QLabel, QVBoxLayout
|
||||
|
||||
from ...common.style_sheet import FluentStyleSheet
|
||||
from ...common.font import setFont
|
||||
from ..layout.expand_layout import ExpandLayout
|
||||
|
||||
|
||||
class SettingCardGroup(QWidget):
|
||||
""" Setting card group """
|
||||
|
||||
def __init__(self, title: str, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.titleLabel = QLabel(title, self)
|
||||
self.vBoxLayout = QVBoxLayout(self)
|
||||
self.cardLayout = ExpandLayout()
|
||||
|
||||
self.vBoxLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.vBoxLayout.setAlignment(Qt.AlignTop)
|
||||
self.vBoxLayout.setSpacing(0)
|
||||
self.cardLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.cardLayout.setSpacing(2)
|
||||
|
||||
self.vBoxLayout.addWidget(self.titleLabel)
|
||||
self.vBoxLayout.addSpacing(12)
|
||||
self.vBoxLayout.addLayout(self.cardLayout, 1)
|
||||
|
||||
FluentStyleSheet.SETTING_CARD_GROUP.apply(self)
|
||||
setFont(self.titleLabel, 20)
|
||||
self.titleLabel.adjustSize()
|
||||
|
||||
def addSettingCard(self, card: QWidget):
|
||||
""" add setting card to group """
|
||||
card.setParent(self)
|
||||
self.cardLayout.addWidget(card)
|
||||
self.adjustSize()
|
||||
|
||||
def addSettingCards(self, cards: List[QWidget]):
|
||||
""" add setting cards to group """
|
||||
for card in cards:
|
||||
self.addSettingCard(card)
|
||||
|
||||
def adjustSize(self):
|
||||
h = self.cardLayout.heightForWidth(self.width()) + 46
|
||||
return self.resize(self.width(), h)
|
||||
Reference in New Issue
Block a user