提交 3f0301d4 编写于 作者: 之一Yo's avatar 之一Yo

添加 `CommandBarView`

上级 8c7cd1e4
# coding:utf-8 # coding:utf-8
import sys import sys
from PyQt5.QtCore import Qt, QSize from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QToolBar, QHBoxLayout, QAction from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout
from qfluentwidgets import FluentIcon, TransparentPushButton from qfluentwidgets import (FluentIcon, TransparentDropDownPushButton, RoundMenu, CommandBar, Action,
from qfluentwidgets import CommandButton, CommandBar, Action, setTheme, Theme, setFont setTheme, Theme, setFont, CommandBarView, Flyout, FlyoutAnimationType,
ImageLabel, ToolButton, PushButton)
from qframelesswindow import FramelessWindow, StandardTitleBar
class Demo(QWidget): class Demo1(QWidget):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
# setTheme(Theme.DARK) # setTheme(Theme.DARK)
# self.setStyleSheet('Demo{background: rgb(32, 32, 32)}') # self.setStyleSheet('Demo1{background: rgb(32, 32, 32)}')
self.hBoxLayout = QHBoxLayout(self) self.hBoxLayout = QHBoxLayout(self)
self.commandBar = CommandBar(self) self.commandBar = CommandBar(self)
self.dropDownButton = self.createDropDownButton()
self.hBoxLayout.addWidget(self.commandBar, 0) self.hBoxLayout.addWidget(self.commandBar, 0)
# change button style # change button style
self.commandBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.commandBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
# self.commandBar.setMenuDropDown(False)
# self.commandBar.setButtonTight(True)
# setFont(self.commandBar, 14) # setFont(self.commandBar, 14)
self.addButton(FluentIcon.ADD, 'Add') self.addButton(FluentIcon.ADD, 'Add')
...@@ -30,10 +37,15 @@ class Demo(QWidget): ...@@ -30,10 +37,15 @@ class Demo(QWidget):
self.addButton(FluentIcon.COPY, 'Copy') self.addButton(FluentIcon.COPY, 'Copy')
self.addButton(FluentIcon.SHARE, 'Share') self.addButton(FluentIcon.SHARE, 'Share')
# add custom widget
self.commandBar.addWidget(self.dropDownButton)
# add hidden actions
self.commandBar.addHiddenAction(Action(FluentIcon.SCROLL, 'Sort', triggered=lambda: print('排序'))) self.commandBar.addHiddenAction(Action(FluentIcon.SCROLL, 'Sort', triggered=lambda: print('排序')))
self.commandBar.addHiddenAction(Action(FluentIcon.SETTING, 'Settings')) self.commandBar.addHiddenAction(Action(FluentIcon.SETTING, 'Settings'))
self.resize(170, 40) self.resize(240, 40)
self.setWindowTitle('Drag window')
def addButton(self, icon, text): def addButton(self, icon, text):
action = Action(icon, text, self) action = Action(icon, text, self)
...@@ -43,6 +55,52 @@ class Demo(QWidget): ...@@ -43,6 +55,52 @@ class Demo(QWidget):
def onEdit(self, isChecked): def onEdit(self, isChecked):
print('Enter edit mode' if isChecked else 'Exit edit mode') print('Enter edit mode' if isChecked else 'Exit edit mode')
def createDropDownButton(self):
button = TransparentDropDownPushButton('Menu', self, FluentIcon.MENU)
button.setFixedHeight(34)
setFont(button, 12)
menu = RoundMenu(parent=self)
menu.addActions([
Action(FluentIcon.COPY, 'Copy'),
Action(FluentIcon.CUT, 'Cut'),
Action(FluentIcon.PASTE, 'Paste'),
Action(FluentIcon.CANCEL, 'Cancel'),
Action('Select all'),
])
button.setMenu(menu)
return button
class Demo2(FramelessWindow):
def __init__(self):
super().__init__()
self.setTitleBar(StandardTitleBar(self))
self.vBoxLayout = QHBoxLayout(self)
self.imageLabel = ImageLabel('resource/pink_memory.jpg')
self.imageLabel.scaledToWidth(380)
self.imageLabel.clicked.connect(self.showCommandBar)
self.vBoxLayout.addWidget(self.imageLabel)
self.vBoxLayout.setContentsMargins(0, 80, 0, 0)
self.setStyleSheet('Demo2{background: white}')
self.setWindowTitle('Click image 🥵')
self.setWindowIcon(QIcon(":/qfluentwidgets/images/logo.png"))
def showCommandBar(self):
view = CommandBarView(self)
view.addAction(Action(FluentIcon.SHARE, 'Share'))
view.addAction(Action(FluentIcon.SAVE, 'Save'))
view.addAction(Action(FluentIcon.DELETE, 'Delete'))
view.addHiddenAction(Action(FluentIcon.SETTING, 'Settings'))
view.resizeToSuitableWidth()
Flyout.make(view, self.imageLabel, self, FlyoutAnimationType.FADE_IN)
if __name__ == '__main__': if __name__ == '__main__':
# enable dpi scale # enable dpi scale
...@@ -52,6 +110,8 @@ if __name__ == '__main__': ...@@ -52,6 +110,8 @@ if __name__ == '__main__':
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
app = QApplication(sys.argv) app = QApplication(sys.argv)
w = Demo() w1 = Demo1()
w.show() w1.show()
w2 = Demo2()
w2.show()
app.exec_() app.exec_()
# coding: utf-8
from PyQt5.QtCore import Qt
from PyQt5.QtDesigner import QPyDesignerCustomWidgetPlugin
from qfluentwidgets import CommandBar, Action, FluentIcon
from plugin_base import PluginBase
class ToolBarPlugin(PluginBase):
def group(self):
return super().group() + ' (ToolBar)'
class CommandBarPlugin(ToolBarPlugin, QPyDesignerCustomWidgetPlugin):
""" Command bar plugin """
def createWidget(self, parent):
w = CommandBar(parent)
w.addAction(Action(FluentIcon.SHARE, 'Share'))
w.addAction(Action(FluentIcon.SAVE, 'Save'))
w.addAction(Action(FluentIcon.DELETE, 'Delete'))
return w
def icon(self):
return super().icon("CommandBar")
def name(self):
return "CommandBar"
...@@ -76,12 +76,24 @@ MenuActionListWidget::item:selected:active { ...@@ -76,12 +76,24 @@ MenuActionListWidget::item:selected:active {
color: rgba(255, 255, 255, 0.7); color: rgba(255, 255, 255, 0.7);
} }
#completerListWidget[dropDown=true] { #completerListWidget[dropDown=true],
#commandListWidget[dropDown=true][long=false] {
border-top-left-radius: 0px; border-top-left-radius: 0px;
border-top-right-radius: 0px; border-top-right-radius: 0px;
} }
#completerListWidget[dropDown=false] { #commandListWidget[dropDown=true][long=true] {
border-top-left-radius: 9px;
border-top-right-radius: 0px;
}
#commandListWidget[dropDown=false][long=true] {
border-bottom-left-radius: 9px;
border-bottom-right-radius: 0px;
}
#completerListWidget[dropDown=false],
#commandListWidget[dropDown=false][long=false] {
border-bottom-left-radius: 0px; border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px; border-bottom-right-radius: 0px;
} }
......
...@@ -73,12 +73,24 @@ MenuActionListWidget::item:selected:active { ...@@ -73,12 +73,24 @@ MenuActionListWidget::item:selected:active {
color: rgba(0, 0, 0, 0.7); color: rgba(0, 0, 0, 0.7);
} }
#completerListWidget[dropDown=true] { #completerListWidget[dropDown=true],
#commandListWidget[dropDown=true][long=false] {
border-top-left-radius: 0px; border-top-left-radius: 0px;
border-top-right-radius: 0px; border-top-right-radius: 0px;
} }
#completerListWidget[dropDown=false] { #commandListWidget[dropDown=true][long=true] {
border-top-left-radius: 9px;
border-top-right-radius: 0px;
}
#commandListWidget[dropDown=false][long=true] {
border-bottom-left-radius: 9px;
border-bottom-right-radius: 0px;
}
#completerListWidget[dropDown=false],
#commandListWidget[dropDown=false][long=false] {
border-bottom-left-radius: 0px; border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px; border-bottom-right-radius: 0px;
} }
......
因为 它太大了无法显示 source diff 。你可以改为 查看blob
...@@ -7,7 +7,7 @@ from .button import (DropDownPushButton, DropDownToolButton, PrimaryPushButton, ...@@ -7,7 +7,7 @@ from .button import (DropDownPushButton, DropDownToolButton, PrimaryPushButton,
from .card_widget import CardWidget from .card_widget import CardWidget
from .check_box import CheckBox from .check_box import CheckBox
from .combo_box import ComboBox, EditableComboBox from .combo_box import ComboBox, EditableComboBox
from .command_bar import CommandBar, CommandButton from .command_bar import CommandBar, CommandButton, CommandBarView
from .line_edit import LineEdit, TextEdit, PlainTextEdit, LineEditButton, SearchLineEdit from .line_edit import LineEdit, TextEdit, PlainTextEdit, LineEditButton, SearchLineEdit
from .icon_widget import IconWidget from .icon_widget import IconWidget
from .label import (PixmapLabel, CaptionLabel, StrongBodyLabel, BodyLabel, SubtitleLabel, TitleLabel, from .label import (PixmapLabel, CaptionLabel, StrongBodyLabel, BodyLabel, SubtitleLabel, TitleLabel,
......
# coding:utf-8 # coding:utf-8
from typing import Iterable, List, Tuple, Union from typing import Iterable, List, Tuple, Union
from PyQt5.QtCore import Qt, pyqtSignal, QSize, QRectF, QRect, QPoint from PyQt5.QtCore import Qt, pyqtSignal, QSize, QRectF, QRect, QPoint, QEvent
from PyQt5.QtGui import QPixmap, QPainter, QColor, QFont from PyQt5.QtGui import QPixmap, QPainter, QColor, QFont, QHoverEvent, QPainterPath
from PyQt5.QtWidgets import QAction, QLayoutItem, QWidget, QFrame from PyQt5.QtWidgets import QAction, QLayoutItem, QWidget, QFrame, QHBoxLayout, QApplication
from ...common.font import setFont from ...common.font import setFont
from ...common.icon import FluentIcon, Icon, Action from ...common.icon import FluentIcon, Icon, Action
from ...common.style_sheet import isDarkTheme from ...common.style_sheet import isDarkTheme
from .menu import RoundMenu, MenuAnimationType from .menu import RoundMenu, MenuAnimationType
from .button import TransparentToggleToolButton from .button import TransparentToggleToolButton
from .tool_tip import ToolTipFilter
from .flyout import FlyoutViewBase, Flyout
class CommandButton(TransparentToggleToolButton): class CommandButton(TransparentToggleToolButton):
...@@ -33,14 +35,13 @@ class CommandButton(TransparentToggleToolButton): ...@@ -33,14 +35,13 @@ class CommandButton(TransparentToggleToolButton):
return self._isTight return self._isTight
def sizeHint(self) -> QSize: def sizeHint(self) -> QSize:
style = self.toolButtonStyle() if self.isIconOnly():
return QSize(36, 34) if self.isTight() else QSize(48, 34)
if style in [Qt.ToolButtonIconOnly, Qt.ToolButtonFollowStyle] or not self.text():
return QSize(40, 34) if self.isTight() else QSize(48, 34)
# get the width of text # get the width of text
tw = self.fontMetrics().width(self.text()) tw = self.fontMetrics().width(self.text())
style = self.toolButtonStyle()
if style == Qt.ToolButtonTextBesideIcon: if style == Qt.ToolButtonTextBesideIcon:
return QSize(tw + 47, 34) return QSize(tw + 47, 34)
if style == Qt.ToolButtonTextOnly: if style == Qt.ToolButtonTextOnly:
...@@ -48,6 +49,12 @@ class CommandButton(TransparentToggleToolButton): ...@@ -48,6 +49,12 @@ class CommandButton(TransparentToggleToolButton):
return QSize(tw + 32, 50) return QSize(tw + 32, 50)
def isIconOnly(self):
if not self.text():
return True
return self.toolButtonStyle() in [Qt.ToolButtonIconOnly, Qt.ToolButtonFollowStyle]
def _drawIcon(self, icon, painter, rect): def _drawIcon(self, icon, painter, rect):
pass pass
...@@ -62,6 +69,17 @@ class CommandButton(TransparentToggleToolButton): ...@@ -62,6 +69,17 @@ class CommandButton(TransparentToggleToolButton):
self._action = action self._action = action
self.clicked.connect(action.trigger) self.clicked.connect(action.trigger)
action.toggled.connect(self._onActionToggled) action.toggled.connect(self._onActionToggled)
action.changed.connect(self._onActionChanged)
# set tool tip
self.setToolTip(action.toolTip())
self.installEventFilter(CommandToolTipFilter(self, 700))
def _onActionChanged(self):
action = self.action()
self.setIcon(action.icon())
self.setText(action.text())
self.setToolTip(action.toolTip())
def _onActionToggled(self, isChecked: bool): def _onActionToggled(self, isChecked: bool):
self.setCheckable(True) self.setCheckable(True)
...@@ -86,7 +104,7 @@ class CommandButton(TransparentToggleToolButton): ...@@ -86,7 +104,7 @@ class CommandButton(TransparentToggleToolButton):
style = self.toolButtonStyle() style = self.toolButtonStyle()
iw, ih = self.iconSize().width(), self.iconSize().height() iw, ih = self.iconSize().width(), self.iconSize().height()
if style in [Qt.ToolButtonIconOnly, Qt.ToolButtonFollowStyle] or not self.text(): if self.isIconOnly():
y = (self.height() - ih) / 2 y = (self.height() - ih) / 2
x = (self.width() - iw) / 2 x = (self.width() - iw) / 2
super()._drawIcon(self._icon, painter, QRectF(x, y, iw, ih)) super()._drawIcon(self._icon, painter, QRectF(x, y, iw, ih))
...@@ -106,6 +124,13 @@ class CommandButton(TransparentToggleToolButton): ...@@ -106,6 +124,13 @@ class CommandButton(TransparentToggleToolButton):
painter.drawText(rect, Qt.AlignHCenter | Qt.AlignTop, self.text()) painter.drawText(rect, Qt.AlignHCenter | Qt.AlignTop, self.text())
class CommandToolTipFilter(ToolTipFilter):
""" Command tool tip filter """
def _canShowToolTip(self) -> bool:
return super()._canShowToolTip() and self.parent().isIconOnly()
class MoreActionsButton(CommandButton): class MoreActionsButton(CommandButton):
""" More action button """ """ More action button """
...@@ -116,6 +141,11 @@ class MoreActionsButton(CommandButton): ...@@ -116,6 +141,11 @@ class MoreActionsButton(CommandButton):
def sizeHint(self): def sizeHint(self):
return QSize(40, 34) return QSize(40, 34)
def clearState(self):
self.setAttribute(Qt.WA_UnderMouse, False)
e = QHoverEvent(QEvent.HoverLeave, QPoint(-1, -1), QPoint())
QApplication.sendEvent(self, e)
class CommandSeparator(QWidget): class CommandSeparator(QWidget):
""" Command separator """ """ Command separator """
...@@ -132,6 +162,7 @@ class CommandSeparator(QWidget): ...@@ -132,6 +162,7 @@ class CommandSeparator(QWidget):
class CommandMenu(RoundMenu): class CommandMenu(RoundMenu):
""" Command menu """
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__("", parent) super().__init__("", parent)
...@@ -140,6 +171,7 @@ class CommandMenu(RoundMenu): ...@@ -140,6 +171,7 @@ class CommandMenu(RoundMenu):
class CommandBar(QFrame): class CommandBar(QFrame):
""" Command bar """
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent=parent) super().__init__(parent=parent)
...@@ -149,6 +181,7 @@ class CommandBar(QFrame): ...@@ -149,6 +181,7 @@ class CommandBar(QFrame):
self._menuAnimation = MenuAnimationType.DROP_DOWN self._menuAnimation = MenuAnimationType.DROP_DOWN
self._toolButtonStyle = Qt.ToolButtonIconOnly self._toolButtonStyle = Qt.ToolButtonIconOnly
self._iconSize = QSize(16, 16)
self._isButtonTight = False self._isButtonTight = False
self._spacing = 4 self._spacing = 4
...@@ -157,6 +190,7 @@ class CommandBar(QFrame): ...@@ -157,6 +190,7 @@ class CommandBar(QFrame):
self.moreButton.hide() self.moreButton.hide()
setFont(self, 12) setFont(self, 12)
self.setAttribute(Qt.WA_TranslucentBackground)
def setSpaing(self, spacing: int): def setSpaing(self, spacing: int):
if spacing == self._spacing: if spacing == self._spacing:
...@@ -202,12 +236,12 @@ class CommandBar(QFrame): ...@@ -202,12 +236,12 @@ class CommandBar(QFrame):
for action in actions: for action in actions:
self.addHiddenAction(action) self.addHiddenAction(action)
def insertAction(self, before: Union[Action, QAction], action: Union[Action, QAction], checkable=False): def insertAction(self, before: QAction, action: QAction):
if before not in self.actions(): if before not in self.actions():
return return
index = self.actions().index(before) index = self.actions().index(before)
button = self._createButton(action, checkable) button = self._createButton(action)
self._insertWidgetToLayout(index, button) self._insertWidgetToLayout(index, button)
super().insertAction(before, action) super().insertAction(before, action)
return button return button
...@@ -222,6 +256,30 @@ class CommandBar(QFrame): ...@@ -222,6 +256,30 @@ class CommandBar(QFrame):
""" add widget to command bar """ """ add widget to command bar """
self._insertWidgetToLayout(-1, widget) self._insertWidgetToLayout(-1, widget)
def removeAction(self, action: QAction):
if action not in self.actions():
return
for w in self.commandButtons:
if w.action() is action:
self._widgets.remove(w)
w.hide()
w.deleteLater()
break
self.updateGeometry()
def removeWidget(self, widget: QWidget):
if widget not in self._widgets:
return
self._widgets.remove(widget)
self.updateGeometry()
def removeHiddenAction(self, action: QAction):
if action in self._hiddenActions:
self._hiddenActions.remove(action)
def setToolButtonStyle(self, style: Qt.ToolButtonStyle): def setToolButtonStyle(self, style: Qt.ToolButtonStyle):
""" set the style of tool button """ """ set the style of tool button """
if self.toolButtonStyle() == style: if self.toolButtonStyle() == style:
...@@ -248,16 +306,28 @@ class CommandBar(QFrame): ...@@ -248,16 +306,28 @@ class CommandBar(QFrame):
def isButtonTight(self): def isButtonTight(self):
return self._isButtonTight return self._isButtonTight
def setIconSize(self, size: QSize):
if size == self._iconSize:
return
self._iconSize = size
for w in self.commandButtons:
w.setIconSize(size)
def iconSize(self):
return self._iconSize
def resizeEvent(self, e): def resizeEvent(self, e):
self.updateGeometry() self.updateGeometry()
def _createButton(self, action: QAction): def _createButton(self, action: QAction):
""" create command button """ """ create command button """
button = CommandButton(action.icon()) button = CommandButton(action.icon(), self)
button.setText(action.text()) button.setText(action.text())
button.setAction(action) button.setAction(action)
button.setToolButtonStyle(self.toolButtonStyle()) button.setToolButtonStyle(self.toolButtonStyle())
button.setTight(self.isButtonTight()) button.setTight(self.isButtonTight())
button.setIconSize(self.iconSize())
button.setFont(self.font()) button.setFont(self.font())
return button return button
...@@ -271,6 +341,7 @@ class CommandBar(QFrame): ...@@ -271,6 +341,7 @@ class CommandBar(QFrame):
else: else:
self._widgets.insert(index, widget) self._widgets.insert(index, widget)
self.setFixedHeight(max(w.height() for w in self._widgets))
self.updateGeometry() self.updateGeometry()
def minimumSizeHint(self) -> QSize: def minimumSizeHint(self) -> QSize:
...@@ -291,7 +362,7 @@ class CommandBar(QFrame): ...@@ -291,7 +362,7 @@ class CommandBar(QFrame):
x += (w + self.spacing()) x += (w + self.spacing())
# show more actions button # show more actions button
if self._hiddenActions: if self._hiddenActions or len(visibles) < len(self._widgets):
self.moreButton.show() self.moreButton.show()
self.moreButton.move(x, (h - self.moreButton.height()) // 2) self.moreButton.move(x, (h - self.moreButton.height()) // 2)
...@@ -301,28 +372,31 @@ class CommandBar(QFrame): ...@@ -301,28 +372,31 @@ class CommandBar(QFrame):
def _visibleWidgets(self) -> List[QLayoutItem]: def _visibleWidgets(self) -> List[QLayoutItem]:
""" return the visible widgets in layout """ """ return the visible widgets in layout """
w = 0
# show more actions if there are hidden actions
widgets = self._widgets.copy()
if self._hiddenActions:
widgets.append(self.moreButton)
widths = [i.width() for i in widgets]
total = sum(widths) + w + self.spacing() * max(len(widgets) - 1, 0)
# have enough spacing to show all widgets # have enough spacing to show all widgets
if total <= self.width(): if self.suitableWidth() <= self.width():
return self._widgets return self._widgets
w += self.moreButton.width() w = self.moreButton.width()
for index, widget in enumerate(self._widgets): for index, widget in enumerate(self._widgets):
w += widget.width() w += widget.width()
if index > 0:
w += self.spacing()
if w > self.width(): if w > self.width():
break break
return self._widgets[:index] return self._widgets[:index]
def suitableWidth(self):
widths = [w.width() for w in self._widgets]
if self._hiddenActions:
widths.append(self.moreButton.width())
return sum(widths) + self.spacing() * max(len(widths) - 1, 0)
def resizeToSuitableWidth(self):
self.setFixedWidth(self.suitableWidth())
def setFont(self, font: QFont): def setFont(self, font: QFont):
super().setFont(font) super().setFont(font)
for button in self.commandButtons: for button in self.commandButtons:
...@@ -339,8 +413,13 @@ class CommandBar(QFrame): ...@@ -339,8 +413,13 @@ class CommandBar(QFrame):
else: else:
self._menuAnimation = MenuAnimationType.PULL_UP self._menuAnimation = MenuAnimationType.PULL_UP
def isMenuDropDown(self):
return self._menuAnimation == MenuAnimationType.DROP_DOWN
def _showMoreActionsMenu(self): def _showMoreActionsMenu(self):
""" show more actions menu """ """ show more actions menu """
self.moreButton.clearState()
actions = self._hiddenActions.copy() actions = self._hiddenActions.copy()
for w in reversed(self._hiddenWidgets): for w in reversed(self._hiddenWidgets):
...@@ -351,11 +430,194 @@ class CommandBar(QFrame): ...@@ -351,11 +430,194 @@ class CommandBar(QFrame):
menu.addActions(actions) menu.addActions(actions)
x = -menu.width() + menu.layout().contentsMargins().right() + \ x = -menu.width() + menu.layout().contentsMargins().right() + \
self.moreButton.width() + 5 self.moreButton.width() + 18
if self._menuAnimation == MenuAnimationType.DROP_DOWN: if self._menuAnimation == MenuAnimationType.DROP_DOWN:
y = self.moreButton.height() y = self.moreButton.height()
else: else:
y = -menu.height() + menu.layout().contentsMargins().bottom() y = -5
pos = self.moreButton.mapToGlobal(QPoint(x, y))
menu.exec(pos, aniType=self._menuAnimation)
class CommandViewMenu(CommandMenu):
""" Command view menu """
def __init__(self, parent=None):
super().__init__(parent)
self.view.setObjectName('commandListWidget')
def setDropDown(self, down: bool, long=False):
self.view.setProperty('dropDown', down)
self.view.setProperty('long', long)
self.view.setStyle(QApplication.style())
self.view.update()
class CommandViewBar(CommandBar):
""" Command view bar """
def __init__(self, parent=None):
super().__init__(parent)
self.setMenuDropDown(True)
def setMenuDropDown(self, down: bool):
""" set the animation direction of more actions menu """
if down:
self._menuAnimation = MenuAnimationType.FADE_IN_DROP_DOWN
else:
self._menuAnimation = MenuAnimationType.FADE_IN_PULL_UP
def isMenuDropDown(self):
return self._menuAnimation == MenuAnimationType.FADE_IN_DROP_DOWN
def _showMoreActionsMenu(self):
self.moreButton.clearState()
actions = self._hiddenActions.copy()
for w in reversed(self._hiddenWidgets):
if isinstance(w, CommandButton):
actions.insert(0, w.action())
menu = CommandViewMenu(self)
menu.addActions(actions)
# adjust the shape of view
view = self.parent() # type: CommandBarView
view.setMenuVisible(True)
# adjust the shape of menu
menu.closedSignal.connect(lambda: view.setMenuVisible(False))
menu.setDropDown(self.isMenuDropDown(), menu.view.width() > view.width())
# adjust menu size
if menu.view.width() < view.width():
menu.view.setFixedWidth(view.width())
menu.adjustSize()
x = -menu.width() + menu.layout().contentsMargins().right() + \
self.moreButton.width() + 18
if self.isMenuDropDown():
y = self.moreButton.height()
else:
y = -13
menu.setShadowEffect(0, (0, 0), QColor(0, 0, 0, 0))
menu.layout().setContentsMargins(12, 20, 12, 8)
pos = self.moreButton.mapToGlobal(QPoint(x, y)) pos = self.moreButton.mapToGlobal(QPoint(x, y))
menu.exec_(pos, aniType=self._menuAnimation) menu.exec(pos, aniType=self._menuAnimation)
class CommandBarView(FlyoutViewBase):
""" Command bar view """
def __init__(self, parent=None):
super().__init__(parent=parent)
self.bar = CommandViewBar(self)
self.hBoxLayout = QHBoxLayout(self)
self.hBoxLayout.setContentsMargins(6, 6, 6, 6)
self.hBoxLayout.addWidget(self.bar)
self.hBoxLayout.setSizeConstraint(QHBoxLayout.SetMinAndMaxSize)
self.setButtonTight(True)
self.setIconSize(QSize(14, 14))
self._isMenuVisible = False
def setMenuVisible(self, isVisible):
self._isMenuVisible = isVisible
self.update()
def addWidget(self, widget: QWidget):
self.bar.addWidget(widget)
def setSpaing(self, spacing: int):
self.bar.setSpaing(spacing)
def spacing(self):
return self.bar.spacing()
def addAction(self, action: QAction):
return self.bar.addAction(action)
def addActions(self, actions: Iterable[QAction]):
self.bar.addActions(actions)
def addHiddenAction(self, action: QAction):
self.bar.addHiddenAction(action)
def addHiddenActions(self, actions: List[QAction]):
self.bar.addHiddenActions(actions)
def insertAction(self, before: QAction, action: QAction):
return self.bar.insertAction(before, action)
def addSeparator(self):
self.bar.addSeparator()
def insertSeparator(self, index: int):
self.bar.insertSeparator(index)
def removeAction(self, action: QAction):
self.bar.removeAction(action)
def removeWidget(self, widget: QWidget):
self.bar.removeWidget(widget)
def removeHiddenAction(self, action: QAction):
self.bar.removeAction(action)
def setToolButtonStyle(self, style: Qt.ToolButtonStyle):
self.bar.setToolButtonStyle(style)
def toolButtonStyle(self):
return self.bar.toolButtonStyle()
def setButtonTight(self, isTight: bool):
self.bar.setButtonTight(isTight)
def isButtonTight(self):
return self.bar.isButtonTight()
def setIconSize(self, size: QSize):
self.bar.setIconSize(size)
def iconSize(self):
return self.bar.iconSize()
def setFont(self, font: QFont):
self.bar.setFont(font)
def setMenuDropDown(self, down: bool):
self.bar.setMenuDropDown(down)
def suitableWidth(self):
m = self.contentsMargins()
return m.left() + m.right() + self.bar.suitableWidth()
def resizeToSuitableWidth(self):
self.bar.resizeToSuitableWidth()
self.setFixedWidth(self.suitableWidth())
def actions(self):
return self.bar.actions()
def paintEvent(self, e):
painter = QPainter(self)
painter.setRenderHints(QPainter.Antialiasing)
path = QPainterPath()
path.setFillRule(Qt.WindingFill)
path.addRoundedRect(QRectF(self.rect().adjusted(1, 1, -1, -1)), 8, 8)
if self._isMenuVisible:
y = self.height() - 10 if self.bar.isMenuDropDown() else 1
path.addRect(1, y, self.width() - 2, 9)
painter.setBrush(
QColor(40, 40, 40) if isDarkTheme() else QColor(248, 248, 248))
painter.setPen(
QColor(23, 23, 23) if isDarkTheme() else QColor(233, 233, 233))
painter.drawPath(path.simplified())
...@@ -20,7 +20,8 @@ class FlyoutAnimationType(Enum): ...@@ -20,7 +20,8 @@ class FlyoutAnimationType(Enum):
DROP_DOWN = 1 DROP_DOWN = 1
SLIDE_LEFT = 2 SLIDE_LEFT = 2
SLIDE_RIGHT = 3 SLIDE_RIGHT = 3
NONE = 4 FADE_IN = 4
NONE = 5
class IconWidget(QWidget): class IconWidget(QWidget):
...@@ -436,6 +437,24 @@ class SlideRightFlyoutAnimationManager(FlyoutAnimationManager): ...@@ -436,6 +437,24 @@ class SlideRightFlyoutAnimationManager(FlyoutAnimationManager):
self.aniGroup.start() self.aniGroup.start()
@FlyoutAnimationManager.register(FlyoutAnimationType.FADE_IN)
class DropDownFlyoutAnimationManager(FlyoutAnimationManager):
""" Drop down flyout animation manager """
def position(self, target: QWidget):
w = self.flyout
pos = target.mapToGlobal(QPoint())
x = pos.x() + target.width()//2 - w.sizeHint().width()//2
y = pos.y() - w.sizeHint().height() + w.layout().contentsMargins().bottom()
return QPoint(x, y)
def exec(self, pos: QPoint):
self.flyout.move(self._adjustPosition(pos))
self.aniGroup.removeAnimation(self.slideAni)
self.aniGroup.start()
@FlyoutAnimationManager.register(FlyoutAnimationType.NONE) @FlyoutAnimationManager.register(FlyoutAnimationType.NONE)
class DummyFlyoutAnimationManager(FlyoutAnimationManager): class DummyFlyoutAnimationManager(FlyoutAnimationManager):
""" Dummy flyout animation manager """ """ Dummy flyout animation manager """
......
# coding:utf-8 # coding:utf-8
from typing import List, Union from typing import List, Union
from PyQt5.QtCore import Qt, QRectF, QPoint from PyQt5.QtCore import Qt, QRectF, QPoint, pyqtSignal
from PyQt5.QtGui import (QPixmap, QPainter, QPalette, QColor, QFont, QImage, QPainterPath, from PyQt5.QtGui import (QPixmap, QPainter, QPalette, QColor, QFont, QImage, QPainterPath,
QImageReader, QBrush, QMovie) QImageReader, QBrush, QMovie)
from PyQt5.QtWidgets import QLabel, QWidget from PyQt5.QtWidgets import QLabel, QWidget
...@@ -129,6 +129,8 @@ class DisplayLabel(FluentLabelBase): ...@@ -129,6 +129,8 @@ class DisplayLabel(FluentLabelBase):
class ImageLabel(QLabel): class ImageLabel(QLabel):
""" Image label """ """ Image label """
clicked = pyqtSignal()
def __init__(self, image: Union[str, QPixmap, QImage] = None, parent=None): def __init__(self, image: Union[str, QPixmap, QImage] = None, parent=None):
super().__init__(parent=parent) super().__init__(parent=parent)
self.setImage(image) self.setImage(image)
...@@ -185,6 +187,10 @@ class ImageLabel(QLabel): ...@@ -185,6 +187,10 @@ class ImageLabel(QLabel):
def isNull(self): def isNull(self):
return self.image.isNull() return self.image.isNull()
def mouseReleaseEvent(self, e):
super().mouseReleaseEvent(e)
self.clicked.emit()
def paintEvent(self, e): def paintEvent(self, e):
if self.isNull(): if self.isNull():
return return
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册