提交 1b91a298 编写于 作者: 之一Yo's avatar 之一Yo

添加 `ElevatedCardWidget`

上级 2d6f9dc1
# coding:utf-8
import sys
from pathlib import Path
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout
from qfluentwidgets import (CardWidget, setTheme, Theme, IconWidget, BodyLabel, CaptionLabel, PushButton,
TransparentToolButton, FluentIcon, RoundMenu, Action)
TransparentToolButton, FluentIcon, RoundMenu, Action, ElevatedCardWidget,
ImageLabel, isDarkTheme, FlowLayout, MSFluentTitleBar)
def isWin11():
return sys.platform == 'win32' and sys.getwindowsversion().build >= 22000
if isWin11() :
from qframelesswindow import AcrylicWindow as Window
else:
from qframelesswindow import FramelessWindow as Window
class AppCard(CardWidget):
......@@ -51,23 +63,72 @@ class AppCard(CardWidget):
menu.addAction(Action(FluentIcon.CHAT, '写评论', self))
menu.addAction(Action(FluentIcon.PIN, '固定到任务栏', self))
x = (self.moreButton.width() - menu.sizeHint().width()) // 2 + 10
x = (self.moreButton.width() - menu.width()) // 2 + 10
pos = self.moreButton.mapToGlobal(QPoint(x, self.moreButton.height()))
menu.exec(pos)
class Demo(QWidget):
class EmojiCard(ElevatedCardWidget):
""" Emoji card """
def __init__(self, iconPath: str, parent=None):
super().__init__(parent)
self.iconWidget = ImageLabel(iconPath, self)
self.label = CaptionLabel(Path(iconPath).stem, self)
self.iconWidget.scaledToHeight(68)
self.vBoxLayout = QVBoxLayout(self)
self.vBoxLayout.setAlignment(Qt.AlignCenter)
self.vBoxLayout.addStretch(1)
self.vBoxLayout.addWidget(self.iconWidget, 0, Qt.AlignCenter)
self.vBoxLayout.addStretch(1)
self.vBoxLayout.addWidget(self.label, 0, Qt.AlignHCenter | Qt.AlignBottom)
self.setFixedSize(168, 176)
class Demo1(Window):
def __init__(self):
super().__init__()
# self.setStyleSheet("Demo {background: rgb(39, 39, 39)}")
# setTheme(Theme.DARK)
self.setTitleBar(MSFluentTitleBar(self))
self.setWindowIcon(QIcon(':/qfluentwidgets/images/logo.png'))
self.setWindowTitle('Fluent Emoji gallery')
if isWin11():
self.windowEffect.setMicaEffect(self.winId(), isDarkTheme())
self.flowLayout = FlowLayout(self)
self.resize(580, 680)
self.flowLayout.setSpacing(6)
self.flowLayout.setContentsMargins(30, 60, 30, 30)
self.flowLayout.setAlignment(Qt.AlignVCenter)
for path in Path('./resource').glob('*.png'):
self.addCard(str(path))
def addCard(self, iconPath: str):
card = EmojiCard(iconPath, self)
self.flowLayout.addWidget(card)
class Demo2(Window):
def __init__(self):
super().__init__()
self.setTitleBar(MSFluentTitleBar(self))
self.resize(600, 600)
if isWin11():
self.windowEffect.setMicaEffect(self.winId(), isDarkTheme())
self.vBoxLayout = QVBoxLayout(self)
self.vBoxLayout.setSpacing(6)
self.vBoxLayout.setContentsMargins(30, 30, 30, 30)
self.vBoxLayout.setContentsMargins(30, 60, 30, 30)
self.vBoxLayout.setAlignment(Qt.AlignTop)
suffix = ":/qfluentwidgets/images/controls"
......@@ -90,7 +151,11 @@ if __name__ == '__main__':
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
# setTheme(Theme.DARK)
app = QApplication(sys.argv)
w = Demo()
w.show()
w1 = Demo1()
w1.show()
w2 = Demo2()
w2.show()
app.exec_()
......@@ -4,7 +4,7 @@ from PyQt5.QtDesigner import (QPyDesignerCustomWidgetPlugin, QDesignerFormWindow
QPyDesignerContainerExtension)
from qfluentwidgets import (ScrollArea, SmoothScrollArea, SingleDirectionScrollArea, OpacityAniStackedWidget,
PopUpAniStackedWidget, CardWidget)
PopUpAniStackedWidget, CardWidget, ElevatedCardWidget)
from plugin_base import PluginBase
......@@ -19,7 +19,7 @@ class ContainerPlugin(PluginBase):
class CardWidgetPlugin(ContainerPlugin, QPyDesignerCustomWidgetPlugin):
""" Single direction scroll area plugin """
""" Card widget plugin """
def createWidget(self, parent):
return CardWidget(parent)
......@@ -31,6 +31,19 @@ class CardWidgetPlugin(ContainerPlugin, QPyDesignerCustomWidgetPlugin):
return "CardWidget"
class ElevatedCardWidgetPlugin(ContainerPlugin, QPyDesignerCustomWidgetPlugin):
""" Elevated card widget plugin """
def createWidget(self, parent):
return ElevatedCardWidget(parent)
def icon(self):
return super().icon("CommandBar")
def name(self):
return "ElevatedCardWidget"
class ScrollAreaPluginBase(ContainerPlugin):
""" Scroll area plugin base """
......
# coding: utf-8
from PyQt5.QtCore import QEasingCurve, QEvent, QObject, QPropertyAnimation, pyqtProperty, pyqtSignal
from PyQt5.QtGui import QMouseEvent, QEnterEvent, QColor
from PyQt5.QtWidgets import QWidget, QLineEdit
from PyQt5.QtWidgets import QWidget, QLineEdit, QGraphicsDropShadowEffect
from .config import qconfig
......@@ -178,3 +178,54 @@ class BackgroundColorObject(QObject):
def backgroundColor(self, color: QColor):
self._backgroundColor = color
self.parent().update()
class DropShadowAnimation(QPropertyAnimation):
""" Drop shadow animation """
def __init__(self, parent: QWidget, normalColor=QColor(0, 0, 0, 0), hoverColor=QColor(0, 0, 0, 75)):
super().__init__(parent=parent)
self.normalColor = normalColor
self.hoverColor = hoverColor
self.isHover = False
self.shadowEffect = QGraphicsDropShadowEffect(self)
self.shadowEffect.setColor(self.normalColor)
parent.setGraphicsEffect(self.shadowEffect)
parent.installEventFilter(self)
self.setTargetObject(self.shadowEffect)
self.setPropertyName(b'color')
self.setDuration(150)
def setBlurRadius(self, radius: int):
self.shadowEffect.setBlurRadius(radius)
def setOffset(self, dx: int, dy: int):
self.shadowEffect.setOffset(dx, dy)
def setNormalColor(self, color: QColor):
self.normalColor = color
if not self.isHover:
self.shadowEffect.setColor(color)
def setHoverColor(self, color: QColor):
self.hoverColor = color
if self.isHover:
self.shadowEffect.setColor(color)
def setColor(self, color):
self.shadowEffect.setColor(color)
def eventFilter(self, obj, e):
if obj is self.parent() and self.parent().isEnabled():
if e.type() in [QEvent.Type.Enter]:
self.isHover = True
self.setEndValue(self.hoverColor)
self.start()
elif e.type() in [QEvent.Type.Leave, QEvent.Type.MouseButtonPress]:
self.isHover = False
self.setEndValue(self.normalColor)
self.start()
return super().eventFilter(obj, e)
......@@ -5,7 +5,7 @@ from .button import (DropDownPushButton, DropDownToolButton, PrimaryPushButton,
TogglePushButton, ToggleToolButton, TransparentPushButton, TransparentTogglePushButton,
TransparentToggleToolButton, TransparentDropDownPushButton, TransparentDropDownToolButton,
PillPushButton, PillToolButton)
from .card_widget import CardWidget
from .card_widget import CardWidget, ElevatedCardWidget
from .check_box import CheckBox
from .combo_box import ComboBox, EditableComboBox
from .command_bar import CommandBar, CommandButton, CommandBarView
......
# coding:utf-8
from PyQt5.QtCore import Qt, pyqtSignal, QRectF, pyqtProperty
from PyQt5.QtCore import Qt, pyqtSignal, QRectF, pyqtProperty, QPropertyAnimation, QPoint
from PyQt5.QtGui import QPixmap, QPainter, QColor, QPainterPath
from PyQt5.QtWidgets import QWidget, QFrame
from PyQt5.QtWidgets import QWidget, QFrame, QGraphicsDropShadowEffect
from ...common.style_sheet import isDarkTheme
from ...common.animation import BackgroundAnimationWidget
from ...common.animation import BackgroundAnimationWidget, DropShadowAnimation
class CardWidget(BackgroundAnimationWidget, QFrame):
......@@ -97,3 +97,62 @@ class CardWidget(BackgroundAnimationWidget, QFrame):
painter.drawRoundedRect(rect, r, r)
borderRadius = pyqtProperty(int, getBorderRadius, setBorderRadius)
class ElevatedCardWidget(CardWidget):
""" Card widget with shadow effect """
def __init__(self, parent=None):
super().__init__(parent)
self.shadowAni = DropShadowAnimation(self, hoverColor=QColor(0, 0, 0, 20))
self.shadowAni.setOffset(0, 5)
self.shadowAni.setBlurRadius(38)
self.elevatedAni = QPropertyAnimation(self, b'pos', self)
self.elevatedAni.setDuration(100)
self._originalPos = self.pos()
self.setBorderRadius(8)
def enterEvent(self, e):
super().enterEvent(e)
if self.elevatedAni.state() != QPropertyAnimation.Running:
self._originalPos = self.pos()
self._startElevateAni(self.pos(), self.pos() - QPoint(0, 3))
def leaveEvent(self, e):
super().leaveEvent(e)
self._startElevateAni(self.pos(), self._originalPos)
def mousePressEvent(self, e):
super().mousePressEvent(e)
self._startElevateAni(self.pos(), self._originalPos)
def _startElevateAni(self, start, end):
self.elevatedAni.setStartValue(start)
self.elevatedAni.setEndValue(end)
self.elevatedAni.start()
def _normalBackgroundColor(self):
return QColor(255, 255, 255, 13 if isDarkTheme() else 170)
def _hoverBackgroundColor(self):
return QColor(255, 255, 255, 16) if isDarkTheme() else QColor(255, 255, 255)
def _pressedBackgroundColor(self):
return QColor(255, 255, 255, 6 if isDarkTheme() else 118)
def paintEvent(self, e):
painter = QPainter(self)
painter.setRenderHints(QPainter.Antialiasing)
painter.setBrush(self.backgroundColor)
if isDarkTheme():
painter.setPen(QColor(0, 0, 0, 12))
else:
painter.setPen(QColor(0, 0, 0, 12))
r = self.borderRadius
painter.drawRoundedRect(self.rect().adjusted(1, 1, -1, -1), r, r)
\ No newline at end of file
......@@ -673,7 +673,7 @@ class TabBar(SingleDirectionScrollArea):
if canDraw:
x = item.geometry().right()
y = self.height() / 2 - 8
y = self.height() // 2 - 8
painter.drawLine(x, y, x, y + 16)
def setMovable(self, movable: bool):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册