提交 674c00e1 编写于 作者: 之一Yo's avatar 之一Yo

Merge branch 'PyQt5' into docs

......@@ -2,24 +2,28 @@
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 PyQt5.QtCore import Qt, QPoint, QSize, QUrl
from PyQt5.QtGui import QIcon, QFont, QColor
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, QSizePolicy
from qfluentwidgets import (CardWidget, setTheme, Theme, IconWidget, BodyLabel, CaptionLabel, PushButton,
TransparentToolButton, FluentIcon, RoundMenu, Action, ElevatedCardWidget,
ImageLabel, isDarkTheme, FlowLayout, MSFluentTitleBar)
ImageLabel, isDarkTheme, FlowLayout, MSFluentTitleBar, SimpleCardWidget,
HeaderCardWidget, InfoBarIcon, HyperlinkLabel, HorizontalFlipView,
PrimaryPushButton, TitleLabel, PillPushButton, setFont, SingleDirectionScrollArea,
VerticalSeparator)
def isWin11():
return sys.platform == 'win32' and sys.getwindowsversion().build >= 22000
if isWin11() :
if isWin11():
from qframelesswindow import AcrylicWindow as Window
else:
from qframelesswindow import FramelessWindow as Window
class AppCard(CardWidget):
""" App card """
......@@ -83,23 +87,191 @@ class EmojiCard(ElevatedCardWidget):
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.vBoxLayout.addWidget(
self.label, 0, Qt.AlignHCenter | Qt.AlignBottom)
self.setFixedSize(168, 176)
class StatisticsWidget(QWidget):
""" Statistics widget """
def __init__(self, title: str, value: str, parent=None):
super().__init__(parent=parent)
self.titleLabel = CaptionLabel(title, self)
self.valueLabel = BodyLabel(value, self)
self.vBoxLayout = QVBoxLayout(self)
self.vBoxLayout.setContentsMargins(16, 0, 16, 0)
self.vBoxLayout.addWidget(self.valueLabel, 0, Qt.AlignTop)
self.vBoxLayout.addWidget(self.titleLabel, 0, Qt.AlignBottom)
setFont(self.valueLabel, 18, QFont.DemiBold)
self.titleLabel.setTextColor(QColor(96, 96, 96), QColor(206, 206, 206))
class AppInfoCard(SimpleCardWidget):
""" App information card """
def __init__(self, parent=None):
super().__init__(parent)
self.iconLabel = ImageLabel(":/qfluentwidgets/images/logo.png", self)
self.iconLabel.setBorderRadius(8, 8, 8, 8)
self.iconLabel.scaledToWidth(120)
self.nameLabel = TitleLabel('QFluentWidgets', self)
self.installButton = PrimaryPushButton('安装', self)
self.companyLabel = HyperlinkLabel(
QUrl('https://github.com/zhiyiYo/PyQt-Fluent-Widgets'), 'Shokokawaii Inc.', self)
self.installButton.setFixedWidth(160)
self.scoreWidget = StatisticsWidget('平均', '5.0', self)
self.separator = VerticalSeparator(self)
self.commentWidget = StatisticsWidget('评论数', '3K', self)
self.descriptionLabel = BodyLabel(
'PyQt-Fluent-Widgets 是一个基于 PyQt/PySide 的 Fluent Design 风格组件库,包含许多美观实用的组件,支持亮暗主题无缝切换和自定义主题色,帮助开发者快速实现美观优雅的现代化界面。', self)
self.descriptionLabel.setWordWrap(True)
self.tagButton = PillPushButton('组件库', self)
self.tagButton.setCheckable(False)
setFont(self.tagButton, 12)
self.tagButton.setFixedSize(80, 32)
self.shareButton = TransparentToolButton(FluentIcon.SHARE, self)
self.shareButton.setFixedSize(32, 32)
self.shareButton.setIconSize(QSize(14, 14))
self.hBoxLayout = QHBoxLayout(self)
self.vBoxLayout = QVBoxLayout()
self.topLayout = QHBoxLayout()
self.statisticsLayout = QHBoxLayout()
self.buttonLayout = QHBoxLayout()
self.initLayout()
def initLayout(self):
self.hBoxLayout.setSpacing(30)
self.hBoxLayout.setContentsMargins(34, 24, 24, 24)
self.hBoxLayout.addWidget(self.iconLabel)
self.hBoxLayout.addLayout(self.vBoxLayout)
self.vBoxLayout.setContentsMargins(0, 0, 0, 0)
self.vBoxLayout.setSpacing(0)
# name label and install button
self.vBoxLayout.addLayout(self.topLayout)
self.topLayout.setContentsMargins(0, 0, 0, 0)
self.topLayout.addWidget(self.nameLabel)
self.topLayout.addWidget(self.installButton, 0, Qt.AlignRight)
# company label
self.vBoxLayout.addSpacing(3)
self.vBoxLayout.addWidget(self.companyLabel)
# statistics widgets
self.vBoxLayout.addSpacing(20)
self.vBoxLayout.addLayout(self.statisticsLayout)
self.statisticsLayout.setContentsMargins(0, 0, 0, 0)
self.statisticsLayout.setSpacing(10)
self.statisticsLayout.addWidget(self.scoreWidget)
self.statisticsLayout.addWidget(self.separator)
self.statisticsLayout.addWidget(self.commentWidget)
self.statisticsLayout.setAlignment(Qt.AlignLeft)
# description label
self.vBoxLayout.addSpacing(20)
self.vBoxLayout.addWidget(self.descriptionLabel)
# button
self.vBoxLayout.addSpacing(12)
self.buttonLayout.setContentsMargins(0, 0, 0, 0)
self.vBoxLayout.addLayout(self.buttonLayout)
self.buttonLayout.addWidget(self.tagButton, 0, Qt.AlignLeft)
self.buttonLayout.addWidget(self.shareButton, 0, Qt.AlignRight)
class GalleryCard(HeaderCardWidget):
""" Gallery card """
def __init__(self, parent=None):
super().__init__(parent)
self.setTitle('屏幕截图')
self.flipView = HorizontalFlipView(self)
self.expandButton = TransparentToolButton(
FluentIcon.CHEVRON_RIGHT_MED, self)
self.expandButton.setFixedSize(32, 32)
self.expandButton.setIconSize(QSize(12, 12))
self.flipView.addImages([
'resource/shoko1.jpg', 'resource/shoko2.jpg',
'resource/shoko3.jpg', 'resource/shoko4.jpg',
])
self.flipView.setBorderRadius(8)
self.flipView.setSpacing(10)
self.headerLayout.addWidget(self.expandButton, 0, Qt.AlignRight)
self.viewLayout.addWidget(self.flipView)
class DescriptionCard(HeaderCardWidget):
""" Description card """
def __init__(self, parent=None):
super().__init__(parent)
self.descriptionLabel = BodyLabel(
'PyQt-Fluent-Widgets 是一个基于 PyQt/PySide 的 Fluent Design 风格组件库,包含许多美观实用的组件,支持亮暗主题无缝切换和自定义主题色,搭配所见即所得的 QtDesigner,帮助开发者快速实现美观优雅的现代化界面。', self)
self.descriptionLabel.setWordWrap(True)
self.viewLayout.addWidget(self.descriptionLabel)
self.setTitle('描述')
class Demo1(Window):
class SystemRequirementCard(HeaderCardWidget):
""" System requirements card """
def __init__(self, parent=None):
super().__init__(parent)
self.setTitle('系统要求')
self.infoLabel = BodyLabel('此产品适用于你的设备。具有复选标记的项目符合开发人员的系统要求。', self)
self.successIcon = IconWidget(InfoBarIcon.SUCCESS, self)
self.detailButton = HyperlinkLabel('详细信息', self)
self.vBoxLayout = QVBoxLayout()
self.hBoxLayout = QHBoxLayout()
self.successIcon.setFixedSize(16, 16)
self.hBoxLayout.setSpacing(10)
self.vBoxLayout.setSpacing(16)
self.hBoxLayout.setContentsMargins(0, 0, 0, 0)
self.vBoxLayout.setContentsMargins(0, 0, 0, 0)
self.hBoxLayout.addWidget(self.successIcon)
self.hBoxLayout.addWidget(self.infoLabel)
self.vBoxLayout.addLayout(self.hBoxLayout)
self.vBoxLayout.addWidget(self.detailButton)
self.viewLayout.addLayout(self.vBoxLayout)
class MicaWindow(Window):
def __init__(self):
super().__init__()
self.setTitleBar(MSFluentTitleBar(self))
self.setWindowIcon(QIcon(':/qfluentwidgets/images/logo.png'))
self.setWindowTitle('Fluent Emoji gallery')
if isWin11():
self.windowEffect.setMicaEffect(self.winId(), isDarkTheme())
class Demo1(MicaWindow):
def __init__(self):
super().__init__()
self.setWindowIcon(QIcon(':/qfluentwidgets/images/logo.png'))
self.setWindowTitle('Fluent Emoji gallery')
self.flowLayout = FlowLayout(self)
self.resize(580, 680)
......@@ -115,16 +287,12 @@ class Demo1(Window):
self.flowLayout.addWidget(card)
class Demo2(Window):
class Demo2(MicaWindow):
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)
......@@ -132,22 +300,66 @@ class Demo2(Window):
self.vBoxLayout.setAlignment(Qt.AlignTop)
suffix = ":/qfluentwidgets/images/controls"
self.addCard(f":/qfluentwidgets/images/logo.png", "PyQt-Fluent-Widgets", 'Shokokawaii Inc.')
self.addCard(f"{suffix}/TitleBar.png", "PyQt-Frameless-Window", 'Shokokawaii Inc.')
self.addCard(f"{suffix}/RatingControl.png", "反馈中心", 'Microsoft Corporation')
self.addCard(f"{suffix}/Checkbox.png", "Microsoft 使用技巧", 'Microsoft Corporation')
self.addCard(f":/qfluentwidgets/images/logo.png",
"PyQt-Fluent-Widgets", 'Shokokawaii Inc.')
self.addCard(f"{suffix}/TitleBar.png",
"PyQt-Frameless-Window", 'Shokokawaii Inc.')
self.addCard(f"{suffix}/RatingControl.png",
"反馈中心", 'Microsoft Corporation')
self.addCard(f"{suffix}/Checkbox.png",
"Microsoft 使用技巧", 'Microsoft Corporation')
self.addCard(f"{suffix}/Pivot.png", "MSN 天气", 'Microsoft Corporation')
self.addCard(f"{suffix}/MediaPlayerElement.png", "电影和电视", 'Microsoft Corporation')
self.addCard(f"{suffix}/PersonPicture.png", "照片", 'Microsoft Corporation')
self.addCard(f"{suffix}/MediaPlayerElement.png",
"电影和电视", 'Microsoft Corporation')
self.addCard(f"{suffix}/PersonPicture.png",
"照片", 'Microsoft Corporation')
def addCard(self, icon, title, content):
card = AppCard(icon, title, content, self)
self.vBoxLayout.addWidget(card, alignment=Qt.AlignTop)
class Demo3(MicaWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('PyQt-Fluent-Widgets')
self.setWindowIcon(QIcon(':/qfluentwidgets/images/logo.png'))
self.hBoxLayout = QHBoxLayout(self)
self.scrollArea = SingleDirectionScrollArea(self)
self.view = QWidget(self)
self.vBoxLayout = QVBoxLayout(self.view)
self.appCard = AppInfoCard(self)
self.galleryCard = GalleryCard(self)
self.descriptionCard = DescriptionCard(self)
self.systemCard = SystemRequirementCard(self)
self.scrollArea.setWidget(self.view)
self.scrollArea.setWidgetResizable(True)
self.hBoxLayout.setContentsMargins(0, 48, 0, 0)
self.hBoxLayout.addWidget(self.scrollArea)
self.vBoxLayout.setSpacing(10)
self.vBoxLayout.setContentsMargins(30, 0, 30, 30)
self.vBoxLayout.addWidget(self.appCard, 0, Qt.AlignTop)
self.vBoxLayout.addWidget(self.galleryCard, 0, Qt.AlignTop)
self.vBoxLayout.addWidget(self.descriptionCard, 0, Qt.AlignTop)
self.vBoxLayout.addWidget(self.systemCard, 0, Qt.AlignTop)
self.resize(780, 800)
self.titleBar.raise_()
self.scrollArea.setStyleSheet(
"QScrollArea {border: none; background:transparent}")
self.view.setStyleSheet('QWidget {background:transparent}')
if __name__ == '__main__':
# enable dpi scale
QApplication.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
QApplication.setHighDpiScaleFactorRoundingPolicy(
Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
......@@ -158,4 +370,6 @@ if __name__ == '__main__':
w1.show()
w2 = Demo2()
w2.show()
w3 = Demo3()
w3.show()
app.exec_()
......@@ -54,6 +54,11 @@ class Demo(QWidget):
self.flipView.addImages([str(i) for i in Path('./resource').glob('*')])
self.pager.setPageNumber(self.flipView.count())
# adjust border radius
# self.flipView.setBorderRadius(15)
# self.flipView.setFixedSize(QSize(710, 270))
# self.flipView.setSpacing(15)
self.pager.currentIndexChanged.connect(self.flipView.setCurrentIndex)
self.flipView.currentIndexChanged.connect(self.pager.setCurrentIndex)
......
# coding:utf-8
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout
from qfluentwidgets import (CaptionLabel, BodyLabel, StrongBodyLabel, SubtitleLabel, TitleLabel,
LargeTitleLabel, DisplayLabel, setTheme, Theme)
LargeTitleLabel, DisplayLabel, setTheme, Theme, HyperlinkLabel, setFont)
class Demo(QWidget):
......@@ -15,6 +15,12 @@ class Demo(QWidget):
self.vBoxLayout.setContentsMargins(30, 30, 30, 30)
self.vBoxLayout.setSpacing(20)
self.hyperlinkLabel = HyperlinkLabel(QUrl('https://github.com/'), 'GitHub')
# self.hyperlinkLabel.setUrl('https://github.com/zhiyiYo/QMaterialWidgets')
# self.hyperlinkLabel.setUnderlineVisible(True)
# setFont(self.hyperlinkLabel, 18)
self.vBoxLayout.addWidget(self.hyperlinkLabel)
self.vBoxLayout.addWidget(CaptionLabel('Caption'))
self.vBoxLayout.addWidget(BodyLabel('Body'))
self.vBoxLayout.addWidget(StrongBodyLabel('Body Strong'))
......@@ -24,7 +30,7 @@ class Demo(QWidget):
self.vBoxLayout.addWidget(DisplayLabel('Display'))
# customize text color
# self.vBoxLayout.itemAt(0).widget().setTextColor('#009faa', '#009faa')
# self.vBoxLayout.itemAt(1).widget().setTextColor('#009faa', '#009faa')
# setTheme(Theme.DARK)
# self.setStyleSheet("QWidget{background: rgb(32, 32, 32)}")
......
......@@ -4,7 +4,8 @@ from PyQt5.QtDesigner import (QPyDesignerCustomWidgetPlugin, QDesignerFormWindow
QPyDesignerContainerExtension)
from qfluentwidgets import (ScrollArea, SmoothScrollArea, SingleDirectionScrollArea, OpacityAniStackedWidget,
PopUpAniStackedWidget, CardWidget, ElevatedCardWidget)
PopUpAniStackedWidget, CardWidget, ElevatedCardWidget, SimpleCardWidget,
HeaderCardWidget)
from plugin_base import PluginBase
......@@ -44,6 +45,32 @@ class ElevatedCardWidgetPlugin(ContainerPlugin, QPyDesignerCustomWidgetPlugin):
return "ElevatedCardWidget"
class SimpleCardWidgetPlugin(ContainerPlugin, QPyDesignerCustomWidgetPlugin):
""" Simple card widget plugin """
def createWidget(self, parent):
return SimpleCardWidget(parent)
def icon(self):
return super().icon("CommandBar")
def name(self):
return "SimpleCardWidget"
class HeaderCardWidgetPlugin(ContainerPlugin, QPyDesignerCustomWidgetPlugin):
""" Header card widget plugin """
def createWidget(self, parent):
return HeaderCardWidget(parent)
def icon(self):
return super().icon("CommandBar")
def name(self):
return "HeaderCardWidget"
class ScrollAreaPluginBase(ContainerPlugin):
""" Scroll area plugin base """
......
......@@ -3,7 +3,7 @@ from PyQt5.QtCore import Qt
from PyQt5.QtDesigner import QPyDesignerCustomWidgetPlugin
from qfluentwidgets import (BodyLabel, CaptionLabel, StrongBodyLabel, SubtitleLabel, TitleLabel, LargeTitleLabel,
DisplayLabel, ImageLabel, AvatarWidget)
DisplayLabel, ImageLabel, AvatarWidget, HyperlinkLabel)
from plugin_base import PluginBase
......@@ -114,6 +114,19 @@ class DisplayLabelPlugin(LabelPlugin, QPyDesignerCustomWidgetPlugin):
return "DisplayLabel"
class DisplayLabelPlugin(LabelPlugin, QPyDesignerCustomWidgetPlugin):
""" Hyperlink label plugin """
def createWidget(self, parent):
return HyperlinkLabel(parent)
def icon(self):
return super().icon("HyperlinkButton")
def name(self):
return "HyperlinkLabel"
class ImageLabelPlugin(LabelPlugin, QPyDesignerCustomWidgetPlugin):
""" Image label plugin """
......
......@@ -12,7 +12,7 @@ Examples are available at https://github.com/zhiyiYo/PyQt-Fluent-Widgets/tree/ma
:license: GPLv3, see LICENSE for more details.
"""
__version__ = "1.1.5"
__version__ = "1.1.7"
from .components import *
from .common import *
......
<?xml version="1.0" encoding="utf-8"?>
<svg id="" width="16" height="16" style="width:16px;height:16px;" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 2048" enable-background="new 0 0 2048 2048" xml:space="preserve">
<path fill="#000" transform="translate(0, 450)" d="M0 128.94 q0 -26.99 10.49 -50.23 q10.49 -23.24 27.73 -40.48 q17.24 -17.24 40.48 -27.73 q23.24 -10.49 50.23 -10.49 q28.48 0 49.47 9.74 q20.99 9.74 40.48 29.23 l805.11 805.11 l805.11 -805.11 q38.98 -38.98 89.95 -38.98 q26.99 0 50.23 10.49 q23.24 10.49 40.48 27.73 q17.24 17.24 27.74 40.48 q10.49 23.24 10.49 50.23 q0 52.47 -37.48 89.95 l-896.56 896.57 q-37.49 37.48 -89.96 37.48 q-52.47 0 -89.96 -37.48 l-896.56 -896.57 q-37.48 -37.48 -37.48 -89.95 Z"/>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<svg id="" width="16" height="16" style="width:16px;height:16px;" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 2048" enable-background="new 0 0 2048 2048" xml:space="preserve">
<path fill="#ffffff" transform="translate(0, 450)" d="M0 128.94 q0 -26.99 10.49 -50.23 q10.49 -23.24 27.73 -40.48 q17.24 -17.24 40.48 -27.73 q23.24 -10.49 50.23 -10.49 q28.48 0 49.47 9.74 q20.99 9.74 40.48 29.23 l805.11 805.11 l805.11 -805.11 q38.98 -38.98 89.95 -38.98 q26.99 0 50.23 10.49 q23.24 10.49 40.48 27.73 q17.24 17.24 27.74 40.48 q10.49 23.24 10.49 50.23 q0 52.47 -37.48 89.95 l-896.56 896.57 q-37.49 37.48 -89.96 37.48 q-52.47 0 -89.96 -37.48 l-896.56 -896.57 q-37.48 -37.48 -37.48 -89.95 Z"/>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<svg id="" width="16" height="16" style="width:16px;height:16px;" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 2048" enable-background="new 0 0 2048 2048" xml:space="preserve">
<path fill="#000" d="M448.28 1919.06 q0 -52.47 37.48 -89.95 l805.11 -805.11 l-805.11 -805.11 q-37.48 -37.48 -37.48 -89.95 q0 -52.48 36.74 -90.71 q36.74 -38.23 90.71 -38.23 q52.47 0 89.95 37.48 l896.57 896.56 q37.48 37.49 37.48 89.96 q0 52.47 -37.48 89.96 l-896.57 896.56 q-37.48 37.48 -89.95 37.48 q-53.97 0 -90.71 -38.23 q-36.74 -38.23 -36.74 -90.71 Z"/>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<svg id="" width="16" height="16" style="width:16px;height:16px;" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 2048" enable-background="new 0 0 2048 2048" xml:space="preserve">
<path fill="#ffffff" d="M448.28 1919.06 q0 -52.47 37.48 -89.95 l805.11 -805.11 l-805.11 -805.11 q-37.48 -37.48 -37.48 -89.95 q0 -52.48 36.74 -90.71 q36.74 -38.23 90.71 -38.23 q52.47 0 89.95 37.48 l896.57 896.56 q37.48 37.49 37.48 89.96 q0 52.47 -37.48 89.96 l-896.57 896.56 q-37.48 37.48 -89.95 37.48 q-53.97 0 -90.71 -38.23 q-36.74 -38.23 -36.74 -90.71 Z"/>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 16 16">
<g>
<path id="path1" transform="rotate(0,8,8) translate(1.42857142857143,0) scale(0.19047619047619,0.19047619047619) " fill="#000000" d="M33,12L34.13671875,12.22265625 35.109375,12.890625 68.109375,45.890625 68.77734375,46.8632850646973 69,48 68.77734375,49.13671875 68.109375,50.109375 35.109375,83.109375 34.13671875,83.77734375 33,84 31.86328125,83.77734375 30.890625,83.109375 30.2226543426514,82.13671875 30,81 30.2226543426514,79.86328125 30.890625,78.890625 61.734375,48 30.890625,17.109375 30.2226543426514,16.13671875 30,15 30.2226543426514,13.86328125 30.890625,12.890625 31.86328125,12.22265625 33,12z" />
<path id="path1" transform="rotate(0,8,8) translate(-1.4, -1.4) scale(0.19047619047619,0.19047619047619) " fill="#000000" d="M33,12L34.13671875,12.22265625 35.109375,12.890625 68.109375,45.890625 68.77734375,46.8632850646973 69,48 68.77734375,49.13671875 68.109375,50.109375 35.109375,83.109375 34.13671875,83.77734375 33,84 31.86328125,83.77734375 30.890625,83.109375 30.2226543426514,82.13671875 30,81 30.2226543426514,79.86328125 30.890625,78.890625 61.734375,48 30.890625,17.109375 30.2226543426514,16.13671875 30,15 30.2226543426514,13.86328125 30.890625,12.890625 31.86328125,12.22265625 33,12z" />
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 16 16">
<g>
<path id="path1" transform="rotate(0,8,8) translate(1.42857142857143,0) scale(0.19047619047619,0.19047619047619) " fill="#FFFFFF" d="M33,12L34.13671875,12.22265625 35.109375,12.890625 68.109375,45.890625 68.77734375,46.8632850646973 69,48 68.77734375,49.13671875 68.109375,50.109375 35.109375,83.109375 34.13671875,83.77734375 33,84 31.86328125,83.77734375 30.890625,83.109375 30.2226543426514,82.13671875 30,81 30.2226543426514,79.86328125 30.890625,78.890625 61.734375,48 30.890625,17.109375 30.2226543426514,16.13671875 30,15 30.2226543426514,13.86328125 30.890625,12.890625 31.86328125,12.22265625 33,12z" />
<path id="path1" transform="rotate(0,8,8) translate(-1.4,-1.4) scale(0.19047619047619,0.19047619047619) " fill="#FFFFFF" d="M33,12L34.13671875,12.22265625 35.109375,12.890625 68.109375,45.890625 68.77734375,46.8632850646973 69,48 68.77734375,49.13671875 68.109375,50.109375 35.109375,83.109375 34.13671875,83.77734375 33,84 31.86328125,83.77734375 30.890625,83.109375 30.2226543426514,82.13671875 30,81 30.2226543426514,79.86328125 30.890625,78.890625 61.734375,48 30.890625,17.109375 30.2226543426514,16.13671875 30,15 30.2226543426514,13.86328125 30.890625,12.890625 31.86328125,12.22265625 33,12z" />
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<svg id="" width="16" height="16" style="width:16px;height:16px;" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 2048" enable-background="new 0 0 2048 2048" xml:space="preserve">
<path fill="#000" d="M302.55 2048 q-45.41 0 -85.15 -17.03 q-39.73 -17.03 -69.82 -46.54 q-30.08 -29.52 -47.11 -69.25 q-17.03 -39.74 -17.03 -85.15 l0 -1612.06 q0 -45.41 17.03 -85.15 q17.03 -39.73 46.54 -69.25 q29.52 -29.52 69.25 -46.55 q39.74 -17.03 85.15 -17.03 q27.25 0 54.49 6.81 q27.25 6.81 51.09 20.44 l1446.31 806.03 q52.23 29.51 81.75 80.03 q29.51 50.52 29.51 110.69 q0 61.3 -28.95 111.26 q-28.95 49.95 -82.31 79.46 l-1445.18 806.03 q-23.84 13.63 -51.09 20.44 q-27.24 6.81 -54.48 6.81 Z"/>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<svg id="" width="16" height="16" style="width:16px;height:16px;" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 2048" enable-background="new 0 0 2048 2048" xml:space="preserve">
<path fill="#ffffff" d="M302.55 2048 q-45.41 0 -85.15 -17.03 q-39.73 -17.03 -69.82 -46.54 q-30.08 -29.52 -47.11 -69.25 q-17.03 -39.74 -17.03 -85.15 l0 -1612.06 q0 -45.41 17.03 -85.15 q17.03 -39.73 46.54 -69.25 q29.52 -29.52 69.25 -46.55 q39.74 -17.03 85.15 -17.03 q27.25 0 54.49 6.81 q27.25 6.81 51.09 20.44 l1446.31 806.03 q52.23 29.51 81.75 80.03 q29.51 50.52 29.51 110.69 q0 61.3 -28.95 111.26 q-28.95 49.95 -82.31 79.46 l-1445.18 806.03 q-23.84 13.63 -51.09 20.44 q-27.24 6.81 -54.48 6.81 Z"/>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<svg id="" width="16" height="16" style="width:16px;height:16px;" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 2048" enable-background="new 0 0 2048 2048" xml:space="preserve">
<path fill="#000" d="M302.55 2048 q-45.41 0 -85.15 -17.03 q-39.73 -17.03 -69.82 -46.54 q-30.08 -29.52 -47.11 -69.25 q-17.03 -39.74 -17.03 -85.15 l0 -1612.06 q0 -45.41 17.03 -85.15 q17.03 -39.73 46.54 -69.25 q29.52 -29.52 69.25 -46.55 q39.74 -17.03 85.15 -17.03 q27.25 0 54.49 6.81 q27.25 6.81 51.09 20.44 l1446.31 806.03 q52.23 29.51 81.75 80.6 q29.51 51.09 29.51 110.12 q0 60.17 -28.95 110.69 q-28.95 50.52 -82.31 80.03 l-1445.18 806.03 q-23.84 13.63 -51.09 20.44 q-27.24 6.81 -54.48 6.81 ZM1819.25 1024 q0 -19.3 -10.22 -36.89 q-10.22 -17.6 -27.25 -26.68 l-1445.18 -806.04 q-15.89 -9.08 -35.19 -9.08 q-29.52 0 -51.09 21.57 q-21.57 21.57 -21.57 51.09 l0 1612.06 q0 29.52 21.57 51.09 q21.57 21.57 51.09 21.57 q19.3 0 35.19 -9.08 l1445.18 -806.04 q17.03 -9.08 27.25 -26.67 q10.22 -17.6 10.22 -36.89 Z"/>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<svg id="" width="16" height="16" style="width:16px;height:16px;" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 2048" enable-background="new 0 0 2048 2048" xml:space="preserve">
<path fill="#ffffff" d="M302.55 2048 q-45.41 0 -85.15 -17.03 q-39.73 -17.03 -69.82 -46.54 q-30.08 -29.52 -47.11 -69.25 q-17.03 -39.74 -17.03 -85.15 l0 -1612.06 q0 -45.41 17.03 -85.15 q17.03 -39.73 46.54 -69.25 q29.52 -29.52 69.25 -46.55 q39.74 -17.03 85.15 -17.03 q27.25 0 54.49 6.81 q27.25 6.81 51.09 20.44 l1446.31 806.03 q52.23 29.51 81.75 80.6 q29.51 51.09 29.51 110.12 q0 60.17 -28.95 110.69 q-28.95 50.52 -82.31 80.03 l-1445.18 806.03 q-23.84 13.63 -51.09 20.44 q-27.24 6.81 -54.48 6.81 ZM1819.25 1024 q0 -19.3 -10.22 -36.89 q-10.22 -17.6 -27.25 -26.68 l-1445.18 -806.04 q-15.89 -9.08 -35.19 -9.08 q-29.52 0 -51.09 21.57 q-21.57 21.57 -21.57 51.09 l0 1612.06 q0 29.52 21.57 51.09 q21.57 21.57 51.09 21.57 q19.3 0 35.19 -9.08 l1445.18 -806.04 q17.03 -9.08 27.25 -26.67 q10.22 -17.6 10.22 -36.89 Z"/>
</svg>
\ No newline at end of file
HeaderCardWidget #headerLabel {
color: white;
}
HeaderCardWidget > #headerView,
HeaderCardWidget > #view {
background-color: transparent;
}
\ No newline at end of file
HyperlinkLabel {
color: --ThemeColorPrimary;
border: none;
background-color: transparent;
text-align: left;
padding: 0;
margin: 0;
}
HyperlinkLabel[underline=true] {
text-decoration: underline;
}
HyperlinkLabel[underline=false] {
text-decoration: none;
}
HyperlinkLabel:hover {
color: --ThemeColorDark1;
}
HyperlinkLabel:pressed {
color: --ThemeColorLight1;
}
\ No newline at end of file
HeaderCardWidget #headerLabel {
color: black;
}
HeaderCardWidget > #headerView,
HeaderCardWidget > #view {
background-color: transparent;
}
\ No newline at end of file
HyperlinkLabel {
color: --ThemeColorPrimary;
border: none;
background-color: transparent;
text-align: left;
padding: 0;
margin: 0;
}
HyperlinkLabel[underline=true] {
text-decoration: underline;
}
HyperlinkLabel[underline=false] {
text-decoration: none;
}
HyperlinkLabel:hover {
color: --ThemeColorDark1;
}
HyperlinkLabel:pressed {
color: --ThemeColorLight1;
}
\ No newline at end of file
此差异已折叠。
......@@ -332,6 +332,14 @@
<file>images/icons/RightArrow_black.svg</file>
<file>images/icons/SearchMirror_white.svg</file>
<file>images/icons/SearchMirror_black.svg</file>
<file>images/icons/ChevronRightMed_white.svg</file>
<file>images/icons/ChevronRightMed_black.svg</file>
<file>images/icons/ChevronDownMed_white.svg</file>
<file>images/icons/ChevronDownMed_black.svg</file>
<file>images/icons/Play_white.svg</file>
<file>images/icons/Play_black.svg</file>
<file>images/icons/PlaySolid_white.svg</file>
<file>images/icons/PlaySolid_black.svg</file>
<file>images/acrylic/noise.png</file>
<file>images/folder_list_dialog/Close_white.png</file>
......@@ -394,6 +402,8 @@
<file>qss/dark/tab_view.qss</file>
<file>qss/dark/pips_pager.qss</file>
<file>qss/dark/flip_view.qss</file>
<file>qss/dark/label.qss</file>
<file>qss/dark/card_widget.qss</file>
<file>qss/light/color_dialog.qss</file>
<file>qss/light/dialog.qss</file>
......@@ -426,6 +436,8 @@
<file>qss/light/tab_view.qss</file>
<file>qss/light/pips_pager.qss</file>
<file>qss/light/flip_view.qss</file>
<file>qss/light/label.qss</file>
<file>qss/light/card_widget.qss</file>
<file>i18n/qfluentwidgets.zh_CN.qm</file>
<file>i18n/qfluentwidgets.zh_HK.qm</file>
......
......@@ -268,6 +268,7 @@ class FluentIcon(FluentIconBase, Enum):
MENU = "Menu"
MORE = "More"
MOVE = "Move"
PLAY = "Play"
SAVE = "Save"
SEND = "Send"
SYNC = "Sync"
......@@ -356,6 +357,7 @@ class FluentIcon(FluentIconBase, Enum):
LEFT_ARROW = "LeftArrow"
ERASE_TOOL = "EraseTool"
PAGE_RIGHT = "PageRight"
PLAY_SOLID = "PlaySolid"
BOOK_SHELF = "BookShelf"
HIGHTLIGHT = "Highlight"
FOLDER_ADD = "FolderAdd"
......@@ -402,6 +404,8 @@ class FluentIcon(FluentIconBase, Enum):
DEVELOPER_TOOLS = "DeveloperTools"
BACKGROUND_FILL = "BackgroundColor"
CARE_RIGHT_SOLID = "CareRightSolid"
CHEVRON_DOWN_MED = "ChevronDownMed"
CHEVRON_RIGHT_MED = "ChevronRightMed"
EMOJI_TAB_SYMBOLS = "EmojiTabSymbols"
EXPRESSIVE_INPUT_ENTRY = "ExpressiveInputEntry"
......
......@@ -87,6 +87,7 @@ class FluentStyleSheet(StyleSheetBase, Enum):
""" Fluent style sheet """
MENU = "menu"
LABEL = "label"
PIVOT = "pivot"
BUTTON = "button"
DIALOG = "dialog"
......@@ -104,6 +105,7 @@ class FluentStyleSheet(StyleSheetBase, Enum):
INFO_BADGE = "info_badge"
PIPS_PAGER = "pips_pager"
TABLE_VIEW = "table_view"
CARD_WIDGET = "card_widget"
TIME_PICKER = "time_picker"
COLOR_DIALOG = "color_dialog"
SETTING_CARD = "setting_card"
......
......@@ -27,6 +27,8 @@ class FlowLayout(QLayout):
self._aniGroup = QParallelAnimationGroup(self)
self._verticalSpacing = 10
self._horizontalSpacing = 10
self.duration = 300
self.ease = QEasingCurve.Linear
self.needAni = needAni
self.isTight = isTight
......@@ -40,7 +42,8 @@ class FlowLayout(QLayout):
ani = QPropertyAnimation(w, b'geometry')
ani.setEndValue(QRect(QPoint(0, 0), w.size()))
ani.setDuration(300)
ani.setDuration(self.duration)
ani.setEasingCurve(self.ease)
w.setProperty('flowAni', ani)
self._anis.append(ani)
self._aniGroup.addAnimation(ani)
......@@ -59,6 +62,9 @@ class FlowLayout(QLayout):
if not self.needAni:
return
self.duration = duration
self.ease = ease
for ani in self._anis:
ani.setDuration(duration)
ani.setEasingCurve(ease)
......
......@@ -198,6 +198,7 @@ class RangeSettingCard(SettingCard):
qconfig.set(self.configItem, value)
self.valueLabel.setNum(value)
self.valueLabel.adjustSize()
self.slider.setValue(value)
class PushSettingCard(SettingCard):
......
......@@ -5,7 +5,7 @@ from .button import (DropDownPushButton, DropDownToolButton, PrimaryPushButton,
TogglePushButton, ToggleToolButton, TransparentPushButton, TransparentTogglePushButton,
TransparentToggleToolButton, TransparentDropDownPushButton, TransparentDropDownToolButton,
PillPushButton, PillToolButton)
from .card_widget import CardWidget, ElevatedCardWidget
from .card_widget import CardWidget, ElevatedCardWidget, SimpleCardWidget, HeaderCardWidget
from .check_box import CheckBox
from .combo_box import ComboBox, EditableComboBox
from .command_bar import CommandBar, CommandButton, CommandBarView
......@@ -13,7 +13,7 @@ from .flip_view import FlipView, HorizontalFlipView, VerticalFlipView, FlipImage
from .line_edit import LineEdit, TextEdit, PlainTextEdit, LineEditButton, SearchLineEdit
from .icon_widget import IconWidget
from .label import (PixmapLabel, CaptionLabel, StrongBodyLabel, BodyLabel, SubtitleLabel, TitleLabel,
LargeTitleLabel, DisplayLabel, FluentLabelBase, ImageLabel, AvatarWidget)
LargeTitleLabel, DisplayLabel, FluentLabelBase, ImageLabel, AvatarWidget, HyperlinkLabel)
from .list_view import ListWidget, ListView, ListItemDelegate
from .menu import (DWMMenu, LineEditMenu, RoundMenu, MenuAnimationManager, MenuAnimationType, IndicatorMenuItemDelegate,
MenuItemDelegate, ShortcutMenuItemDelegate, CheckableMenu, MenuIndicatorType, SystemTrayMenu,
......@@ -36,4 +36,5 @@ from .scroll_bar import ScrollBar, SmoothScrollBar, SmoothScrollDelegate
from .teaching_tip import TeachingTip, TeachingTipTailPosition, TeachingTipView, PopupTeachingTip
from .flyout import FlyoutView, FlyoutViewBase, Flyout, FlyoutAnimationType, FlyoutAnimationManager
from .tab_view import TabBar, TabItem, TabCloseButtonDisplayMode
from .pips_pager import PipsPager, VerticalPipsPager, HorizontalPipsPager, PipsScrollButtonDisplayMode
\ No newline at end of file
from .pips_pager import PipsPager, VerticalPipsPager, HorizontalPipsPager, PipsScrollButtonDisplayMode
from .separator import HorizontalSeparator, VerticalSeparator
\ No newline at end of file
......@@ -148,7 +148,7 @@ class HyperlinkButton(PushButton):
FluentStyleSheet.BUTTON.apply(self)
self.setCursor(Qt.PointingHandCursor)
setFont(self)
self.clicked.connect(lambda i: QDesktopServices.openUrl(self.getUrl()))
self.clicked.connect(self._onClicked)
@__init__.register
def _(self, url: str, text: str, parent: QWidget = None, icon: Union[QIcon, FluentIconBase, str] = None):
......@@ -163,6 +163,10 @@ class HyperlinkButton(PushButton):
def setUrl(self, url: Union[str, QUrl]):
self._url = QUrl(url)
def _onClicked(self):
if self.getUrl().isValid():
QDesktopServices.openUrl(self.getUrl())
def _drawIcon(self, icon, painter, rect, state=QIcon.Off):
if isinstance(icon, FluentIconBase) and self.isEnabled():
icon = icon.icon(color=themeColor())
......
# coding:utf-8
from PyQt5.QtCore import Qt, pyqtSignal, QRectF, pyqtProperty, QPropertyAnimation, QPoint
from PyQt5.QtGui import QPixmap, QPainter, QColor, QPainterPath
from PyQt5.QtWidgets import QWidget, QFrame, QGraphicsDropShadowEffect
from PyQt5.QtGui import QPixmap, QPainter, QColor, QPainterPath, QFont
from PyQt5.QtWidgets import QWidget, QFrame, QVBoxLayout, QHBoxLayout, QLabel
from ...common.style_sheet import isDarkTheme
from ...common.overload import singledispatchmethod
from ...common.style_sheet import isDarkTheme, FluentStyleSheet
from ...common.animation import BackgroundAnimationWidget, DropShadowAnimation
from ...common.font import setFont
class CardWidget(BackgroundAnimationWidget, QFrame):
......@@ -150,9 +152,94 @@ class ElevatedCardWidget(CardWidget):
painter.setBrush(self.backgroundColor)
if isDarkTheme():
painter.setPen(QColor(0, 0, 0, 36))
painter.setPen(QColor(0, 0, 0, 48))
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
painter.drawRoundedRect(self.rect().adjusted(1, 1, -1, -1), r, r)
class SimpleCardWidget(ElevatedCardWidget):
""" Simple card widget """
def __init__(self, parent=None):
super().__init__(parent)
self.shadowAni.setHoverColor(QColor(0, 0, 0, 0))
def _hoverBackgroundColor(self):
return self._normalBackgroundColor()
def _pressedBackgroundColor(self):
return self._normalBackgroundColor()
def _startElevateAni(self, start, end):
pass
class CardSeparator(QWidget):
""" Card 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(255, 255, 255, 46))
else:
painter.setPen(QColor(0, 0, 0, 12))
painter.drawLine(2, 1, self.width() - 2, 1)
class HeaderCardWidget(SimpleCardWidget):
""" Header card widget """
@singledispatchmethod
def __init__(self, parent=None):
super().__init__(parent)
self.headerView = QWidget(self)
self.headerLabel = QLabel(self)
self.separator = CardSeparator(self)
self.view = QWidget(self)
self.vBoxLayout = QVBoxLayout(self)
self.headerLayout = QHBoxLayout(self.headerView)
self.viewLayout = QHBoxLayout(self.view)
self.headerLayout.addWidget(self.headerLabel)
self.headerLayout.setContentsMargins(24, 0, 16, 0)
self.headerView.setFixedHeight(48)
self.vBoxLayout.setSpacing(0)
self.vBoxLayout.setContentsMargins(0, 0, 0, 0)
self.vBoxLayout.addWidget(self.headerView)
self.vBoxLayout.addWidget(self.separator)
self.vBoxLayout.addWidget(self.view)
self.viewLayout.setContentsMargins(24, 24, 24, 24)
setFont(self.headerLabel, 15, QFont.DemiBold)
self.view.setObjectName('view')
self.headerView.setObjectName('headerView')
self.headerLabel.setObjectName('headerLabel')
FluentStyleSheet.CARD_WIDGET.apply(self)
@__init__.register
def _(self, title: str, parent=None):
self.__init__(parent)
self.setTitle(title)
def getTitle(self):
return self.headerLabel.text()
def setTitle(self, title: str):
self.headerLabel.setText(title)
title = pyqtProperty(str, getTitle, setTitle)
\ No newline at end of file
......@@ -2,8 +2,8 @@
from typing import List, Union
from PyQt5.QtCore import Qt, pyqtSignal, QModelIndex, QSize, pyqtProperty, QRectF, QPropertyAnimation
from PyQt5.QtGui import QPixmap, QPainter, QColor, QImage, QWheelEvent
from PyQt5.QtWidgets import QStyleOptionViewItem, QWidget, QListWidget, QStyledItemDelegate, QListWidgetItem
from PyQt5.QtGui import QPixmap, QPainter, QColor, QImage, QWheelEvent, QPainterPath
from PyQt5.QtWidgets import QStyleOptionViewItem, QListWidget, QStyledItemDelegate, QListWidgetItem
from ...common.overload import singledispatchmethod
from ...common.style_sheet import isDarkTheme, FluentStyleSheet
......@@ -77,10 +77,15 @@ class FlipImageDelegate(QStyledItemDelegate):
def __init__(self, parent=None):
super().__init__(parent)
self.borderRadius = 0
def itemSize(self):
return self.parent().itemSize
def setBorderRadius(self, radius: int):
self.borderRadius = radius
self.parent().viewport().update()
def paint(self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex):
painter.save()
painter.setRenderHints(QPainter.Antialiasing)
......@@ -94,12 +99,17 @@ class FlipImageDelegate(QStyledItemDelegate):
if image is None:
return painter.restore()
image = image.scaled(size * r, Qt.KeepAspectRatio, Qt.SmoothTransformation)
x = option.rect.x() + int((option.rect.width() - size.width()) / 2)
y = option.rect.y() + int((option.rect.height() - size.height()) / 2)
painter.drawImage(QRectF(x, y, size.width(), size.height()), image)
rect = QRectF(x, y, size.width(), size.height())
# clipped path
path = QPainterPath()
path.addRoundedRect(rect, self.borderRadius, self.borderRadius)
image = image.scaled(size * r, Qt.KeepAspectRatio, Qt.SmoothTransformation)
painter.setClipPath(path)
painter.drawImage(rect, image)
painter.restore()
......@@ -132,8 +142,7 @@ class FlipView(QListWidget):
self.scrollBar.setForceHidden(True)
self.setUniformItemSizes(True)
self.setGridSize(self.itemSize)
self.setFixedSize(self.itemSize)
self.setMinimumSize(self.itemSize)
self.setItemDelegate(self.delegate)
self.setMovement(QListWidget.Static)
self.setVerticalScrollMode(self.ScrollPerPixel)
......@@ -167,7 +176,6 @@ class FlipView(QListWidget):
return
self._itemSize = size
self.setGridSize(size)
for i in range(self.count()):
item = self.item(i)
......@@ -179,6 +187,13 @@ class FlipView(QListWidget):
""" get the size of item """
return self._itemSize
def setBorderRadius(self, radius: int):
""" set the border radius of item """
self.delegate.setBorderRadius(radius)
def getBorderRadius(self):
return self.delegate.borderRadius
def scrollPrevious(self):
""" scroll to previous item """
self.setCurrentIndex(self.currentIndex() - 1)
......@@ -219,6 +234,7 @@ class FlipView(QListWidget):
else:
value = self.itemSize.height() * index
value += (2 * index + 1) * self.spacing()
self.scrollBar.scrollTo(value)
def currentIndex(self):
......@@ -243,7 +259,7 @@ class FlipView(QListWidget):
self.addItems([''] * len(images))
for i in range(N, self.count()):
self.setImage(i, images[i - N])
self.setItemImage(i, images[i - N])
if self.currentIndex() < 0:
self._currentIndex = 0
......@@ -315,6 +331,7 @@ class FlipView(QListWidget):
self.scrollPrevious()
itemSize = pyqtProperty(QSize, getItemSize, setItemSize)
borderRadius = pyqtProperty(int, getBorderRadius, setBorderRadius)
class HorizontalFlipView(FlipView):
......
# coding:utf-8
from typing import List, Union
from PyQt5.QtCore import Qt, pyqtProperty, QPoint, pyqtSignal, QSize, QRectF
from PyQt5.QtCore import Qt, pyqtProperty, QPoint, pyqtSignal, QSize, QRectF, QUrl
from PyQt5.QtGui import (QPixmap, QPainter, QPalette, QColor, QFont, QImage, QPainterPath,
QImageReader, QBrush, QMovie)
from PyQt5.QtWidgets import QLabel, QWidget, QApplication
QImageReader, QBrush, QMovie, QDesktopServices)
from PyQt5.QtWidgets import QLabel, QWidget, QApplication, QPushButton
from ...common.overload import singledispatchmethod
from ...common.font import setFont, getFont
from ...common.style_sheet import FluentStyleSheet
from ...common.config import qconfig, isDarkTheme
......@@ -392,4 +393,51 @@ class AvatarWidget(ImageLabel):
painter.setClipPath(path)
painter.drawImage(self.rect(), image)
radius = pyqtProperty(int, getRadius, setRadius)
\ No newline at end of file
radius = pyqtProperty(int, getRadius, setRadius)
class HyperlinkLabel(QPushButton):
""" Hyperlink label """
@singledispatchmethod
def __init__(self, parent=None):
super().__init__(parent=parent)
self._url = QUrl()
setFont(self, 14)
self.setUnderlineVisible(False)
FluentStyleSheet.LABEL.apply(self)
self.setCursor(Qt.PointingHandCursor)
self.clicked.connect(self._onClicked)
@__init__.register
def _(self, text: str, parent=None):
self.__init__(parent)
self.setText(text)
@__init__.register
def _(self, url: QUrl, text: str, parent=None):
self.__init__(parent)
self.setText(text)
self._url = url
def getUrl(self) -> QUrl:
return self._url
def setUrl(self, url: Union[QUrl, str]):
self._url = QUrl(url)
def isUnderlineVisible(self):
return self._isUnderlineVisible
def setUnderlineVisible(self, isVisible: bool):
self._isUnderlineVisible = isVisible
self.setProperty('underline', isVisible)
self.setStyle(QApplication.style())
def _onClicked(self):
if self.getUrl().isValid():
QDesktopServices.openUrl(self.getUrl())
url = pyqtProperty(QUrl, getUrl, setUrl)
underlineVisible = pyqtProperty(bool, isUnderlineVisible, setUnderlineVisible)
\ No newline at end of file
......@@ -780,7 +780,7 @@ class MenuAnimationManager(QObject):
def _endPosition(self, pos):
m = self.menu
rect = QApplication.screenAt(QCursor.pos()).availableGeometry()
w, h = m.width() + 5, m.sizeHint().height()
w, h = m.width() + 5, m.height()
x = min(pos.x() - m.layout().contentsMargins().left(), rect.right() - w)
y = min(pos.y() - 4, rect.bottom() - h)
......
# coding:utf-8
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtGui import QPixmap, QPainter, QColor
from PyQt5.QtWidgets import QWidget
from ...common.style_sheet import isDarkTheme
class HorizontalSeparator(QWidget):
""" Horizontal 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(255, 255, 255, 51))
else:
painter.setPen(QColor(0, 0, 0, 22))
painter.drawLine(0, 1, self.width(), 1)
class VerticalSeparator(QWidget):
""" Vertical separator """
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setFixedWidth(3)
def paintEvent(self, e):
painter = QPainter(self)
painter.setRenderHints(QPainter.Antialiasing)
if isDarkTheme():
painter.setPen(QColor(255, 255, 255, 51))
else:
painter.setPen(QColor(0, 0, 0, 22))
painter.drawLine(1, 0, 1, self.height())
\ No newline at end of file
......@@ -148,7 +148,7 @@ class Slider(QSlider):
return
painter.setBrush(themeColor())
aw = (self.value() - self.minimum()) / self.maximum() * (w - r*2)
aw = (self.value() - self.minimum()) / (self.maximum() - self.minimum()) * (w - r*2)
painter.drawRoundedRect(QRectF(r, r-2, aw, 4), 2, 2)
def _drawVerticalGroove(self, painter: QPainter):
......@@ -159,7 +159,7 @@ class Slider(QSlider):
return
painter.setBrush(themeColor())
ah = (self.value() - self.minimum()) / self.maximum() * (h - r*2)
ah = (self.value() - self.minimum()) / (self.maximum() - self.minimum()) * (h - r*2)
painter.drawRoundedRect(QRectF(r-2, r, 4, ah), 2, 2)
def resizeEvent(self, e):
......
......@@ -6,7 +6,7 @@ with open('README.md', encoding='utf-8') as f:
setuptools.setup(
name="PyQt-Fluent-Widgets",
version="1.1.5",
version="1.1.7",
keywords="pyqt fluent widgets",
author="zhiyiYo",
author_email="shokokawaii@outlook.com",
......
import os
# https://blog.csdn.net/qq_25262697/article/details/129302819
# https://www.cnblogs.com/happylee666/articles/16158458.html
os.system('nuitka --standalone --windows-disable-console --plugin-enable=pyqt5 --include-qt-plugins=sensible,styles --mingw64 --show-memory --show-progress --windows-icon-from-ico=docs/source/_static/logo.ico demo.py')
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册